Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/foxtools/MFXListIconItem.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2006-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file MFXListIconItem.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Feb 2023
17
///
18
//
19
/****************************************************************************/
20
21
// ===========================================================================
22
// included modules
23
// ===========================================================================
24
25
#include <utils/common/UtilExceptions.h>
26
#include <fxkeys.h>
27
28
#include "MFXListIconItem.h"
29
#include "MFXListIcon.h"
30
31
// ===========================================================================
32
// Macross
33
// ===========================================================================
34
35
#define SIDE_SPACING 6 // Left or right spacing between items
36
#define ICON_SPACING 4 // Spacing between icon and label (2 + 2)
37
#define LINE_SPACING 4 // Line spacing between items
38
#define ICON_SIZE 16
39
40
// ===========================================================================
41
// FOX callback mapping
42
// ===========================================================================
43
44
// Object implementation
45
FXIMPLEMENT(MFXListIconItem, FXObject, nullptr, 0)
46
47
// ===========================================================================
48
// member method definitions
49
// ===========================================================================
50
51
MFXListIconItem::MFXListIconItem(const FXString& text, FXIcon* ic, FXColor backGroundColor, void* ptr):
52
label(text),
53
icon(ic),
54
data(ptr),
55
myBackGroundColor(backGroundColor) {
56
}
57
58
59
MFXListIconItem::~MFXListIconItem() {
60
if (state & ICONOWNED) {
61
delete icon;
62
}
63
icon = (FXIcon*) - 1L;
64
}
65
66
67
void
68
MFXListIconItem::setFocus(FXbool focus) {
69
if (focus) {
70
state |= FOCUS;
71
} else {
72
state &= ~(FXuint)FOCUS;
73
}
74
}
75
76
77
FXbool
78
MFXListIconItem::hasFocus() const {
79
return (state & FOCUS) != 0;
80
}
81
82
83
void
84
MFXListIconItem::setSelected(FXbool selected) {
85
if (selected) {
86
state |= SELECTED;
87
} else {
88
state &= ~SELECTED;
89
}
90
}
91
92
93
FXbool
94
MFXListIconItem::isSelected() const {
95
return (state & SELECTED) != 0;
96
}
97
98
99
void
100
MFXListIconItem::setEnabled(FXbool enabled) {
101
if (enabled) {
102
state &= ~DISABLED;
103
} else {
104
state |= DISABLED;
105
}
106
}
107
108
109
FXbool
110
MFXListIconItem::isEnabled() const {
111
return (state & DISABLED) == 0;
112
}
113
114
115
void
116
MFXListIconItem::setDraggable(FXbool draggable) {
117
if (draggable) {
118
state |= DRAGGABLE;
119
} else {
120
state &= ~DRAGGABLE;
121
}
122
}
123
124
125
FXbool
126
MFXListIconItem::isDraggable() const {
127
return (state & DRAGGABLE) != 0;
128
}
129
130
131
void
132
MFXListIconItem::setText(const FXString& txt) {
133
label = txt;
134
}
135
136
137
const FXString&
138
MFXListIconItem::getText() const {
139
return label;
140
}
141
142
143
FXIcon*
144
MFXListIconItem::getIcon() const {
145
return icon;
146
}
147
148
149
void
150
MFXListIconItem::create() {
151
if (icon) {
152
icon->create();
153
}
154
}
155
156
157
void
158
MFXListIconItem::destroy() {
159
if ((state & ICONOWNED) && icon) {
160
icon->destroy();
161
}
162
}
163
164
165
void
166
MFXListIconItem::detach() {
167
if (icon) {
168
icon->detach();
169
}
170
}
171
172
173
FXint
174
MFXListIconItem::getWidth(const MFXListIcon* list) const {
175
FXFont* font = list->getFont();
176
FXint w = 0;
177
if (icon) {
178
w = icon->getWidth();
179
}
180
if (!label.empty()) {
181
if (w) {
182
w += ICON_SPACING;
183
}
184
w += font->getTextWidth(label.text(), label.length());
185
}
186
return SIDE_SPACING + w;
187
}
188
189
190
191
FXint
192
MFXListIconItem::getHeight(const MFXListIcon* list) const {
193
FXFont* font = list->getFont();
194
FXint th = 0, ih = 0;
195
if (icon) {
196
ih = icon->getHeight();
197
}
198
if (!label.empty()) {
199
th = font->getFontHeight();
200
}
201
return LINE_SPACING + FXMAX(th, ih);
202
}
203
204
205
206
const FXColor&
207
MFXListIconItem::getBackGroundColor() const {
208
return myBackGroundColor;
209
}
210
211
212
MFXListIconItem::MFXListIconItem() {}
213
214
215
void
216
MFXListIconItem::draw(const MFXListIcon* list, FXDC& dc, FXint xx, FXint yy, FXint ww, FXint hh) {
217
FXFont* font = list->getFont();
218
FXint ih = icon ? ICON_SIZE : 0;
219
FXint th = 0;
220
if (!label.empty()) {
221
th = font->getFontHeight();
222
}
223
if (isSelected()) {
224
dc.setForeground(list->getSelBackColor());
225
} else {
226
dc.setForeground(myBackGroundColor); // FIXME maybe paint background in onPaint?
227
}
228
dc.fillRectangle(xx, yy, ww, hh);
229
if (hasFocus()) {
230
dc.drawFocusRectangle(xx + 1, yy + 1, ww - 2, hh - 2);
231
}
232
xx += SIDE_SPACING / 2;
233
if (icon) {
234
dc.drawIcon(icon, xx, yy + (hh - ih) / 2);
235
}
236
if (icon) {
237
xx += ICON_SPACING + ICON_SIZE;
238
}
239
if (!label.empty()) {
240
dc.setFont(font);
241
if (!isEnabled()) {
242
dc.setForeground(makeShadowColor(list->getBackColor()));
243
} else if (isSelected()) {
244
dc.setForeground(list->getSelTextColor());
245
} else {
246
dc.setForeground(list->getTextColor());
247
}
248
dc.drawText(xx, yy + (hh - th) / 2 + font->getFontAscent(), label);
249
}
250
}
251
252
253
FXint
254
MFXListIconItem::hitItem(const MFXListIcon* list, FXint xx, FXint yy) const {
255
FXint iw = 0, ih = 0, tw = 0, th = 0, ix, iy, tx, ty, h;
256
FXFont* font = list->getFont();
257
if (icon) {
258
iw = icon->getWidth();
259
ih = icon->getHeight();
260
}
261
if (!label.empty()) {
262
tw = 4 + font->getTextWidth(label.text(), label.length());
263
th = 4 + font->getFontHeight();
264
}
265
h = LINE_SPACING + FXMAX(th, ih);
266
ix = SIDE_SPACING / 2;
267
tx = SIDE_SPACING / 2;
268
if (iw) {
269
tx += iw + ICON_SPACING;
270
}
271
iy = (h - ih) / 2;
272
ty = (h - th) / 2;
273
274
// In icon?
275
if (ix <= xx && iy <= yy && xx < ix + iw && yy < iy + ih) {
276
return 1;
277
}
278
279
// In text?
280
if (tx <= xx && ty <= yy && xx < tx + tw && yy < ty + th) {
281
return 2;
282
}
283
284
// Outside
285
return 0;
286
}
287
288