wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
ElementLabel.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
5
6#include <QApplication>
7#include <QDrag>
8#include <QFileInfo>
9#include <QHBoxLayout>
10#include <QMimeData>
11#include <QMouseEvent>
12
13#include "App/Core/MimeTypes.h"
16
17ElementLabel::ElementLabel(const QPixmap &pixmap, ElementType type, const QString &icFileName, QWidget *parent, bool isEmbedded)
18 : QFrame(parent)
19 , m_elementType(type)
20 , m_pixmap(pixmap)
21 , m_icFileName(icFileName)
22 , m_isEmbedded(isEmbedded)
23{
24 m_iconLabel.setPixmap(pixmap);
25 m_iconLabel.setScaledContents(true);
26 m_iconLabel.setFixedSize(64, 64);
27
28 if (m_isEmbedded) {
29 m_nameLabel.setText(icFileName.toUpper());
30 } else if (type == ElementType::IC) {
31 m_nameLabel.setText(QFileInfo(icFileName).baseName().toUpper());
32 } else {
33 m_nameLabel.setText(ElementFactory::translatedName(type));
34 }
35
36 // Describe what the item is and how to place it. Set on the frame and both child labels
37 // so the tooltip appears wherever the pointer rests on the item.
38 QString tip;
39 if (m_isEmbedded) {
40 tip = tr("Embedded IC: %1").arg(icFileName);
41 } else if (type == ElementType::IC) {
42 tip = tr("IC from file: %1").arg(QFileInfo(icFileName).fileName());
43 } else {
45 }
46 const QString addHint = tr("Drag or double-click to add.");
47 tip = tip.isEmpty() ? addHint : tip + QLatin1Char('\n') + addHint;
48 setToolTip(tip);
49 m_iconLabel.setToolTip(tip);
50 m_nameLabel.setToolTip(tip);
51
52 auto *itemLayout = new QHBoxLayout();
53 itemLayout->setSpacing(6);
54 itemLayout->setObjectName(QStringLiteral("itemLayout"));
55
56 setLayout(itemLayout);
57
58 itemLayout->addWidget(&m_iconLabel);
59 itemLayout->addStretch();
60 itemLayout->addWidget(&m_nameLabel);
61 itemLayout->addStretch();
62 itemLayout->setContentsMargins(0, 0, 0, 0);
63}
64
66{
67 if (m_elementType != ElementType::IC) {
68 m_nameLabel.setText(ElementFactory::translatedName(m_elementType));
69 }
70}
71
72void ElementLabel::mousePressEvent(QMouseEvent *event)
73{
74 // Only remember where the press started. Deferring the drag until the pointer
75 // actually moves leaves the press/release free for double-click detection, which a
76 // blocking drag->exec() on press would otherwise swallow.
77 if (event->button() == Qt::LeftButton) {
78 m_dragStartPos = event->pos();
79 }
80}
81
82void ElementLabel::mouseMoveEvent(QMouseEvent *event)
83{
84 if (!(event->buttons() & Qt::LeftButton)) {
85 return;
86 }
87 if ((event->pos() - m_dragStartPos).manhattanLength() < QApplication::startDragDistance()) {
88 return;
89 }
90 startDrag();
91}
92
94{
95 Q_UNUSED(event)
96 // Drag-free shortcut: add this element straight to the active scene. mimeData()
97 // hands off a freshly-allocated payload the scene takes ownership of.
99}
100
102{
103 return m_elementType;
104}
105
106const QPixmap &ElementLabel::pixmap() const
107{
108 return m_pixmap;
109}
110
111QString ElementLabel::name() const
112{
113 return m_nameLabel.text();
114}
115
117{
118 return m_icFileName;
119}
120
122{
123 return m_isEmbedded;
124}
125
127{
128 // The hot spot is the icon's centre so the element appears centred under
129 // the cursor when dropped onto the scene.
130 QPoint offset = m_iconLabel.pixmap(Qt::ReturnByValue).rect().center();
131
132 auto *drag = new QDrag(parent());
133 drag->setMimeData(mimeData());
134 drag->setPixmap(pixmap());
135 drag->setHotSpot(offset);
136 // CopyAction for both proposed and allowed: placing an element on the scene
137 // always creates a new instance, never moves the palette entry.
138 drag->exec(Qt::CopyAction, Qt::CopyAction);
139}
140
141QMimeData *ElementLabel::mimeData() const
142{
143 QPoint offset = m_iconLabel.pixmap(Qt::ReturnByValue).rect().center();
144 QByteArray itemData;
145 QDataStream stream(&itemData, QIODevice::WriteOnly);
147 stream << offset << m_elementType << m_icFileName << m_isEmbedded << (m_isEmbedded ? m_icFileName : QString());
148
149 auto *mimeData = new QMimeData();
150 mimeData->setData(MimeType::DragDrop, itemData);
151
152 return mimeData;
153}
154
156{
157 m_pixmap = ElementFactory::pixmap(m_elementType);
158 m_iconLabel.setPixmap(m_pixmap);
159}
Singleton factory for all circuit element types.
Draggable element icon+label widget used in the element palette.
Enums::ElementType ElementType
Definition Enums.h:107
MIME type string constants for drag-and-drop operations.
Circuit and waveform file serialization/deserialization utilities.
static QString translatedName(const ElementType type)
Returns the translated human-readable name for type.
static QPixmap pixmap(const ElementType type)
Returns the pixmap icon for the given element type.
static QString description(const ElementType type)
void startDrag()
Initiates a drag operation carrying this label's element type.
void mouseMoveEvent(QMouseEvent *event) override
Starts the drag once the pointer moves past the platform drag threshold.
void addToSceneRequested(QMimeData *mimeData)
QString name() const
Returns the displayed element name.
bool isEmbedded() const
Returns true if this label represents an embedded IC.
void mousePressEvent(QMouseEvent *event) override
const QPixmap & pixmap() const
Returns the icon pixmap shown in this label.
void updateName()
Updates the displayed name to match the current application locale.
QMimeData * mimeData() const
Creates and returns the MIME data payload used for drag-and-drop.
QString icFileName() const
Returns the IC file path, or an empty string for built-in elements.
void mouseDoubleClickEvent(QMouseEvent *event) override
Requests adding this element to the active scene (drag-free shortcut).
void updateTheme()
Updates colors to match the current application theme.
const ElementType & elementType() const
Returns the element type identifier for this label.
ElementLabel(const QPixmap &pixmap, ElementType type, const QString &icFileName, QWidget *parent=nullptr, bool isEmbedded=false)
Constructs an ElementLabel from a pixmap.
static void writePandaHeader(QDataStream &stream)
Writes the .panda circuit file header to stream.
constexpr const char * DragDrop
Current drag-and-drop MIME type for element palette → scene drops.
Definition MimeTypes.h:13