Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/foxtools/MFXTextFieldSearch.cpp
193905 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2006-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 MFXTextFieldSearch.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date May 2023
17
///
18
// TextField for search elements
19
/****************************************************************************/
20
21
#include <utils/common/MsgHandler.h>
22
#include <utils/gui/windows/GUIAppEnum.h>
23
#include <utils/gui/images/GUIIconSubSys.h>
24
25
#include "MFXTextFieldSearch.h"
26
27
// =========================================================================
28
// defines
29
// =========================================================================
30
31
#define ICON_SPACING 4 // Spacing between icon and label (2 + 2)
32
#define ICON_SIZE 16
33
34
// ===========================================================================
35
// FOX callback mapping
36
// ===========================================================================
37
38
FXDEFMAP(MFXTextFieldSearch) MFXTextFieldSearchMap[] = {
39
FXMAPFUNC(SEL_PAINT, 0, MFXTextFieldSearch::onPaint),
40
FXMAPFUNC(SEL_FOCUSIN, 0, MFXTextFieldSearch::onFocusIn),
41
FXMAPFUNC(SEL_FOCUSOUT, 0, MFXTextFieldSearch::onFocusOut),
42
FXMAPFUNC(SEL_FOCUS_SELF, 0, MFXTextFieldSearch::onFocusSelf),
43
FXMAPFUNC(SEL_KEYPRESS, 0, MFXTextFieldSearch::onKeyPress),
44
};
45
46
// Object implementation
47
FXIMPLEMENT(MFXTextFieldSearch, MFXTextFieldIcon, MFXTextFieldSearchMap, ARRAYNUMBER(MFXTextFieldSearchMap))
48
49
// ===========================================================================
50
// member method definitions
51
// ===========================================================================
52
53
MFXTextFieldSearch::MFXTextFieldSearch(FXComposite* p, MFXStaticToolTip* staticToolTip, FXObject* tgt, FXSelector sel,
54
FXuint opt, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb) :
55
MFXTextFieldIcon(p, staticToolTip, GUIIcon::SEARCH, tgt, sel, opt, x, y, w, h, pl, pr, pt, pb),
56
myTarget(tgt) {
57
}
58
59
60
long
61
MFXTextFieldSearch::onKeyPress(FXObject* obj, FXSelector sel, void* ptr) {
62
MFXTextFieldIcon::onKeyPress(obj, sel, ptr);
63
return myTarget->handle(this, FXSEL(SEL_COMMAND, MID_MTEXTFIELDSEARCH_UPDATED), ptr);
64
}
65
66
67
long
68
MFXTextFieldSearch::onPaint(FXObject*, FXSelector, void* ptr) {
69
FXEvent* ev = (FXEvent*)ptr;
70
FXDCWindow dc(this, ev);
71
// Draw frame
72
drawFrame(dc, 0, 0, width, height);
73
// Gray background if disabled
74
if (isEnabled()) {
75
dc.setForeground(backColor);
76
} else {
77
dc.setForeground(baseColor);
78
}
79
// Draw background
80
dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));
81
// Draw text, clipped against frame interior
82
dc.setClipRectangle(border, border, width - (border << 1), height - (border << 1));
83
// continue depending of search string
84
if (hasFocus() || (contents.count() > 0)) {
85
drawTextRange(dc, 0, contents.length());
86
} else {
87
drawSearchTextRange(dc, 0, TL("Type to search..."));
88
}
89
// Draw caret
90
if (flags & FLAG_CARET) {
91
int xx = coord(myCursorPosition) - 1;
92
xx += ICON_SPACING + ICON_SIZE;
93
dc.setForeground(myCursorColor);
94
dc.fillRectangle(xx, padtop + border, 1, height - padbottom - padtop - (border << 1));
95
dc.fillRectangle(xx - 2, padtop + border, 5, 1);
96
dc.fillRectangle(xx - 2, height - border - padbottom - 1, 5, 1);
97
}
98
// draw icon
99
dc.drawIcon(myIcon, 3, border + padtop + (height - padbottom - padtop - (border << 1) - ICON_SIZE) / 2);
100
return 1;
101
}
102
103
104
long
105
MFXTextFieldSearch::onFocusIn(FXObject* sender, FXSelector sel, void* ptr) {
106
update();
107
return MFXTextFieldIcon::onFocusIn(sender, sel, ptr);
108
}
109
110
111
112
long
113
MFXTextFieldSearch::onFocusOut(FXObject* sender, FXSelector sel, void* ptr) {
114
update();
115
return MFXTextFieldIcon::onFocusOut(sender, sel, ptr);
116
}
117
118
119
120
long
121
MFXTextFieldSearch::onFocusSelf(FXObject* sender, FXSelector sel, void* ptr) {
122
//onPaint(sender, sel, ptr);
123
return MFXTextFieldIcon::onFocusSelf(sender, sel, ptr);
124
}
125
126
127
MFXTextFieldSearch::MFXTextFieldSearch() :
128
MFXTextFieldIcon() {
129
}
130
131
132
void
133
MFXTextFieldSearch::drawSearchTextRange(FXDCWindow& dc, FXint fm, const FXString& searchString) {
134
FXint xx, yy, cw, hh, ww, si, ei, lx, rx, t;
135
FXint rr = width - border - padright;
136
FXint ll = border + padleft;
137
FXint mm = (ll + rr) / 2;
138
FXint to = (int)searchString.length();
139
if (to <= fm) {
140
return;
141
}
142
dc.setFont(myFont);
143
// Text color
144
dc.setForeground(FXRGBA(128, 128, 128, 255));
145
// Height
146
hh = myFont->getFontHeight();
147
// Text sticks to top of field
148
if (options & JUSTIFY_TOP) {
149
yy = padtop + border;
150
} else if (options & JUSTIFY_BOTTOM) {
151
// Text sticks to bottom of field
152
yy = height - padbottom - border - hh;
153
} else {
154
// Text centered in y
155
yy = border + padtop + (height - padbottom - padtop - (border << 1) - hh) / 2;
156
}
157
if (myAnchorPosition < myCursorPosition) {
158
si = myAnchorPosition;
159
ei = myCursorPosition;
160
} else {
161
si = myCursorPosition;
162
ei = myAnchorPosition;
163
}
164
// Normal mode
165
ww = myFont->getTextWidth(searchString.text(), searchString.length());
166
// Text sticks to right of field
167
if (options & JUSTIFY_RIGHT) {
168
xx = myShiftAmount + rr - ww;
169
} else if (options & JUSTIFY_LEFT) {
170
// Text sticks on left of field
171
xx = myShiftAmount + ll;
172
} else {
173
// Text centered in field
174
xx = myShiftAmount + mm - ww / 2;
175
}
176
// add icon spacing
177
xx += ICON_SPACING + ICON_SIZE;
178
// Reduce to avoid drawing excessive amounts of text
179
lx = xx + myFont->getTextWidth(&searchString[0], fm);
180
rx = lx + myFont->getTextWidth(&searchString[fm], to - fm);
181
while (fm < to) {
182
t = searchString.inc(fm);
183
cw = myFont->getTextWidth(&searchString[fm], t - fm);
184
if (lx + cw >= 0) {
185
break;
186
}
187
lx += cw;
188
fm = t;
189
}
190
while (fm < to) {
191
t = searchString.dec(to);
192
cw = myFont->getTextWidth(&searchString[t], to - t);
193
if (rx - cw < width) {
194
break;
195
}
196
rx -= cw;
197
to = t;
198
}
199
// Adjust selected range
200
if (si < fm) {
201
si = fm;
202
}
203
if (ei > to) {
204
ei = to;
205
}
206
// draw text
207
xx += myFont->getTextWidth(searchString.text(), fm);
208
yy += myFont->getFontAscent();
209
dc.drawText(xx, yy, &searchString[fm], to - fm);
210
}
211
212