Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 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 GUIParameterTracker.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Sept 2002
19 : ///
20 : // A window which displays the time line of one (or more) value(s)
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <string>
25 : #include <fstream>
26 : #include <utils/common/MsgHandler.h>
27 : #include <utils/common/ToString.h>
28 : #include <utils/common/StringUtils.h>
29 : #include <utils/common/SUMOTime.h>
30 : #include <utils/foxtools/MFXUtils.h>
31 : #include <utils/iodevices/OutputDevice.h>
32 : #include <utils/gui/div/GLHelper.h>
33 : #include <utils/gui/globjects/GUIGlObject.h>
34 : #include <utils/gui/div/GUIIOGlobals.h>
35 : #include <utils/gui/div/GUIDesigns.h>
36 : #include <utils/gui/windows/GUIAppEnum.h>
37 : #include <utils/gui/windows/GUIMainWindow.h>
38 : #include <utils/gui/images/GUIIconSubSys.h>
39 : #include <foreign/fontstash/fontstash.h>
40 : #include <utils/gui/globjects/GLIncludes.h>
41 : #include "GUIParameterTracker.h"
42 :
43 :
44 : // ===========================================================================
45 : // FOX callback mapping
46 : // ===========================================================================
47 : FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[] = {
48 : FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::onConfigure),
49 : FXMAPFUNC(SEL_PAINT, 0, GUIParameterTracker::onPaint),
50 : FXMAPFUNC(SEL_COMMAND, MID_SIMSTEP, GUIParameterTracker::onSimStep),
51 : FXMAPFUNC(SEL_COMMAND, GUIParameterTracker::MID_MULTIPLOT, GUIParameterTracker::onMultiPlot),
52 : FXMAPFUNC(SEL_COMMAND, GUIParameterTracker::MID_AGGREGATIONINTERVAL, GUIParameterTracker::onCmdChangeAggregation),
53 : FXMAPFUNC(SEL_COMMAND, GUIParameterTracker::MID_SAVE, GUIParameterTracker::onCmdSave),
54 :
55 : };
56 :
57 : // Macro for the GLTestApp class hierarchy implementation
58 0 : FXIMPLEMENT(GUIParameterTracker, FXMainWindow, GUIParameterTrackerMap, ARRAYNUMBER(GUIParameterTrackerMap))
59 :
60 : // ===========================================================================
61 : // static value definitions
62 : // ===========================================================================
63 : std::set<GUIParameterTracker*> GUIParameterTracker::myMultiPlots;
64 : std::vector<RGBColor> GUIParameterTracker::myColors;
65 :
66 :
67 : // ===========================================================================
68 : // method definitions
69 : // ===========================================================================
70 0 : GUIParameterTracker::GUIParameterTracker(GUIMainWindow& app,
71 0 : const std::string& name)
72 : : FXMainWindow(app.getApp(), "Tracker", nullptr, nullptr, DECOR_ALL, 20, 20, 300, 200),
73 0 : myApplication(&app) {
74 0 : buildToolBar();
75 0 : app.addChild(this);
76 0 : FXVerticalFrame* glcanvasFrame = new FXVerticalFrame(this, FRAME_SUNKEN | LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
77 0 : myPanel = new GUIParameterTrackerPanel(glcanvasFrame, *myApplication, *this);
78 0 : setTitle(name.c_str());
79 0 : setIcon(GUIIconSubSys::getIcon(GUIIcon::APP_TRACKER));
80 :
81 0 : if (myColors.size() == 0) {
82 0 : myColors = {RGBColor::BLACK, RGBColor::GREEN, RGBColor::RED, RGBColor::BLUE, RGBColor::ORANGE, RGBColor::CYAN, RGBColor::MAGENTA};
83 :
84 : }
85 0 : }
86 :
87 :
88 0 : GUIParameterTracker::~GUIParameterTracker() {
89 0 : myMultiPlots.erase(this);
90 0 : myApplication->removeChild(this);
91 0 : for (std::vector<TrackerValueDesc*>::iterator i1 = myTracked.begin(); i1 != myTracked.end(); i1++) {
92 0 : delete (*i1);
93 : }
94 : // deleted by GUINet
95 0 : for (std::vector<GLObjectValuePassConnector<double>*>::iterator i2 = myValuePassers.begin(); i2 != myValuePassers.end(); i2++) {
96 0 : delete (*i2);
97 : }
98 0 : delete myToolBarDrag;
99 0 : delete myToolBar;
100 0 : }
101 :
102 :
103 : void
104 0 : GUIParameterTracker::create() {
105 0 : FXMainWindow::create();
106 0 : myToolBarDrag->create();
107 0 : }
108 :
109 :
110 : void
111 0 : GUIParameterTracker::buildToolBar() {
112 0 : myToolBarDrag = new FXToolBarShell(this, GUIDesignToolBar);
113 0 : myToolBar = new FXToolBar(this, myToolBarDrag, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | FRAME_RAISED);
114 0 : new FXToolBarGrip(myToolBar, myToolBar, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
115 : // save button
116 0 : GUIDesigns::buildFXButton(myToolBar, "", "", + TL("Save the data..."),
117 : GUIIconSubSys::getIcon(GUIIcon::SAVE), this, GUIParameterTracker::MID_SAVE, GUIDesignButtonToolbar);
118 :
119 : // aggregation interval combo
120 0 : myAggregationInterval = new MFXComboBoxIcon(myToolBar, nullptr, false, GUIDesignComboBoxVisibleItems,
121 0 : this, MID_AGGREGATIONINTERVAL, GUIDesignComboBoxStatic);
122 0 : myAggregationInterval->appendIconItem("1s");
123 0 : myAggregationInterval->appendIconItem("1min");
124 0 : myAggregationInterval->appendIconItem("5min");
125 0 : myAggregationInterval->appendIconItem("15min");
126 0 : myAggregationInterval->appendIconItem("30min");
127 0 : myAggregationInterval->appendIconItem("60min");
128 :
129 0 : myMultiPlot = new FXCheckButton(myToolBar, TL("Multiplot"), this, MID_MULTIPLOT);
130 0 : myMultiPlot->setCheck(false);
131 0 : }
132 :
133 :
134 : bool
135 0 : GUIParameterTracker::addTrackedMultiplot(GUIGlObject& o, ValueSource<double>* src, TrackerValueDesc* newTracked) {
136 : bool first = true;
137 0 : for (GUIParameterTracker* tr : myMultiPlots) {
138 0 : if (first) {
139 : first = false;
140 : } else {
141 : // each Tracker gets its own copy to simplify cleanup
142 : newTracked = new TrackerValueDesc(newTracked->getName(), RGBColor::BLACK, newTracked->getRecordingBegin(),
143 0 : STEPS2TIME(newTracked->getAggregationSpan()));
144 0 : src = src->copy();
145 : }
146 0 : tr->addTracked(o, src, newTracked);
147 : }
148 0 : return myMultiPlots.size() > 0;
149 : }
150 :
151 :
152 : void
153 0 : GUIParameterTracker::addTracked(GUIGlObject& o, ValueSource<double>* src,
154 : TrackerValueDesc* newTracked) {
155 0 : myTracked.push_back(newTracked);
156 : // build connection (is automatically set into an execution map)
157 0 : myValuePassers.push_back(new GLObjectValuePassConnector<double>(o, src, newTracked));
158 0 : update();
159 0 : }
160 :
161 :
162 : long
163 0 : GUIParameterTracker::onConfigure(FXObject* sender, FXSelector sel, void* ptr) {
164 0 : myPanel->onConfigure(sender, sel, ptr);
165 0 : return FXMainWindow::onConfigure(sender, sel, ptr);
166 : }
167 :
168 :
169 : long
170 0 : GUIParameterTracker::onPaint(FXObject* sender, FXSelector sel, void* ptr) {
171 0 : myPanel->onPaint(sender, sel, ptr);
172 0 : return FXMainWindow::onPaint(sender, sel, ptr);
173 : }
174 :
175 :
176 : long
177 0 : GUIParameterTracker::onSimStep(FXObject*, FXSelector, void*) {
178 0 : update();
179 0 : return 1;
180 : }
181 :
182 : long
183 0 : GUIParameterTracker::onCmdChangeAggregation(FXObject*, FXSelector, void*) {
184 0 : int index = myAggregationInterval->getCurrentItem();
185 : int aggInt = 0;
186 : switch (index) {
187 : case 0:
188 : aggInt = 1;
189 : break;
190 : case 1:
191 : aggInt = 60;
192 : break;
193 : case 2:
194 : aggInt = 60 * 5;
195 : break;
196 : case 3:
197 : aggInt = 60 * 15;
198 : break;
199 : case 4:
200 : aggInt = 60 * 30;
201 : break;
202 : case 5:
203 : aggInt = 60 * 60;
204 : break;
205 0 : default:
206 0 : throw 1;
207 : }
208 0 : for (TrackerValueDesc* const tvd : myTracked) {
209 0 : tvd->setAggregationSpan(TIME2STEPS(aggInt));
210 : }
211 0 : return 1;
212 : }
213 :
214 :
215 : long
216 0 : GUIParameterTracker::onCmdSave(FXObject*, FXSelector, void*) {
217 0 : FXString file = MFXUtils::getFilename2Write(this, TL("Save Data"),
218 0 : SUMOXMLDefinitions::CSVFileExtensions.getMultilineString().c_str(),
219 0 : GUIIconSubSys::getIcon(GUIIcon::EMPTY), gCurrentFolder);
220 0 : if (file == "") {
221 : return 1;
222 : }
223 : try {
224 0 : OutputDevice& dev = OutputDevice::getDevice(file.text());
225 : // write header
226 : std::vector<TrackerValueDesc*>::iterator i;
227 0 : dev << "# Time";
228 0 : for (i = myTracked.begin(); i != myTracked.end(); ++i) {
229 0 : TrackerValueDesc* tvd = *i;
230 0 : dev << ';' << tvd->getName();
231 : }
232 0 : dev << '\n';
233 : // count entries
234 : int max = 0;
235 0 : for (i = myTracked.begin(); i != myTracked.end(); ++i) {
236 0 : TrackerValueDesc* tvd = *i;
237 0 : int sizei = (int)tvd->getAggregatedValues().size();
238 0 : if (max < sizei) {
239 : max = sizei;
240 : }
241 0 : tvd->unlockValues();
242 : }
243 : // write entries
244 0 : SUMOTime t = myTracked.empty() ? 0 : myTracked.front()->getRecordingBegin();
245 0 : SUMOTime dt = myTracked.empty() ? DELTA_T : myTracked.front()->getAggregationSpan();
246 0 : for (int j = 0; j < max; j++) {
247 0 : dev << time2string(t);
248 0 : for (i = myTracked.begin(); i != myTracked.end(); ++i) {
249 0 : TrackerValueDesc* tvd = *i;
250 0 : dev << ';' << tvd->getAggregatedValues()[j];
251 0 : tvd->unlockValues();
252 : }
253 0 : dev << '\n';
254 0 : t += dt;
255 : }
256 0 : dev.close();
257 0 : } catch (IOError& e) {
258 0 : FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
259 0 : }
260 : return 1;
261 0 : }
262 :
263 :
264 : long
265 0 : GUIParameterTracker::onMultiPlot(FXObject*, FXSelector, void*) {
266 0 : if (myMultiPlot->getCheck()) {
267 0 : myMultiPlots.insert(this);
268 : } else {
269 0 : myMultiPlots.erase(this);
270 : }
271 0 : return 1;
272 : }
273 :
274 : /* -------------------------------------------------------------------------
275 : * GUIParameterTracker::GUIParameterTrackerPanel-methods
276 : * ----------------------------------------------------------------------- */
277 : FXDEFMAP(GUIParameterTracker::GUIParameterTrackerPanel) GUIParameterTrackerPanelMap[] = {
278 : FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::GUIParameterTrackerPanel::onConfigure),
279 : FXMAPFUNC(SEL_MOTION, 0, GUIParameterTracker::GUIParameterTrackerPanel::onMouseMove),
280 : FXMAPFUNC(SEL_PAINT, 0, GUIParameterTracker::GUIParameterTrackerPanel::onPaint),
281 :
282 : };
283 :
284 : // Macro for the GLTestApp class hierarchy implementation
285 0 : FXIMPLEMENT(GUIParameterTracker::GUIParameterTrackerPanel, FXGLCanvas, GUIParameterTrackerPanelMap, ARRAYNUMBER(GUIParameterTrackerPanelMap))
286 :
287 :
288 :
289 0 : GUIParameterTracker::GUIParameterTrackerPanel::GUIParameterTrackerPanel(
290 : FXComposite* c, GUIMainWindow& app,
291 0 : GUIParameterTracker& parent)
292 0 : : FXGLCanvas(c, app.getGLVisual(), app.getBuildGLCanvas(), (FXObject*) nullptr, (FXSelector) 0, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 300, 200),
293 0 : myParent(&parent) {}
294 :
295 :
296 0 : GUIParameterTracker::GUIParameterTrackerPanel::~GUIParameterTrackerPanel() {}
297 :
298 :
299 : void
300 0 : GUIParameterTracker::GUIParameterTrackerPanel::drawValues() {
301 0 : glMatrixMode(GL_PROJECTION);
302 0 : glLoadIdentity();
303 0 : glMatrixMode(GL_MODELVIEW);
304 0 : glLoadIdentity();
305 0 : glDisable(GL_TEXTURE_2D);
306 0 : for (int i = 0; i < (int)myParent->myTracked.size(); i++) {
307 0 : TrackerValueDesc* desc = myParent->myTracked[i];
308 0 : glPushMatrix();
309 0 : drawValue(*desc, myColors[i % myColors.size()], i);
310 0 : glPopMatrix();
311 : }
312 0 : }
313 :
314 :
315 : void
316 0 : GUIParameterTracker::GUIParameterTrackerPanel::drawValue(TrackerValueDesc& desc,
317 : const RGBColor& col,
318 : int index) {
319 0 : const double fontWidth = 0.1 * 300. / myWidthInPixels;
320 0 : const double fontHeight = 0.1 * 300. / myHeightInPixels;
321 0 : const bool isMultiPlot = myParent->myTracked.size() > 1;
322 0 : const std::vector<double>& values = desc.getAggregatedValues();
323 0 : if (values.size() < 2) {
324 : // draw name
325 0 : glTranslated(-.9, 0.9, 0);
326 0 : GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
327 0 : desc.unlockValues();
328 0 : return;
329 : }
330 : //
331 : // apply scaling
332 0 : GLHelper::pushMatrix();
333 :
334 : // apply the positiopn offset of the display
335 0 : glScaled(0.8, 0.8, 1);
336 : // apply value range scaling
337 0 : double ys = (double) 2.0 / (double) desc.getRange();
338 0 : glScaled(1.0, ys, 1.0);
339 0 : glTranslated(-1.0, -desc.getYCenter(), 0);
340 :
341 : // draw value bounderies
342 : // draw minimum boundary
343 0 : glBegin(GL_LINES);
344 0 : glVertex2d(0, desc.getMin());
345 0 : glVertex2d(2.0, desc.getMin());
346 0 : glEnd();
347 0 : glBegin(GL_LINES);
348 0 : glVertex2d(0, desc.getMax());
349 0 : glVertex2d(2.0, desc.getMax());
350 0 : glEnd();
351 0 : GLHelper::setColor(col.changedAlpha(-178));
352 0 : for (int a = 1; a < 6; a++) {
353 0 : const double yp = desc.getRange() / 6.0 * (double) a + desc.getMin();
354 0 : glBegin(GL_LINES);
355 0 : glVertex2d(0, yp);
356 0 : glVertex2d(2.0, yp);
357 0 : glEnd();
358 : }
359 :
360 : double latest = 0;
361 0 : double mx = (2 * myMouseX / myWidthInPixels - 1) / 0.8 + 1;
362 : int mIndex = 0;
363 0 : double mouseValue = std::numeric_limits<double>::max();
364 0 : latest = values.back();
365 : // init values
366 0 : const double xStep = 2.0 / (double) values.size();
367 : std::vector<double>::const_iterator i = values.begin();
368 0 : double yp = (*i);
369 : double xp = 0;
370 : i++;
371 0 : GLHelper::setColor(col);
372 0 : for (; i != values.end(); i++) {
373 0 : double yn = (*i);
374 0 : double xn = xp + xStep;
375 0 : if (xp < mx && mx < xn) {
376 0 : mouseValue = yp;
377 0 : mIndex = (int)(i - values.begin()) - 1;
378 0 : glPushMatrix();
379 0 : GLHelper::setColor(isMultiPlot ? col.changedBrightness(-40).changedAlpha(-100) : RGBColor::BLUE);
380 0 : glTranslated(xn, yn, 0);
381 0 : glScaled(20.0 / myWidthInPixels, 10.0 * desc.getRange() / myHeightInPixels, 0);
382 0 : GLHelper::drawFilledCircle(1, 8);
383 0 : GLHelper::setColor(col);
384 0 : glPopMatrix();
385 : }
386 0 : glBegin(GL_LINES);
387 0 : glVertex2d(xp, yp);
388 0 : glVertex2d(xn, yn);
389 0 : glEnd();
390 : yp = yn;
391 : xp = xn;
392 : }
393 0 : desc.unlockValues();
394 0 : GLHelper::popMatrix();
395 :
396 : // draw value bounderies and descriptions
397 0 : GLHelper::setColor(col);
398 :
399 : // draw min time
400 0 : SUMOTime beginStep = desc.getRecordingBegin();
401 0 : std::string begStr = time2string(beginStep);
402 0 : double w = 50 / myWidthInPixels;
403 0 : glTranslated(-0.8 - w / 2., -0.88, 0);
404 0 : GLHelper::drawText(begStr, Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
405 0 : glTranslated(0.8 + w / 2., 0.88, 0);
406 :
407 : // draw max time
408 0 : glTranslated(0.75, -0.88, 0);
409 0 : GLHelper::drawText(time2string(beginStep + static_cast<SUMOTime>(values.size() * desc.getAggregationSpan())),
410 0 : Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
411 0 : glTranslated(-0.75, 0.88, 0);
412 :
413 : // draw min value
414 0 : glTranslated(-0.98, -0.82, 0);
415 0 : GLHelper::drawText(toString(desc.getMin()), Position(0, index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
416 0 : glTranslated(0.98, 0.82, 0);
417 :
418 : // draw max value
419 0 : glTranslated(-0.98, 0.78, 0);
420 0 : GLHelper::drawText(toString(desc.getMax()), Position(0, -index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
421 0 : glTranslated(0.98, -0.78, 0);
422 :
423 : // draw name
424 0 : glTranslated(-0.98, .92, 0);
425 0 : GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
426 0 : glTranslated(0.98, -.92, 0);
427 :
428 : // draw current value (with contrasting color)
429 : double p = (double) 0.8 -
430 0 : ((double) 1.6 / (desc.getMax() - desc.getMin()) * (latest - desc.getMin()));
431 0 : glTranslated(-0.98, -(p + .02), 0);
432 0 : GLHelper::drawText(toString(latest), Position(isMultiPlot ? 0.1 : 0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(50) : RGBColor::RED, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
433 0 : glTranslated(0.98, p + .02, 0);
434 :
435 : // draw moused value
436 0 : if (mouseValue != std::numeric_limits<double>::max()) {
437 0 : p = (double) 0.8 -
438 0 : ((double) 1.6 / (desc.getMax() - desc.getMin()) * (mouseValue - desc.getMin()));
439 0 : glTranslated(-0.98, -(p + .02), 0);
440 0 : GLHelper::drawText(toString(mouseValue), Position(isMultiPlot ? 0.1 : 0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(-40) : RGBColor::BLUE, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
441 0 : glTranslated(0.98, p + .02, 0);
442 :
443 0 : if (index == 0) {
444 : // time is the same for all plots so we only draw it once
445 0 : const std::string mouseTime = time2string(beginStep + static_cast<SUMOTime>(mIndex * desc.getAggregationSpan()));
446 0 : glTranslated(1.6 * (double)mIndex / (double)values.size() - 0.8, -0.9, 0);
447 0 : GLHelper::drawText(mouseTime, Position(0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(-40) : RGBColor::BLUE, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
448 : }
449 : }
450 :
451 : }
452 :
453 :
454 : long
455 0 : GUIParameterTracker::GUIParameterTrackerPanel::onConfigure(FXObject*,
456 : FXSelector, void*) {
457 0 : if (makeCurrent()) {
458 0 : myWidthInPixels = myParent->getWidth();
459 0 : myHeightInPixels = myParent->getHeight();
460 0 : if (myWidthInPixels != 0 && myHeightInPixels != 0) {
461 0 : glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
462 0 : glClearColor(1.0, 1.0, 1.0, 1);
463 0 : glDisable(GL_DEPTH_TEST);
464 0 : glDisable(GL_LIGHTING);
465 0 : glDisable(GL_LINE_SMOOTH);
466 0 : glEnable(GL_BLEND);
467 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
468 0 : glEnable(GL_ALPHA_TEST);
469 0 : glDisable(GL_COLOR_MATERIAL);
470 0 : glLineWidth(1);
471 0 : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
472 : }
473 0 : makeNonCurrent();
474 : }
475 0 : return 1;
476 : }
477 :
478 :
479 : long
480 0 : GUIParameterTracker::GUIParameterTrackerPanel::onPaint(FXObject*,
481 : FXSelector, void*) {
482 0 : if (!isEnabled()) {
483 : return 1;
484 : }
485 0 : if (makeCurrent()) {
486 0 : myWidthInPixels = getWidth();
487 0 : myHeightInPixels = getHeight();
488 0 : if (myWidthInPixels != 0 && myHeightInPixels != 0) {
489 0 : glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
490 0 : glClearColor(1.0, 1.0, 1.0, 1);
491 0 : glDisable(GL_DEPTH_TEST);
492 0 : glDisable(GL_LIGHTING);
493 0 : glDisable(GL_LINE_SMOOTH);
494 0 : glEnable(GL_BLEND);
495 0 : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
496 0 : glEnable(GL_ALPHA_TEST);
497 0 : glDisable(GL_COLOR_MATERIAL);
498 0 : glLineWidth(1);
499 0 : glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
500 : // draw
501 0 : glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
502 0 : drawValues();
503 0 : swapBuffers();
504 : }
505 0 : makeNonCurrent();
506 : }
507 : return 1;
508 : }
509 :
510 :
511 : long
512 0 : GUIParameterTracker::GUIParameterTrackerPanel::onMouseMove(FXObject*, FXSelector, void* ptr) {
513 : FXEvent* event = (FXEvent*) ptr;
514 0 : myMouseX = event->win_x;
515 0 : update();
516 0 : return 1;
517 : }
518 :
519 :
520 :
521 : /****************************************************************************/
|