Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MFXDynamicLabel.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-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/****************************************************************************/
18// Text label with dynamic multi-line text (inserts line line breaks on the fly)
19/****************************************************************************/
20#include <config.h>
21#include "MFXDynamicLabel.h"
22
23// ===========================================================================
24// FOX callback mapping
25// ===========================================================================
26
27FXDEFMAP(MFXDynamicLabel) MFXLabelMap[] = {
28 FXMAPFUNC(SEL_UPDATE, 0, MFXDynamicLabel::onUpdate),
29};
30
31// Object implementation
32FXIMPLEMENT(MFXDynamicLabel, FXLabel, MFXLabelMap, ARRAYNUMBER(MFXLabelMap))
33
34// ===========================================================================
35// method definitions
36// ===========================================================================
37
38// ---------------------------------------------------------------------------
39// MFXLabel - public methods
40// ---------------------------------------------------------------------------
41
42MFXDynamicLabel::MFXDynamicLabel(FXComposite* p, const FXString& text, FXIcon* ic, FXuint opts, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb, std::string indent):
43 FXLabel(p, text, ic, opts, x, y, w, h, pl, pr, pt, pb), myOriginalString(text.text()), myIndentString(indent), myPreviousWidth(0) {
44 computeIndentation();
45}
46
47
48long
49MFXDynamicLabel::onUpdate(FXObject* sender, FXSelector sel, void* ptr) {
50 const int curWidth = getWidth();
51 if (myPreviousWidth - curWidth != 0 && curWidth > 1) {
52 reformatLineBreaks(curWidth);
53 myPreviousWidth = curWidth;
54 }
55 return FXLabel::onUpdate(sender, sel, ptr);
56}
57
58
59void
60MFXDynamicLabel::setText(const FXString& text) {
61 FXLabel::setText(text);
62 myOriginalString = text.text();
64}
65
66
67void
68MFXDynamicLabel::position(FXint x, FXint y, FXint w, FXint h) {
69 FXLabel::position(x, y, w, h);
71}
72
73
74FXint
76 int pWidth = getParent()->getWidth();
77 if (pWidth > 1) { // sign that it has been initialised
78 FXFrame* frame = dynamic_cast<FXFrame*>(getParent());
79 int padding = 0;
80 if (frame != nullptr) {
81 padding = frame->getPadLeft() + frame->getPadRight();
82 }
83 reformatLineBreaks(pWidth - padding);
84 }
85 return FXLabel::getDefaultHeight();
86}
87
88
89void
91 if (myOriginalString.find(myIndentString) == 0 || myOriginalString.find("\n" + myIndentString) != std::string::npos) {
92 myIndent = (int)myIndentString.size();
93 } else {
94 myIndent = 0;
95 }
96}
97
98
99void
101 const int preferredWidth = curWidth - getPadLeft() - getPadRight();
102 const int textWidth = getApp()->getNormalFont()->getTextWidth(label);
103 if (textWidth <= preferredWidth || preferredWidth < 1) {
104 return;
105 }
106 std::string newLine = "\n" + std::string(myIndent, ' ');
107 const int newLineOffset = (int)newLine.size();
108 std::string msg = myOriginalString;
109 int pos = 0;
110 int finalPos = (int)msg.size() - 1;
111 std::string::size_type nextLineBreak;
112 while (pos < finalPos) {
113 nextLineBreak = msg.find('\n', pos);
114 int subPos = (nextLineBreak != std::string::npos) ? (int)nextLineBreak : finalPos;
115 if (getApp()->getNormalFont()->getTextWidth(msg.substr(pos, subPos - pos).c_str()) <= preferredWidth) {
116 pos = subPos + 1;
117 continue;
118 }
119 if (myIndent > 0 && msg.substr(pos, myIndent) == myIndentString) {
120 pos += myIndent;
121 }
122 // select position for next line break
123 const int endPos = (nextLineBreak != std::string::npos) ? (int)nextLineBreak - 1 : finalPos;
124 std::string::size_type nextSpace = std::string::npos;
125 int lastSpacePos = -1;
126 int pos2 = pos;
127 while (pos2 < endPos) {
128 nextSpace = msg.find(' ', pos2);
129 if (nextSpace != std::string::npos && (int)nextSpace <= pos + myIndent) {
130 nextSpace = std::string::npos;
131 pos2 += myIndent + 1;
132 } else if (nextSpace != std::string::npos && (int)nextSpace < endPos) {
133 std::string testString = msg.substr(pos, nextSpace - pos);
134 if (getApp()->getNormalFont()->getTextWidth(msg.substr(pos, nextSpace - pos).c_str()) > preferredWidth) {
135 if (lastSpacePos > 0) {
136 msg.replace(lastSpacePos, 1, newLine);
137 pos2 = lastSpacePos + newLineOffset;
138 finalPos += newLineOffset;
139 } else {
140 msg.replace(nextSpace, 1, newLine);
141 pos2 = (int)nextSpace + newLineOffset;
142 finalPos += newLineOffset;
143 }
144 break;
145 } else {
146 pos2 = (int)nextSpace + 1;
147 if (msg.find(' ', pos2) == std::string::npos && lastSpacePos > 0) { // string end condition
148 msg.replace(lastSpacePos, 1, newLine);
149 pos2 += newLineOffset;
150 break;
151 }
152 }
153 lastSpacePos = (int)nextSpace;
154 } else {
155 pos2 = endPos + 2;
156 }
157 }
158 pos = pos2;
159 }
160 label = msg.c_str();
161}
162
163
FXDEFMAP(MFXDynamicLabel) MFXLabelMap[]
A list item which allows for custom coloring.
void reformatLineBreaks(const int curWidth)
MFXDynamicLabel()
fox needs this
void setText(const FXString &text)
overload text label updates to store the original string as backup for when width changes again
void position(FXint x, FXint y, FXint w, FXint h)
overload position to be informed when the parent has done the layout
long onUpdate(FXObject *sender, FXSelector, void *)
overload to be informed when the label text has to be reformatted due to width changes
std::string myOriginalString
std::string myIndentString
Definition json.hpp:4471