wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
ICDropZone.cpp
Go to the documentation of this file.
1// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "App/UI/ICDropZone.h"
5
6#include <optional>
7
8#include <QDragEnterEvent>
9#include <QDragMoveEvent>
10#include <QLabel>
11#include <QMimeData>
12#include <QResizeEvent>
13
15#include "App/Core/Enums.h"
16#include "App/Core/MimeTypes.h"
18
19namespace {
20
21std::optional<DragDropPayload> extractDragPayload(const QMimeData *mimeData)
22{
23 QByteArray itemData;
24 if (mimeData->hasFormat(MimeType::DragDrop)) {
25 itemData = mimeData->data(MimeType::DragDrop);
26 } else if (mimeData->hasFormat(MimeType::DragDropLegacy)) {
27 itemData = mimeData->data(MimeType::DragDropLegacy);
28 } else {
29 return std::nullopt;
30 }
31
32 QDataStream stream(&itemData, QIODevice::ReadOnly);
34
35 return readDragDropPayload(stream);
36}
37
38} // namespace
39
40ICDropZone::ICDropZone(Section section, QWidget *parent)
41 : QWidget(parent)
42 , m_section(section)
43{
44 setAcceptDrops(true);
45
46 setAccessibleName(m_section == Section::Embedded ? tr("Embedded IC drop zone") : tr("File-based IC drop zone"));
47 setWhatsThis(m_section == Section::Embedded
48 ? tr("Drop a file-based IC here to embed it directly in the circuit.")
49 : tr("Drop an embedded IC here to extract it to its own file."));
50
51 // Cross-section drag-to-convert is otherwise invisible. A raised overlay, shown only
52 // while a compatible IC is dragged over, spells out what the drop will do.
53 m_hintOverlay = new QLabel(this);
54 m_hintOverlay->setObjectName("icDropHint");
55 m_hintOverlay->setAlignment(Qt::AlignCenter);
56 m_hintOverlay->setWordWrap(true);
57 m_hintOverlay->setText(m_section == Section::Embedded
58 ? tr("Drop here to embed this IC in the circuit")
59 : tr("Drop here to extract this IC to a file"));
60 // Concrete rgba (Qt Style Sheets don't support palette()); blue+white reads on both themes.
61 m_hintOverlay->setStyleSheet(QStringLiteral(
62 "QLabel { background: rgba(51, 129, 204, 215); color: white;"
63 " border: 2px dashed white; border-radius: 6px; padding: 8px; font-weight: bold; }"));
64 m_hintOverlay->hide();
65}
66
67void ICDropZone::setHintVisible(bool visible)
68{
69 if (visible) {
70 m_hintOverlay->resize(size());
71 m_hintOverlay->raise();
72 }
73 m_hintOverlay->setVisible(visible);
74}
75
76void ICDropZone::resizeEvent(QResizeEvent *event)
77{
78 QWidget::resizeEvent(event);
79 m_hintOverlay->resize(event->size());
80}
81
82void ICDropZone::dragEnterEvent(QDragEnterEvent *event)
83{
84 auto payload = extractDragPayload(event->mimeData());
85 if (!payload) return;
86
87 // Only accept opposite-type drops
88 if (m_section == Section::Embedded && !payload->isEmbedded) {
89 event->acceptProposedAction(); // File-based dropped onto embedded section
90 setHintVisible(true);
91 } else if (m_section == Section::FileBased && payload->isEmbedded) {
92 event->acceptProposedAction(); // Embedded dropped onto file-based section
93 setHintVisible(true);
94 }
95}
96
97void ICDropZone::dragMoveEvent(QDragMoveEvent *event)
98{
99 event->acceptProposedAction();
100}
101
102void ICDropZone::dragLeaveEvent(QDragLeaveEvent *event)
103{
104 Q_UNUSED(event)
105 setHintVisible(false);
106}
107
108void ICDropZone::dropEvent(QDropEvent *event)
109{
110 setHintVisible(false);
111
112 auto payload = extractDragPayload(event->mimeData());
113 if (!payload) return;
114
115 if (m_section == Section::Embedded && !payload->isEmbedded) {
116 emit embedByFileRequested(payload->icFileName);
117 event->acceptProposedAction();
118 } else if (m_section == Section::FileBased && payload->isEmbedded) {
119 emit extractByBlobNameRequested(payload->blobName);
120 event->acceptProposedAction();
121 }
122}
DragDropPayload readDragDropPayload(QDataStream &stream)
Reads a drag-and-drop payload from stream.
Shared reader for wiRedPanda's drag-and-drop MIME payload format.
Central enumeration types for element types, groups, and signal status.
ICDropZone: drop target widget for cross-section IC palette drops.
MIME type string constants for drag-and-drop operations.
Circuit and waveform file serialization/deserialization utilities.
void dragMoveEvent(QDragMoveEvent *event) override
void extractByBlobNameRequested(const QString &blobName)
Emitted when an embedded IC is dropped onto the file-based section.
Section
Identifies which IC palette section this zone belongs to.
Definition ICDropZone.h:28
@ Embedded
The embedded IC section (accepts file-backed drops for embedding).
Definition ICDropZone.h:30
@ FileBased
The file-backed IC section (accepts embedded drops for extraction).
Definition ICDropZone.h:29
void embedByFileRequested(const QString &fileName)
Emitted when a file-based IC is dropped onto the embedded section.
void dragEnterEvent(QDragEnterEvent *event) override
ICDropZone(Section section, QWidget *parent=nullptr)
Constructs a drop zone for the given palette section.
void dropEvent(QDropEvent *event) override
void dragLeaveEvent(QDragLeaveEvent *event) override
void resizeEvent(QResizeEvent *event) override
static QVersionNumber readPandaHeader(QDataStream &stream)
Reads and validates the .panda circuit file header; returns the stored version number.
constexpr const char * DragDropLegacy
Legacy drag-and-drop MIME type retained for backward compatibility.
Definition MimeTypes.h:15
constexpr const char * DragDrop
Current drag-and-drop MIME type for element palette → scene drops.
Definition MimeTypes.h:13