Path: blob/main/src/utils/foxtools/MFXTextFieldSearch.cpp
193905 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2006-2026 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file MFXTextFieldSearch.cpp14/// @author Pablo Alvarez Lopez15/// @date May 202316///17// TextField for search elements18/****************************************************************************/1920#include <utils/common/MsgHandler.h>21#include <utils/gui/windows/GUIAppEnum.h>22#include <utils/gui/images/GUIIconSubSys.h>2324#include "MFXTextFieldSearch.h"2526// =========================================================================27// defines28// =========================================================================2930#define ICON_SPACING 4 // Spacing between icon and label (2 + 2)31#define ICON_SIZE 163233// ===========================================================================34// FOX callback mapping35// ===========================================================================3637FXDEFMAP(MFXTextFieldSearch) MFXTextFieldSearchMap[] = {38FXMAPFUNC(SEL_PAINT, 0, MFXTextFieldSearch::onPaint),39FXMAPFUNC(SEL_FOCUSIN, 0, MFXTextFieldSearch::onFocusIn),40FXMAPFUNC(SEL_FOCUSOUT, 0, MFXTextFieldSearch::onFocusOut),41FXMAPFUNC(SEL_FOCUS_SELF, 0, MFXTextFieldSearch::onFocusSelf),42FXMAPFUNC(SEL_KEYPRESS, 0, MFXTextFieldSearch::onKeyPress),43};4445// Object implementation46FXIMPLEMENT(MFXTextFieldSearch, MFXTextFieldIcon, MFXTextFieldSearchMap, ARRAYNUMBER(MFXTextFieldSearchMap))4748// ===========================================================================49// member method definitions50// ===========================================================================5152MFXTextFieldSearch::MFXTextFieldSearch(FXComposite* p, MFXStaticToolTip* staticToolTip, FXObject* tgt, FXSelector sel,53FXuint opt, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb) :54MFXTextFieldIcon(p, staticToolTip, GUIIcon::SEARCH, tgt, sel, opt, x, y, w, h, pl, pr, pt, pb),55myTarget(tgt) {56}575859long60MFXTextFieldSearch::onKeyPress(FXObject* obj, FXSelector sel, void* ptr) {61MFXTextFieldIcon::onKeyPress(obj, sel, ptr);62return myTarget->handle(this, FXSEL(SEL_COMMAND, MID_MTEXTFIELDSEARCH_UPDATED), ptr);63}646566long67MFXTextFieldSearch::onPaint(FXObject*, FXSelector, void* ptr) {68FXEvent* ev = (FXEvent*)ptr;69FXDCWindow dc(this, ev);70// Draw frame71drawFrame(dc, 0, 0, width, height);72// Gray background if disabled73if (isEnabled()) {74dc.setForeground(backColor);75} else {76dc.setForeground(baseColor);77}78// Draw background79dc.fillRectangle(border, border, width - (border << 1), height - (border << 1));80// Draw text, clipped against frame interior81dc.setClipRectangle(border, border, width - (border << 1), height - (border << 1));82// continue depending of search string83if (hasFocus() || (contents.count() > 0)) {84drawTextRange(dc, 0, contents.length());85} else {86drawSearchTextRange(dc, 0, TL("Type to search..."));87}88// Draw caret89if (flags & FLAG_CARET) {90int xx = coord(myCursorPosition) - 1;91xx += ICON_SPACING + ICON_SIZE;92dc.setForeground(myCursorColor);93dc.fillRectangle(xx, padtop + border, 1, height - padbottom - padtop - (border << 1));94dc.fillRectangle(xx - 2, padtop + border, 5, 1);95dc.fillRectangle(xx - 2, height - border - padbottom - 1, 5, 1);96}97// draw icon98dc.drawIcon(myIcon, 3, border + padtop + (height - padbottom - padtop - (border << 1) - ICON_SIZE) / 2);99return 1;100}101102103long104MFXTextFieldSearch::onFocusIn(FXObject* sender, FXSelector sel, void* ptr) {105update();106return MFXTextFieldIcon::onFocusIn(sender, sel, ptr);107}108109110111long112MFXTextFieldSearch::onFocusOut(FXObject* sender, FXSelector sel, void* ptr) {113update();114return MFXTextFieldIcon::onFocusOut(sender, sel, ptr);115}116117118119long120MFXTextFieldSearch::onFocusSelf(FXObject* sender, FXSelector sel, void* ptr) {121//onPaint(sender, sel, ptr);122return MFXTextFieldIcon::onFocusSelf(sender, sel, ptr);123}124125126MFXTextFieldSearch::MFXTextFieldSearch() :127MFXTextFieldIcon() {128}129130131void132MFXTextFieldSearch::drawSearchTextRange(FXDCWindow& dc, FXint fm, const FXString& searchString) {133FXint xx, yy, cw, hh, ww, si, ei, lx, rx, t;134FXint rr = width - border - padright;135FXint ll = border + padleft;136FXint mm = (ll + rr) / 2;137FXint to = (int)searchString.length();138if (to <= fm) {139return;140}141dc.setFont(myFont);142// Text color143dc.setForeground(FXRGBA(128, 128, 128, 255));144// Height145hh = myFont->getFontHeight();146// Text sticks to top of field147if (options & JUSTIFY_TOP) {148yy = padtop + border;149} else if (options & JUSTIFY_BOTTOM) {150// Text sticks to bottom of field151yy = height - padbottom - border - hh;152} else {153// Text centered in y154yy = border + padtop + (height - padbottom - padtop - (border << 1) - hh) / 2;155}156if (myAnchorPosition < myCursorPosition) {157si = myAnchorPosition;158ei = myCursorPosition;159} else {160si = myCursorPosition;161ei = myAnchorPosition;162}163// Normal mode164ww = myFont->getTextWidth(searchString.text(), searchString.length());165// Text sticks to right of field166if (options & JUSTIFY_RIGHT) {167xx = myShiftAmount + rr - ww;168} else if (options & JUSTIFY_LEFT) {169// Text sticks on left of field170xx = myShiftAmount + ll;171} else {172// Text centered in field173xx = myShiftAmount + mm - ww / 2;174}175// add icon spacing176xx += ICON_SPACING + ICON_SIZE;177// Reduce to avoid drawing excessive amounts of text178lx = xx + myFont->getTextWidth(&searchString[0], fm);179rx = lx + myFont->getTextWidth(&searchString[fm], to - fm);180while (fm < to) {181t = searchString.inc(fm);182cw = myFont->getTextWidth(&searchString[fm], t - fm);183if (lx + cw >= 0) {184break;185}186lx += cw;187fm = t;188}189while (fm < to) {190t = searchString.dec(to);191cw = myFont->getTextWidth(&searchString[t], to - t);192if (rx - cw < width) {193break;194}195rx -= cw;196to = t;197}198// Adjust selected range199if (si < fm) {200si = fm;201}202if (ei > to) {203ei = to;204}205// draw text206xx += myFont->getTextWidth(searchString.text(), fm);207yy += myFont->getFontAscent();208dc.drawText(xx, yy, &searchString[fm], to - fm);209}210211212