Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2006-2024 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 0 : FXIMPLEMENT(MFXListIconItem, FXObject, nullptr, 0)
46 :
47 : // ===========================================================================
48 : // member method definitions
49 : // ===========================================================================
50 :
51 35563 : MFXListIconItem::MFXListIconItem(const FXString& text, FXIcon* ic, FXColor backGroundColor, void* ptr):
52 35563 : label(text),
53 35563 : icon(ic),
54 35563 : data(ptr),
55 35563 : myBackGroundColor(backGroundColor) {
56 35563 : }
57 :
58 :
59 70994 : MFXListIconItem::~MFXListIconItem() {
60 35497 : if (state & ICONOWNED) {
61 0 : delete icon;
62 : }
63 35497 : icon = (FXIcon*) - 1L;
64 70994 : }
65 :
66 :
67 : void
68 14276 : MFXListIconItem::setFocus(FXbool focus) {
69 14276 : if (focus) {
70 7138 : state |= FOCUS;
71 : } else {
72 7138 : state &= ~(FXuint)FOCUS;
73 : }
74 14276 : }
75 :
76 :
77 : FXbool
78 35257 : MFXListIconItem::hasFocus() const {
79 35257 : return (state & FOCUS) != 0;
80 : }
81 :
82 :
83 : void
84 0 : MFXListIconItem::setSelected(FXbool selected) {
85 0 : if (selected) {
86 0 : state |= SELECTED;
87 : } else {
88 0 : state &= ~SELECTED;
89 : }
90 0 : }
91 :
92 :
93 : FXbool
94 70514 : MFXListIconItem::isSelected() const {
95 70514 : return (state & SELECTED) != 0;
96 : }
97 :
98 :
99 : void
100 0 : MFXListIconItem::setEnabled(FXbool enabled) {
101 0 : if (enabled) {
102 0 : state &= ~DISABLED;
103 : } else {
104 0 : state |= DISABLED;
105 : }
106 0 : }
107 :
108 :
109 : FXbool
110 35257 : MFXListIconItem::isEnabled() const {
111 35257 : return (state & DISABLED) == 0;
112 : }
113 :
114 :
115 : void
116 0 : MFXListIconItem::setDraggable(FXbool draggable) {
117 0 : if (draggable) {
118 0 : state |= DRAGGABLE;
119 : } else {
120 0 : state &= ~DRAGGABLE;
121 : }
122 0 : }
123 :
124 :
125 : FXbool
126 0 : MFXListIconItem::isDraggable() const {
127 0 : return (state & DRAGGABLE) != 0;
128 : }
129 :
130 :
131 : void
132 0 : MFXListIconItem::setText(const FXString& txt) {
133 0 : label = txt;
134 0 : }
135 :
136 :
137 : const FXString&
138 114135 : MFXListIconItem::getText() const {
139 114135 : return label;
140 : }
141 :
142 :
143 : FXIcon*
144 7138 : MFXListIconItem::getIcon() const {
145 7138 : return icon;
146 : }
147 :
148 :
149 : void
150 142252 : MFXListIconItem::create() {
151 142252 : if (icon) {
152 0 : icon->create();
153 : }
154 142252 : }
155 :
156 :
157 : void
158 0 : MFXListIconItem::destroy() {
159 0 : if ((state & ICONOWNED) && icon) {
160 0 : icon->destroy();
161 : }
162 0 : }
163 :
164 :
165 : void
166 0 : MFXListIconItem::detach() {
167 0 : if (icon) {
168 0 : icon->detach();
169 : }
170 0 : }
171 :
172 :
173 : FXint
174 149458 : MFXListIconItem::getWidth(const MFXListIcon* list) const {
175 : FXFont* font = list->getFont();
176 : FXint w = 0;
177 149458 : if (icon) {
178 : w = icon->getWidth();
179 : }
180 149458 : if (!label.empty()) {
181 149458 : if (w) {
182 0 : w += ICON_SPACING;
183 : }
184 149458 : w += font->getTextWidth(label.text(), label.length());
185 : }
186 149458 : return SIDE_SPACING + w;
187 : }
188 :
189 :
190 :
191 : FXint
192 206129 : MFXListIconItem::getHeight(const MFXListIcon* list) const {
193 : FXFont* font = list->getFont();
194 : FXint th = 0, ih = 0;
195 206129 : if (icon) {
196 : ih = icon->getHeight();
197 : }
198 206129 : if (!label.empty()) {
199 206129 : th = font->getFontHeight();
200 : }
201 206129 : return LINE_SPACING + FXMAX(th, ih);
202 : }
203 :
204 :
205 :
206 : const FXColor&
207 7138 : MFXListIconItem::getBackGroundColor() const {
208 7138 : return myBackGroundColor;
209 : }
210 :
211 :
212 0 : MFXListIconItem::MFXListIconItem() {}
213 :
214 :
215 : void
216 35257 : MFXListIconItem::draw(const MFXListIcon* list, FXDC& dc, FXint xx, FXint yy, FXint ww, FXint hh) {
217 : FXFont* font = list->getFont();
218 35257 : FXint ih = icon ? ICON_SIZE : 0;
219 : FXint th = 0;
220 35257 : if (!label.empty()) {
221 35257 : th = font->getFontHeight();
222 : }
223 35257 : if (isSelected()) {
224 0 : dc.setForeground(list->getSelBackColor());
225 : } else {
226 35257 : dc.setForeground(myBackGroundColor); // FIXME maybe paint background in onPaint?
227 : }
228 35257 : dc.fillRectangle(xx, yy, ww, hh);
229 35257 : if (hasFocus()) {
230 7045 : dc.drawFocusRectangle(xx + 1, yy + 1, ww - 2, hh - 2);
231 : }
232 35257 : xx += SIDE_SPACING / 2;
233 35257 : if (icon) {
234 0 : dc.drawIcon(icon, xx, yy + (hh - ih) / 2);
235 : }
236 35257 : if (icon) {
237 0 : xx += ICON_SPACING + ICON_SIZE;
238 : }
239 35257 : if (!label.empty()) {
240 35257 : dc.setFont(font);
241 35257 : if (!isEnabled()) {
242 0 : dc.setForeground(makeShadowColor(list->getBackColor()));
243 35257 : } else if (isSelected()) {
244 0 : dc.setForeground(list->getSelTextColor());
245 : } else {
246 35257 : dc.setForeground(list->getTextColor());
247 : }
248 35257 : dc.drawText(xx, yy + (hh - th) / 2 + font->getFontAscent(), label);
249 : }
250 35257 : }
251 :
252 :
253 : FXint
254 0 : 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 0 : if (icon) {
258 : iw = icon->getWidth();
259 : ih = icon->getHeight();
260 : }
261 0 : if (!label.empty()) {
262 0 : tw = 4 + font->getTextWidth(label.text(), label.length());
263 0 : th = 4 + font->getFontHeight();
264 : }
265 0 : h = LINE_SPACING + FXMAX(th, ih);
266 : ix = SIDE_SPACING / 2;
267 : tx = SIDE_SPACING / 2;
268 0 : if (iw) {
269 0 : tx += iw + ICON_SPACING;
270 : }
271 0 : iy = (h - ih) / 2;
272 0 : ty = (h - th) / 2;
273 :
274 : // In icon?
275 0 : if (ix <= xx && iy <= yy && xx < ix + iw && yy < iy + ih) {
276 : return 1;
277 : }
278 :
279 : // In text?
280 0 : if (tx <= xx && ty <= yy && xx < tx + tw && yy < ty + th) {
281 0 : return 2;
282 : }
283 :
284 : // Outside
285 : return 0;
286 : }
|