Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2004-2026 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 MFXTreeListDynamic.cpp
15 : /// @author Pablo Alvarez Lopez
16 : /// @date Feb 2021
17 : ///
18 : //
19 : /****************************************************************************/
20 :
21 : #include "MFXTreeListDynamic.h"
22 :
23 : #include <utils/common/UtilExceptions.h>
24 :
25 : #define SIDE_SPACING 4 // Spacing between side and item
26 : #define ICON_SPACING 4 // Spacing between parent and child in x direction
27 :
28 : // ===========================================================================
29 : // FOX callback mapping
30 : // ===========================================================================
31 :
32 : FXDEFMAP(MFXTreeListDynamic) MFXTreeListDynamicMap[] = {
33 : FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, MFXTreeListDynamic::onLeftBtnPress),
34 : };
35 :
36 : // Object implementation
37 0 : FXIMPLEMENT(MFXTreeListDynamic, FXTreeList, MFXTreeListDynamicMap, ARRAYNUMBER(MFXTreeListDynamicMap))
38 :
39 : // ===========================================================================
40 : // member method definitions
41 : // ===========================================================================
42 :
43 : // FXTreeItemDynamic
44 :
45 0 : FXTreeItemDynamic::FXTreeItemDynamic(const FXString& text, FXIcon* oi, FXIcon* ci, void* ptr) :
46 0 : FXTreeItem(text, oi, ci, ptr) {
47 0 : }
48 :
49 :
50 : void
51 0 : FXTreeItemDynamic::setTextColor(FXColor clr) {
52 0 : myTextColor = clr;
53 0 : }
54 :
55 :
56 : void
57 0 : FXTreeItemDynamic::draw(const FXTreeList* list, FXDC& dc, FXint xx, FXint yy, FXint, FXint hh) const {
58 0 : FXIcon* icon = (state & OPENED) ? openIcon : closedIcon;
59 : FXFont* font = list->getFont();
60 : FXint th = 0, tw = 0, ih = 0, iw = 0;
61 0 : xx += SIDE_SPACING / 2;
62 0 : if (icon) {
63 : iw = icon->getWidth();
64 : ih = icon->getHeight();
65 : dc.drawIcon(icon, xx, yy + (hh - ih) / 2);
66 0 : xx += ICON_SPACING + iw;
67 : }
68 0 : if (!label.empty()) {
69 0 : tw = 4 + font->getTextWidth(label.text(), label.length());
70 0 : th = 4 + font->getFontHeight();
71 0 : yy += (hh - th) / 2;
72 0 : if (isSelected()) {
73 0 : dc.setForeground(list->getSelBackColor());
74 0 : dc.fillRectangle(xx, yy, tw, th);
75 : }
76 0 : if (hasFocus()) {
77 0 : dc.drawFocusRectangle(xx + 1, yy + 1, tw - 2, th - 2);
78 : }
79 0 : if (!isEnabled()) {
80 0 : dc.setForeground(makeShadowColor(list->getBackColor()));
81 0 : } else if (isSelected()) {
82 0 : dc.setForeground(list->getSelTextColor());
83 : } else {
84 0 : dc.setForeground(myTextColor);
85 : }
86 0 : dc.drawText(xx + 2, yy + font->getFontAscent() + 2, label);
87 : }
88 0 : }
89 :
90 : // MFXTreeListDynamic
91 :
92 0 : MFXTreeListDynamic::MFXTreeListDynamic(FXComposite* p, FXObject* tgt, FXSelector sel, FXuint opts) :
93 0 : FXTreeList(p, tgt, sel, opts, 0, 0, 0, 200) {
94 0 : }
95 :
96 :
97 : void
98 0 : MFXTreeListDynamic::show() {
99 : // update height
100 0 : setHeight(getContentHeight() + 20);
101 : // show
102 0 : FXTreeList::show();
103 0 : }
104 :
105 :
106 : void
107 0 : MFXTreeListDynamic::hide() {
108 : // hide
109 0 : FXTreeList::hide();
110 0 : }
111 :
112 :
113 : void
114 0 : MFXTreeListDynamic::update() {
115 : // update
116 0 : FXTreeList::update();
117 0 : }
118 :
119 :
120 : void
121 0 : MFXTreeListDynamic::clearItems() {
122 : myFXTreeItemDynamicItems.clear();
123 0 : return FXTreeList::clearItems();
124 : }
125 :
126 :
127 : FXint
128 0 : MFXTreeListDynamic::getNumItems() {
129 0 : return FXTreeList::getNumItems();
130 : }
131 :
132 :
133 : FXint
134 0 : MFXTreeListDynamic::getSelectedIndex() {
135 0 : return mySelectedItem;
136 : }
137 :
138 :
139 : FXTreeItem*
140 0 : MFXTreeListDynamic::prependItem(FXTreeItem* father, const FXString& text, FXIcon* oi, FXColor tColor) {
141 0 : FXTreeItemDynamic* newItem = dynamic_cast<FXTreeItemDynamic*>(FXTreeList::prependItem(father, new FXTreeItemDynamic(text, oi, oi, nullptr), false));
142 0 : if (newItem != nullptr) {
143 0 : myFXTreeItemDynamicItems.insert(myFXTreeItemDynamicItems.begin(), newItem);
144 0 : newItem->setTextColor(tColor);
145 0 : return newItem;
146 : }
147 0 : throw ProcessError("New item cannot be NULL");
148 : }
149 :
150 :
151 : FXTreeItem*
152 0 : MFXTreeListDynamic::appendItem(FXTreeItem* father, const FXString& text, FXIcon* oi, FXColor tColor) {
153 0 : FXTreeItemDynamic* newItem = dynamic_cast<FXTreeItemDynamic*>(FXTreeList::appendItem(father, new FXTreeItemDynamic(text, oi, oi, nullptr), false));
154 0 : if (newItem != nullptr) {
155 0 : myFXTreeItemDynamicItems.push_back(newItem);
156 0 : newItem->setTextColor(tColor);
157 0 : return newItem;
158 : }
159 0 : throw ProcessError("New item cannot be NULL");
160 : }
161 :
162 :
163 : FXWindow*
164 0 : MFXTreeListDynamic::getFXWindow() {
165 0 : return this;
166 : }
167 :
168 :
169 : FXTreeItem*
170 0 : MFXTreeListDynamic::getItemAt(FXint x, FXint y) const {
171 0 : return FXTreeList::getItemAt(x, y);
172 : }
173 :
174 :
175 : FXTreeItemDynamic*
176 0 : MFXTreeListDynamic::getItem(FXint index) const {
177 0 : return myFXTreeItemDynamicItems.at(index);
178 : }
179 :
180 :
181 : void
182 0 : MFXTreeListDynamic::resetSelectedItem() {
183 0 : if (mySelectedItem != -1) {
184 0 : myFXTreeItemDynamicItems.at(mySelectedItem)->setSelected(false);
185 0 : mySelectedItem = -1;
186 : }
187 0 : }
188 :
189 :
190 : long
191 0 : MFXTreeListDynamic::onLeftBtnPress(FXObject* obj, FXSelector sel, void* ptr) {
192 0 : FXTreeList::onLeftBtnPress(obj, sel, ptr);
193 : // update selected item
194 0 : mySelectedItem = -1;
195 0 : for (int i = 0; i < (int)myFXTreeItemDynamicItems.size(); i++) {
196 0 : if (myFXTreeItemDynamicItems.at(i)->isSelected()) {
197 0 : mySelectedItem = i;
198 : }
199 : }
200 : // update height
201 0 : setHeight(getContentHeight() + 20);
202 0 : return 1;
203 : }
204 :
205 :
206 0 : MFXTreeListDynamic::MFXTreeListDynamic() :
207 0 : FXTreeList::FXTreeList() {
208 0 : }
|