Belle II Software development
DisplayUI Class Reference

Control TEve browser user interface. More...

#include <DisplayUI.h>

Inheritance diagram for DisplayUI:

Classes

struct  Parameter
 Wraps a module parameter that can be toggled from the UI. More...
 

Public Member Functions

 DisplayUI (bool automatic=false, bool advance=false)
 Constructor.
 
 ~DisplayUI ()
 Destructor.
 
void addParameter (const std::string &label, ModuleParam< bool > &param, int level)
 Generate UI elements so the given module parameter can be changed at run time.
 
void next ()
 Go to next event.
 
void prev ()
 Go to previous event.
 
void goToEvent (Long_t id)
 Go to event with index id.
 
void goToEvent (Long_t event, Long_t run, Long_t experiment)
 Go to the event specified, using the input file's index.
 
void goToEventWidget ()
 go to the event given by m_eventNumberWidget.
 
void autoAdvanceDelayChanged ()
 m_autoAdvanceDelay was changed, update m_timer if enabled.
 
void togglePlayPause ()
 Handle Play/Pause button clicks.
 
void showJumpToEventDialog ()
 Show a dialog to to enter exp, run, event numbers.
 
void clearEvent ()
 remove all event data in current event.
 
void startAutomaticRun ()
 switch to automatic mode, where visualisations are saved for each event, with no interactive control.
 
void automaticEvent ()
 The actual per-event functionality for automatic saving.
 
bool startDisplay ()
 Start interactive display for current event.
 
void setTitle (const std::string &fileName="")
 Set title of Eve window.
 
void allowFlaggingEvents (const std::string &description="")
 Show control for flagging events (to set module return value).
 
bool getReturnValue () const
 Return value for current event, only makes sense if allowFlaggingEvents(true) was called.
 
void hideObjects (const std::vector< std::string > &names)
 hide objects with the given names.
 
void toggleColorScheme ()
 Toggle between light and dark color scheme for viewers.
 
void toggleUndock ()
 dock/undock active viewer.
 
void handleParameterChange (int id)
 Called when one of the module parameters is changed via UI.
 
void savePicture (bool highres=false)
 Save the current view to a user-defined filename.
 
void saveHiResPicture ()
 alias for savePicture(true).
 
SplitGLViewgetViewPane ()
 return right-side pane with viewers.
 
void pollNewEvents ()
 Check if new events are available, and go to next event.
 
void closeAndExit ()
 Close window and exit immediately.
 
void showUserData (const DisplayData &displayData)
 Add user-defined data (histograms, etc.).
 
bool cumulativeIsOn () const
 If true, DisplayModule shouldn't clear previous data (i.e.
 
void toggleCumulative ()
 toggle cumulative mode.
 
void selectionHandler (TEveElement *eveObj)
 Handle special actions when objects are selected.
 
void handleEvent (Event_t *event)
 Handles keyboard shortcuts.
 

Private Member Functions

void makeGui ()
 Build the buttons for event navigation.
 
void updateUI ()
 Update UI after a new event was loaded, as well as m_currentEntry.
 

Private Attributes

long m_currentEntry {0}
 Current entry id.
 
bool m_guiInitialized {false}
 Was GUI already built?
 
bool m_reshowCurrentEvent {false}
 Show current event again after startDisplay() returns?
 
bool m_automatic {false}
 If true, disable interactive control and call automaticEvent() instead.
 
bool m_advance {false}
 If true, start advancing through the events on startup.
 
bool m_cumulative {false}
 If true, DisplayModule shouldn't clear previous data (i.e.
 
std::vector< Parameterm_paramList
 List of run time configurable module parameters.
 
TGButton * m_prevButton {nullptr}
 Button to switch to previous event.
 
TGButton * m_nextButton {nullptr}
 Button to switch to next event.
 
TGNumberEntry * m_eventNumberWidget {nullptr}
 Event switcher with numeric entry.
 
TGNumberEntry * m_autoAdvanceDelay {nullptr}
 Delay for automatic advance, in seconds.
 
TGPictureButton * m_playPauseButton {nullptr}
 Play / Pause button.
 
TGCheckButton * m_flagEvent {nullptr}
 Show control for flagging events (to set module return value).
 
TGLabel * m_eventLabel {nullptr}
 show event/run/exp number for current event.
 
TGTextEntry * m_autoFileNamePrefix {nullptr}
 File name prefix (prefix + event number + "_" + projection + ".png").
 
TGNumberEntry * m_autoPictureWidth {nullptr}
 width of saved PNGs.
 
TEveElementList * m_eventData {nullptr}
 List of event data, including projections.
 
SplitGLViewm_viewPane {nullptr}
 pointer to right-side pane with viewers.
 
TTimer * m_timer {nullptr}
 Polling/auto-advance timer.
 
std::vector< std::string > m_hideObjects
 objects which are to be hidden (can be manually re-enabled in tree view).
 

Detailed Description

Control TEve browser user interface.

Mostly responsible for interactive elements like buttons etc.

See also
DisplayModule

Definition at line 41 of file DisplayUI.h.

Constructor & Destructor Documentation

◆ DisplayUI()

DisplayUI ( bool  automatic = false,
bool  advance = false 
)
explicit

Constructor.

Parameters
automaticif true, hide window and save events using automaticEvent()
advanceif true, start advancing through the events on startup.

Definition at line 58 of file DisplayUI.cc.

58 :
59 m_automatic(automatic), m_advance(advance)
60{
61 //ensure GUI thread goes away when parent dies. (root UI loves deadlocks)
62 prctl(PR_SET_PDEATHSIG, SIGHUP);
63
64 if (!gEve) {
65 B2INFO("Creating TEve window.");
66 TEveManager::Create(!m_automatic, "I"); //show window in interactive mode, hide file browser
67 }
68
69 setTitle(); //set default window title
70 TEveBrowser* browser = gEve->GetBrowser();
71 browser->HideBottomTab();
72 browser->StartEmbedding(TRootBrowser::kRight);
73 m_viewPane = new SplitGLView();
74 browser->StopEmbedding();
75
76 //Without this, our own menu bar entries are not drawn (might appear later)
77 browser->Resize(TGDimension(1200, 1000));
78
79 m_eventData = new TEveElementList();
80}
bool m_automatic
If true, disable interactive control and call automaticEvent() instead.
Definition: DisplayUI.h:186
void setTitle(const std::string &fileName="")
Set title of Eve window.
Definition: DisplayUI.cc:113
TEveElementList * m_eventData
List of event data, including projections.
Definition: DisplayUI.h:225
bool m_advance
If true, start advancing through the events on startup.
Definition: DisplayUI.h:189
SplitGLView * m_viewPane
pointer to right-side pane with viewers.
Definition: DisplayUI.h:228
Responsible for arranging the GL viewers and providing related functionality.
Definition: SplitGLView.h:30

◆ ~DisplayUI()

~DisplayUI ( )

Destructor.

Definition at line 82 of file DisplayUI.cc.

83{
84 delete m_timer;
85}
TTimer * m_timer
Polling/auto-advance timer.
Definition: DisplayUI.h:231

Member Function Documentation

◆ addParameter()

void addParameter ( const std::string &  label,
ModuleParam< bool > &  param,
int  level 
)

Generate UI elements so the given module parameter can be changed at run time.

Will result in a checkbox with given label indented by the amount in level (0 being leftmost). Clicking the checkbox will toggle the parameter and reload the event.

Definition at line 87 of file DisplayUI.cc.

88{
89 Parameter p;
90 p.m_label = label;
91 p.m_param = &param;
92 p.m_level = level;
93 m_paramList.push_back(p);
94}
std::vector< Parameter > m_paramList
List of run time configurable module parameters.
Definition: DisplayUI.h:195

◆ allowFlaggingEvents()

void allowFlaggingEvents ( const std::string &  description = "")

Show control for flagging events (to set module return value).

Needs to be called in initialize().

Definition at line 124 of file DisplayUI.cc.

125{
126 std::string label = "Flag this Event";
127 if (!description.empty())
128 label += " for " + description;
129
130 m_flagEvent = new TGCheckButton(nullptr, label.c_str());
131}
TGCheckButton * m_flagEvent
Show control for flagging events (to set module return value).
Definition: DisplayUI.h:213

◆ autoAdvanceDelayChanged()

void autoAdvanceDelayChanged ( )

m_autoAdvanceDelay was changed, update m_timer if enabled.

Definition at line 233 of file DisplayUI.cc.

234{
235 if (m_timer) {
236 m_timer->Stop();
237 m_timer->Start((int)(1000.0 * m_autoAdvanceDelay->GetNumber()));
238 }
239}
TGNumberEntry * m_autoAdvanceDelay
Delay for automatic advance, in seconds.
Definition: DisplayUI.h:207

◆ automaticEvent()

void automaticEvent ( )

The actual per-event functionality for automatic saving.

Definition at line 763 of file DisplayUI.cc.

764{
765 static int i = 0;
766 B2INFO("Saving event " << i);
767
768 //force immediate redraw
769 gEve->FullRedraw3D();
770
771 TEveViewerList* viewers = gEve->GetViewers();
772 TEveElement::List_ci end_it = viewers->EndChildren();
773 for (TEveElement::List_i it = viewers->BeginChildren(); it != end_it; ++it) {
774 TEveViewer* v = static_cast<TEveViewer*>(*it);
775 TGLViewer* glv = v->GetGLViewer();
776
777 TString projectionName(v->GetName());
778 projectionName.ReplaceAll(" viewer", "");
779 projectionName.ReplaceAll("/", "");
780 const int width = m_autoPictureWidth->GetIntNumber();
781 const bool scalePixelObjects = false;
782 TString name = TString::Format("%s_%s_%d.png", m_autoFileNamePrefix->GetText(), projectionName.Data(), i);
783 glv->SavePictureWidth(name, width, scalePixelObjects);
784 }
785
786 i++;
787}
TGNumberEntry * m_autoPictureWidth
width of saved PNGs.
Definition: DisplayUI.h:222
TGTextEntry * m_autoFileNamePrefix
File name prefix (prefix + event number + "_" + projection + ".png").
Definition: DisplayUI.h:219

◆ clearEvent()

void clearEvent ( )

remove all event data in current event.

Definition at line 282 of file DisplayUI.cc.

283{
284 if (!gEve)
285 return;
286 if (m_cumulative) {
287 gEve->AddEvent(new TEveEventManager());
288 } else {
289 if (gEve->GetCurrentEvent())
290 gEve->GetCurrentEvent()->DestroyElements();
291
292 //make sure we delete projected events with the rest of the event scene
293 m_eventData->DestroyElements();
294 }
295}
bool m_cumulative
If true, DisplayModule shouldn't clear previous data (i.e.
Definition: DisplayUI.h:192

◆ closeAndExit()

void closeAndExit ( )

Close window and exit immediately.

Definition at line 803 of file DisplayUI.cc.

804{
805 //stop event processing after current event
806 StoreObjPtr<EventMetaData> eventMetaData;
807 eventMetaData->setEndOfData();
808
809 gSystem->ExitLoop();
810 gROOT->SetInterrupt();
811 m_cumulative = false;
812
813 if (!gEve)
814 return;
815
816 // avoid emittting signals at end
817 gEve->GetBrowser()->Disconnect();
818
819 gEve->GetSelection()->Disconnect();
820 gEve->GetHighlight()->Disconnect();
821
822 gEve->GetBrowser()->UnmapWindow();
823 gEve->GetBrowser()->SendCloseMessage();
824
825 // This is a bit ugly to do, but it allows us to terminate the process faster and without segfaults
826 // TODO: it's possible to handle this better
827 B2INFO("The display and the basf2 process will now be gracefully terminated.");
828 exit(0);
829}
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96

◆ cumulativeIsOn()

bool cumulativeIsOn ( ) const
inline

If true, DisplayModule shouldn't clear previous data (i.e.

we want to show multiple events)

Definition at line 148 of file DisplayUI.h.

148{ return m_cumulative; }

◆ getReturnValue()

bool getReturnValue ( ) const

Return value for current event, only makes sense if allowFlaggingEvents(true) was called.

Return value for current event, only makes sense if allowFlaggingEvents() was called.

Definition at line 134 of file DisplayUI.cc.

135{
136 return m_flagEvent && (m_flagEvent->GetState() == kButtonDown);
137}

◆ getViewPane()

SplitGLView * getViewPane ( )
inline

return right-side pane with viewers.

Definition at line 133 of file DisplayUI.h.

133{ return m_viewPane; }

◆ goToEvent() [1/2]

void goToEvent ( Long_t  event,
Long_t  run,
Long_t  experiment 
)

Go to the event specified, using the input file's index.

Definition at line 216 of file DisplayUI.cc.

217{
218 const long numEntries = InputController::numEntries();
219 if (numEntries > 0 && InputController::canControlInput()) {
220 B2DEBUG(100, "Switching to event " << event << " in run " << run << ", experiment " << experiment);
221 gVirtualX->SetCursor(gEve->GetBrowser()->GetId(), gVirtualX->CreateCursor(kWatch));
222 InputController::setNextEntry(experiment, run, event);
223 }
224 B2DEBUG(100, "exiting event loop now.");
225 gSystem->ExitLoop();
226}
static void setNextEntry(long entry, bool independentPath=false)
Set the file entry to be loaded the next time event() is called.
static long numEntries(bool independentPath=false)
Returns total number of entries in the event tree.
static bool canControlInput()
Is there an input module to be controlled.

◆ goToEvent() [2/2]

void goToEvent ( Long_t  id)

Go to event with index id.

Definition at line 182 of file DisplayUI.cc.

183{
184 if (id < 0)
185 id = 0;
186 const long numEntries = InputController::numEntries();
187 if (numEntries > 0 and id >= numEntries)
188 id = numEntries - 1;
189
190 if (m_currentEntry == id) return;
191
193 B2ERROR("Cannot switch to event " << id << ", only works in conjunction with RootInput.");
194 }
195
196 if (numEntries > 0 && InputController::canControlInput()) {
197 B2DEBUG(100, "Switching to event " << id);
199 } else {
201 }
202 gVirtualX->SetCursor(gEve->GetBrowser()->GetId(), gVirtualX->CreateCursor(kWatch));
203 m_nextButton->SetEnabled(false);
204 m_prevButton->SetEnabled(false);
205
206 if (m_timer)
207 m_timer->Stop(); //apparently timer only deactivates after processing event, so do it manually
208 //process remaining events to ensure redraw (only needed if called from Timeout())
209 gSystem->ProcessEvents();
210
211 B2DEBUG(100, "exiting event loop now.");
212 //exit event loop to allow basf2 to go to next event
213 gSystem->ExitLoop();
214}
long m_currentEntry
Current entry id.
Definition: DisplayUI.h:177
TGButton * m_prevButton
Button to switch to previous event.
Definition: DisplayUI.h:198
TGButton * m_nextButton
Button to switch to next event.
Definition: DisplayUI.h:201

◆ goToEventWidget()

void goToEventWidget ( )

go to the event given by m_eventNumberWidget.

Definition at line 228 of file DisplayUI.cc.

229{
230 goToEvent(m_eventNumberWidget->GetIntNumber());
231}
void goToEvent(Long_t id)
Go to event with index id.
Definition: DisplayUI.cc:182
TGNumberEntry * m_eventNumberWidget
Event switcher with numeric entry.
Definition: DisplayUI.h:204

◆ handleEvent()

void handleEvent ( Event_t *  event)

Handles keyboard shortcuts.

Definition at line 312 of file DisplayUI.cc.

313{
314 if (event->fType == kGKeyPress) {
315 //B2DEBUG(100, "event type " << event->fType << ", code: " << event->fCode << ", state: " << event->fState);
316 switch (event->fCode) {
317 case 117: //Page Down
318 next();
319 break;
320 case 112: //Page Up
321 prev();
322 break;
323 case 65: //Space bar
325 break;
326 case 47: // s
328 break;
329 case 53: //Ctrl + q
330 if (event->fState & kKeyControlMask)
331 closeAndExit();
332 break;
333 }
334 }
335}
void next()
Go to next event.
Definition: DisplayUI.cc:96
void togglePlayPause()
Handle Play/Pause button clicks.
Definition: DisplayUI.cc:241
void closeAndExit()
Close window and exit immediately.
Definition: DisplayUI.cc:803
void prev()
Go to previous event.
Definition: DisplayUI.cc:104
void saveHiResPicture()
alias for savePicture(true).
Definition: DisplayUI.h:130

◆ handleParameterChange()

void handleParameterChange ( int  id)

Called when one of the module parameters is changed via UI.

Definition at line 641 of file DisplayUI.cc.

642{
643 if (id >= (int)m_paramList.size()) {
644 B2ERROR("widget ID too large!");
645 return;
646 }
647 //toggle value
648 m_paramList[id].m_param->setValue(!m_paramList[id].m_param->getValue());
649
650 //reprocess current event
652 gSystem->ExitLoop();
653}
bool m_reshowCurrentEvent
Show current event again after startDisplay() returns?
Definition: DisplayUI.h:183

◆ hideObjects()

void hideObjects ( const std::vector< std::string > &  names)
inline

hide objects with the given names.

Definition at line 112 of file DisplayUI.h.

112{ m_hideObjects = names; }
std::vector< std::string > m_hideObjects
objects which are to be hidden (can be manually re-enabled in tree view).
Definition: DisplayUI.h:234

◆ makeGui()

void makeGui ( )
private

Build the buttons for event navigation.

Definition at line 406 of file DisplayUI.cc.

407{
408 m_guiInitialized = true;
409 TEveBrowser* browser = gEve->GetBrowser();
410 const int margin = 3;
411
412 browser->Connect("CloseWindow()", "Belle2::DisplayUI", this, "closeAndExit()");
413
414 //add handler for keyboard events, needs to be done for browser TGFrame as well as frames of all TGLViewers
415 browser->Connect("ProcessedEvent(Event_t*)", "Belle2::DisplayUI", this, "handleEvent(Event_t*)");
416 TEveViewerList* viewers = gEve->GetViewers();
417 TEveElement::List_ci end_it = viewers->EndChildren();
418 for (TEveElement::List_i it = viewers->BeginChildren(); it != end_it; ++it) {
419 TEveViewer* v = static_cast<TEveViewer*>(*it);
420 TGLViewer* glv = v->GetGLViewer();
421 glv->GetGLWidget()->Connect("ProcessedEvent(Event_t*)", "Belle2::DisplayUI", this, "handleEvent(Event_t*)");
422 }
423
424 //----------Event Control
425 browser->StartEmbedding(TRootBrowser::kLeft);
426
427 TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 240, 600);
428 frmMain->SetWindowName("Event control main frame");
429 frmMain->SetCleanup(kDeepCleanup);
430
431 const TString icondir(Form("%s/icons/", gSystem->Getenv("ROOTSYS")));
432
433 TGGroupFrame* event_frame = new TGGroupFrame(frmMain);
434 event_frame->SetTitle("Event");
435 {
436 TGHorizontalFrame* hf = new TGHorizontalFrame(event_frame);
437 {
438 m_prevButton = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoBack.gif"));
439 m_prevButton->SetToolTipText("Go to previous event (Page Up)");
440 hf->AddFrame(m_prevButton, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
441 m_prevButton->Connect("Clicked()", "Belle2::DisplayUI", this, "prev()");
442
443 const long numEntries = InputController::numEntries();
444 m_eventNumberWidget = new TGNumberEntry(hf, 0, 4, 999, TGNumberFormat::kNESInteger,
445 TGNumberFormat::kNEANonNegative,
446 TGNumberFormat::kNELLimitMinMax,
447 0, numEntries - 1);
449 hf->AddFrame(m_eventNumberWidget, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
450 //note: parameter of ValueSet signal is _not_ the number just set.
451 m_eventNumberWidget->Connect("ValueSet(Long_t)", "Belle2::DisplayUI", this, "goToEventWidget()");
452 m_eventNumberWidget->GetNumberEntry()->Connect("ReturnPressed()", "Belle2::DisplayUI", this, "goToEventWidget()");
453
454
455 if (numEntries > 0) {
456 TGLabel* maxEvents = new TGLabel(hf, TString::Format("/%ld", numEntries - 1));
457 hf->AddFrame(maxEvents, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
458 }
459
460 m_nextButton = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoForward.gif"));
461 m_nextButton->SetToolTipText("Go to next event (Page Down)");
462 hf->AddFrame(m_nextButton, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
463 m_nextButton->Connect("Clicked()", "Belle2::DisplayUI", this, "next()");
464 }
465 event_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
466
467 hf = new TGHorizontalFrame(event_frame);
468 {
469 //const bool file = InputController::canControlInput();
470 const bool async = AsyncWrapper::isAsync();
471
472 TGLabel* delayLabel = new TGLabel(hf, "Delay (s):");
473 hf->AddFrame(delayLabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
474
475 const double valueSeconds = async ? 0.5 : 3.5;
476 m_autoAdvanceDelay = new TGNumberEntry(hf, valueSeconds, 3, 999, TGNumberFormat::kNESRealOne,
477 TGNumberFormat::kNEAPositive,
478 TGNumberFormat::kNELLimitMin,
479 0.1); //minimum
480 //m_autoAdvanceDelay->SetState(file or async);
481 hf->AddFrame(m_autoAdvanceDelay, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
482 //note: parameter of ValueSet signal is _not_ the number just set.
483 m_autoAdvanceDelay->Connect("ValueSet(Long_t)", "Belle2::DisplayUI", this, "autoAdvanceDelayChanged()");
484 m_autoAdvanceDelay->GetNumberEntry()->Connect("ReturnPressed()", "Belle2::DisplayUI", this, "autoAdvanceDelayChanged()");
485
486 m_playPauseButton = new TGPictureButton(hf, gClient->GetPicture(icondir + "ed_execute.png"));
487 //m_playPauseButton->SetEnabled(file or async);
488 m_playPauseButton->SetToolTipText("Advance automatically to next event after the given delay.");
489 hf->AddFrame(m_playPauseButton, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
490 m_playPauseButton->Connect("Clicked()", "Belle2::DisplayUI", this, "togglePlayPause()");
491 }
492 event_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
493
494 TGButton* jumpToEventButton = new TGTextButton(event_frame, "Jump to event/run/exp...");
495 jumpToEventButton->SetEnabled(InputController::canControlInput());
496 jumpToEventButton->SetToolTipText("Find a given entry identified by an event / run / experiment triplet in the current file");
497 event_frame->AddFrame(jumpToEventButton, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
498 jumpToEventButton->Connect("Clicked()", "Belle2::DisplayUI", this, "showJumpToEventDialog()");
499
500 m_eventLabel = new TGLabel(event_frame);
501 event_frame->AddFrame(m_eventLabel, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
502
503 if (m_flagEvent) {
504 TString descr = m_flagEvent->GetString();
505 delete m_flagEvent;
506 m_flagEvent = new TGCheckButton(event_frame, descr);
507 m_flagEvent->SetToolTipText("Set return value to true for this event");
508 m_flagEvent->SetState(kButtonUp);
509 event_frame->AddFrame(m_flagEvent, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
510 }
511 }
512 frmMain->AddFrame(event_frame, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
513
514 TGGroupFrame* param_frame = new TGGroupFrame(frmMain);
515 param_frame->SetTitle("Options");
516 {
517 const int nParams = m_paramList.size();
518 for (int i = 0; i < nParams; i++) {
519 TGCheckButton* b = new TGCheckButton(param_frame, m_paramList[i].m_label.c_str(), i);
520 b->SetToolTipText(m_paramList[i].m_param->getDescription().c_str());
521 b->SetState(m_paramList[i].m_param->getValue() ? kButtonDown : kButtonUp);
522 b->Connect("Clicked()", "Belle2::DisplayUI", this, TString::Format("handleParameterChange(=%d)", i));
523 int indentation = 15 * m_paramList[i].m_level;
524 param_frame->AddFrame(b, new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, indentation, margin, margin, margin));
525 }
526
527 }
528 frmMain->AddFrame(param_frame, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
529
530 TGGroupFrame* viewer_frame = new TGGroupFrame(frmMain);
531 viewer_frame->SetTitle("Current Viewer");
532 {
533 TGHorizontalFrame* hf = new TGHorizontalFrame(viewer_frame);
534 TGButton* b = 0;
535 {
536 b = new TGTextButton(hf, "Save As...");
537 b->SetToolTipText("Save a bitmap graphic for the current viewer");
538 hf->AddFrame(b, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin + 1, margin, margin, margin));
539 b->Connect("Clicked()", "Belle2::DisplayUI", this, "savePicture()");
540
541 b = new TGTextButton(hf, "Save As (High-Res)... ");
542 b->SetToolTipText("Save a bitmap graphic for the current viewer with user-specified size");
543 hf->AddFrame(b, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
544 b->Connect("Clicked()", "Belle2::DisplayUI", this, "saveHiResPicture()");
545
546 }
547 viewer_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
548
549 hf = new TGHorizontalFrame(viewer_frame);
550 {
551 b = new TGTextButton(hf, "Dock/Undock Viewer");
552 b->SetToolTipText("Move current viewer into it's own window, or back to its original position");
553 hf->AddFrame(b, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
554 b->Connect("Clicked()", "Belle2::DisplayUI", this, "toggleUndock()");
555 }
556 viewer_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
557 }
558 frmMain->AddFrame(viewer_frame, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
559
560
561 TGGroupFrame* visOptionsFrame = new TGGroupFrame(frmMain);
562 visOptionsFrame->SetTitle("Visualisation Options");
563 {
564 TGHorizontalFrame* hf = new TGHorizontalFrame(visOptionsFrame);
565 {
566 TGButton* b = new TGTextButton(hf, "Dark/light colors");
567 b->SetToolTipText("Toggle background color");
568 hf->AddFrame(b, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
569 b->Connect("Clicked()", "Belle2::DisplayUI", this, "toggleColorScheme()");
570 }
571 visOptionsFrame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
572
573 {
574 TGCheckButton* c = new TGCheckButton(visOptionsFrame, "Cumulative mode (experimental)");
575 c->SetToolTipText("Do not erase previous event, i.e. show data from multiple events. This is quite unstable and will crash sooner or later.");
576 c->SetState(m_cumulative ? kButtonDown : kButtonUp);
577 c->Connect("Clicked()", "Belle2::DisplayUI", this, "toggleCumulative()");
578 visOptionsFrame->AddFrame(c, new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 0, margin, margin, margin));
579 }
580 }
581 frmMain->AddFrame(visOptionsFrame, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
582
583 TGGroupFrame* automatisation_frame = new TGGroupFrame(frmMain);
584 automatisation_frame->SetTitle("Automatic Saving (experimental)");
585 {
586 TGHorizontalFrame* hf = new TGHorizontalFrame(automatisation_frame);
587 {
588 TGLabel* prefixLabel = new TGLabel(hf, "Prefix:");
589 hf->AddFrame(prefixLabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
590
591 m_autoFileNamePrefix = new TGTextEntry(hf, "display_");
592 hf->AddFrame(m_autoFileNamePrefix, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
593 }
594 automatisation_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
595
596 hf = new TGHorizontalFrame(automatisation_frame);
597 {
598 TGLabel* widthLabel = new TGLabel(hf, "Width (px):");
599 hf->AddFrame(widthLabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
600
601 m_autoPictureWidth = new TGNumberEntry(hf, 800, 5, 998, TGNumberFormat::kNESInteger,
602 TGNumberFormat::kNEANonNegative,
603 TGNumberFormat::kNELLimitMinMax,
604 100, 6000);
605 hf->AddFrame(m_autoPictureWidth, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
606
607 TGButton* b = new TGTextButton(hf, "Save PNGs");
608 b->SetToolTipText("Save bitmap graphics for all further events. Cannot be aborted. (EXPERIMENTAL)");
609 hf->AddFrame(b, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, margin, margin, margin, margin));
610 b->Connect("Clicked()", "Belle2::DisplayUI", this, "startAutomaticRun()");
611 }
612 automatisation_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
613
614 }
615 frmMain->AddFrame(automatisation_frame, new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 0));
616
617 //this will be shown at the very bottom
618 TGGroupFrame* exit_frame = new TGGroupFrame(frmMain);
619 exit_frame->SetTitle("Closing");
620 {
621 TGHorizontalFrame* hf = new TGHorizontalFrame(exit_frame);
622 {
623 TGButton* b = new TGTextButton(hf, " Exit ");
624 b->SetToolTipText("Close the display and stop basf2 after this event.");
625 hf->AddFrame(b, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, margin, margin, margin, margin));
626 b->Connect("Clicked()", "Belle2::DisplayUI", this, "closeAndExit()");
627
628 }
629 exit_frame->AddFrame(hf, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 0, 0, 0, 0));
630
631 }
632 frmMain->AddFrame(exit_frame, new TGLayoutHints(kLHintsExpandX | kLHintsBottom, 0, 0, 0, 0));
633
634 //magic to prevent the frame being empty.
635 frmMain->MapSubwindows();
636 frmMain->Resize();
637 frmMain->MapWindow();
638 browser->StopEmbedding("Event Control");
639}
static bool isAsync()
returns true if the current process is on the receiving (async) side of an AsyncWrapper.
Definition: AsyncWrapper.h:57
TGLabel * m_eventLabel
show event/run/exp number for current event.
Definition: DisplayUI.h:216
TGPictureButton * m_playPauseButton
Play / Pause button.
Definition: DisplayUI.h:210
bool m_guiInitialized
Was GUI already built?
Definition: DisplayUI.h:180

◆ next()

void next ( )

Go to next event.

Definition at line 96 of file DisplayUI.cc.

97{
98 // periodically called by auto-advance timer, but we don't want to freeze UI if no events are there
99 if (!m_nextButton->IsEnabled())
100 return;
102}

◆ pollNewEvents()

void pollNewEvents ( )

Check if new events are available, and go to next event.

Only useful for AsyncDisplay.

Definition at line 789 of file DisplayUI.cc.

790{
792 return;
793 if (!gEve)
794 return;
795
796 int numEvents = AsyncWrapper::numAvailableEvents();
797 bool state = m_nextButton->IsEnabled();
798 //only call SetEnabled() if state changes (interrupts UI interactions otherwise)
799 if (state != (numEvents > 0))
800 m_nextButton->SetEnabled(numEvents > 0);
801}
static int numAvailableEvents()
Retun number of events available in the RingBuffer.
Definition: AsyncWrapper.cc:41

◆ prev()

void prev ( )

Go to previous event.

Definition at line 104 of file DisplayUI.cc.

105{
106 if (!m_prevButton->IsEnabled())
107 return;
109 return;
111}

◆ saveHiResPicture()

void saveHiResPicture ( )
inline

alias for savePicture(true).

Definition at line 130 of file DisplayUI.h.

130{ savePicture(true); }
void savePicture(bool highres=false)
Save the current view to a user-defined filename.
Definition: DisplayUI.cc:703

◆ savePicture()

void savePicture ( bool  highres = false)

Save the current view to a user-defined filename.

Parameters
highressave picture with 4000px width instead of screen size

Definition at line 703 of file DisplayUI.cc.

704{
705 const char* filetypes[] = {
706 "PNG (bitmap)", "*.png",
707 "PDF (experimental!)", "*.pdf",
708 "All files", "*",
709 0, 0
710 };
711 TGFileInfo fi;
712 fi.fFileTypes = filetypes;
713
714 //deleting the pointer crashes, so I'm assuming this is magically cleaned up at some point
715 new TGFileDialog(gEve->GetBrowser()->GetClient()->GetDefaultRoot(), gEve->GetBrowser(), kFDSave, &fi);
716 if (!fi.fFilename)
717 return; //cancelled
718 TGLViewer* v = getViewPane()->getActiveGLViewer();
719 bool success = false;
720 if (!highres) {
721 success = v->SavePicture(fi.fFilename);
722 } else {
723 char returnString[256];
724 new TGInputDialog(gEve->GetBrowser()->GetClient()->GetDefaultRoot(), gEve->GetBrowser(),
725 "Bitmap width (pixels) [Note: Values larger than ~5000 may cause crashes.]",
726 "4000", //default
727 returnString);
728 if (returnString[0] == '\0')
729 return; //cancelled
730 const TString t(returnString);
731 if (!t.IsDigit()) {
732 B2ERROR("Given width is not a number!");
733 return;
734 }
735 const int width = t.Atoi();
736 B2INFO("Saving bitmap (width: " << width << "px)..."); //may take a while
737 success = v->SavePictureWidth(fi.fFilename, width, false); // don't scale pixel objects
738 }
739
740 if (success) {
741 B2INFO("Saved image in: " << fi.fFilename);
742 } else {
743 new TGMsgBox(gEve->GetBrowser()->GetClient()->GetDefaultRoot(), gEve->GetBrowser(), "Saving image failed",
744 TString::Format("Couldn't save to '%s'! Please verify you used an appropriate image file extension in the file name. Check console output for further information.",
745 fi.fFilename));
746 }
747
748 //file dialog leaves empty box, redraw
749 gEve->FullRedraw3D(false); //do not reset camera when redrawing
750}
SplitGLView * getViewPane()
return right-side pane with viewers.
Definition: DisplayUI.h:133
TGLEmbeddedViewer * getActiveGLViewer()
return TGLEmbeddedViewer that is active right now.
Definition: SplitGLView.cc:297

◆ selectionHandler()

void selectionHandler ( TEveElement *  eveObj)

Handle special actions when objects are selected.

Definition at line 297 of file DisplayUI.cc.

298{
299 if (VisualRepMap::getInstance()->isCurrentlySelecting())
300 return;
301
302 //B2INFO("in selection handler: " << eveObj->GetElementName());
303
304 const TObject* representedObject = VisualRepMap::getInstance()->getDataStoreObject(eveObj);
305 if (representedObject)
306 m_viewPane->getInfoWidget()->show(representedObject);
307
310}
void show(const char *uri="main:", bool clearSelection=true)
Navigate to given URI.
Definition: InfoWidget.cc:93
InfoWidget * getInfoWidget() const
text-based info viewer.
Definition: SplitGLView.h:64
const TObject * getDataStoreObject(TEveElement *elem) const
Get object represented by given visual representation.
Definition: VisualRepMap.cc:56
static VisualRepMap * getInstance()
get instance pointer.
Definition: VisualRepMap.cc:36
void selectRelated(TEveElement *eveObj) const
Select related objects.
void selectOnly(const TEveElement *eveObj) const
Deselect all other objects.

◆ setTitle()

void setTitle ( const std::string &  fileName = "")

Set title of Eve window.

Add fileName, if given.

Definition at line 113 of file DisplayUI.cc.

114{
115 assert(gEve);
116 std::string title("Belle II Event Display");
117 if (!fileName.empty())
118 title += " - " + fileName;
119
120 TEveBrowser* browser = gEve->GetBrowser();
121 browser->SetWindowName(title.c_str());
122}

◆ showJumpToEventDialog()

void showJumpToEventDialog ( )

Show a dialog to to enter exp, run, event numbers.

Definition at line 259 of file DisplayUI.cc.

260{
261 StoreObjPtr<EventMetaData> eventMetaData;
262 if (!eventMetaData)
263 return; //this should not actually happen.
264
265 char returnString[256]; //magic length specified by TGInputDialog. Note that it still overwrites the stack if you paste something long enough.
266 new TGInputDialog(gEve->GetBrowser()->GetClient()->GetDefaultRoot(), gEve->GetBrowser(),
267 "Jump to event '#evt/#run/#exp':",
268 TString::Format("%u/%d/%d", eventMetaData->getEvent(), eventMetaData->getRun(), eventMetaData->getExperiment()),
269 returnString);
270 if (returnString[0] == '\0')
271 return; //cancelled
272
273 unsigned int event, run, exp;
274 returnString[255] = '\0'; //I don't trust root to terminate the string correctly
275 if (sscanf(returnString, "%u/%u/%u", &event, &run, &exp) != 3) {
276 B2WARNING("Wrong format!");
277 return;
278 }
279 goToEvent(event, run, exp);
280}

◆ showUserData()

void showUserData ( const DisplayData displayData)

Add user-defined data (histograms, etc.).

Definition at line 831 of file DisplayUI.cc.

832{
833 static std::map<std::string, BrowsableWrapper*> wrapperMap;
834 for (auto& entry : wrapperMap) {
835 entry.second = NULL;
836 }
837
838 if (!displayData.m_histograms.empty()) {
839 static TGFileBrowser* fileBrowser = NULL;
840 if (!fileBrowser) {
841 gEve->GetBrowser()->StartEmbedding(0);
842 fileBrowser = gEve->GetBrowser()->MakeFileBrowser();
843 gEve->GetBrowser()->StopEmbedding("Histograms");
844
845 //create new tab with canvas
846 gEve->GetBrowser()->StartEmbedding(TRootBrowser::kRight);
847 TEveWindowSlot* slot = TEveWindow::CreateWindowMainFrame();
848 gEve->GetBrowser()->StopEmbedding();
849 slot->StartEmbedding();
850 new TCanvas;
851 slot->StopEmbedding("Canvas");
852 }
853
854 //invert pad -> name map
855 const std::map<TVirtualPad*, std::string>& padMap = BrowsableWrapper::getPads();
856 std::map<std::string, TVirtualPad*> nameMap;
857 for (const auto& entry : padMap) {
858 nameMap[entry.second] = entry.first;
859 }
860
861 for (unsigned int i = 0; i < displayData.m_histograms.size(); i++) {
862 std::string name(displayData.m_histograms.at(i)->GetName());
863 if (!wrapperMap[name])
864 wrapperMap[name] = new BrowsableWrapper(displayData.m_histograms.at(i));
865 else
866 wrapperMap[name]->setWrapped(displayData.m_histograms.at(i));
867 BrowsableWrapper* wrapper = wrapperMap[name];
868
869 if (nameMap.find(name) != nameMap.end()) {
870 TVirtualPad* oldGpad = gPad;
871 //redraw
872 nameMap[name]->cd();
873 wrapper->Browse(fileBrowser->Browser());
874
875 //restore state
876 oldGpad->cd();
877 }
878 fileBrowser->Add(wrapper);
879
880 }
881 }
882
883 for (const auto& pair : displayData.m_selectedObjects) {
884 //convert the name, index pair back into pointer
885 StoreArray<TObject> array(pair.first);
886 const TObject* obj = array[pair.second];
887 if (obj) {
888 VisualRepMap::getInstance()->select(array[pair.second]);
889 } else {
890 B2WARNING("Cannot select object " << pair.first << "[" << pair.second << "], not found. Is the array available?");
891 }
892 }
893}
A wrapper for browsable objects to enable automatic redrawing.
static const std::map< TVirtualPad *, std::string > & getPads()
Get list of pads (static).
std::vector< TH1 * > m_histograms
Histograms to be shown in Eve.
Definition: DisplayData.h:111
std::vector< std::pair< std::string, unsigned int > > m_selectedObjects
List of selected objects (array name, index).
Definition: DisplayData.h:113
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
void select(const TObject *object) const
Select the representation of the given object.
Definition: VisualRepMap.cc:87

◆ startAutomaticRun()

void startAutomaticRun ( )

switch to automatic mode, where visualisations are saved for each event, with no interactive control.

Definition at line 752 of file DisplayUI.cc.

753{
754 B2INFO("Starting automatic run.");
755 m_automatic = true;
756
757 //save current event, too
759
760 gSystem->ExitLoop();
761}
void automaticEvent()
The actual per-event functionality for automatic saving.
Definition: DisplayUI.cc:763

◆ startDisplay()

bool startDisplay ( )

Start interactive display for current event.

Returns only after user presses prev/next, or closes the window.

Returns
wether to reprocess the current event, e.g. when visualisation options changed

Definition at line 337 of file DisplayUI.cc.

338{
339 if (!m_guiInitialized) {
340 makeGui();
341 if (AsyncWrapper::isAsync()) {
342 //continually check for new events and enable/disable '->' button accordingly
343 TTimer* t = new TTimer();
344 const int pollIntervalMs = 300;
345 t->Connect("Timeout()", "Belle2::DisplayUI", this, "pollNewEvents()");
346 t->Start(pollIntervalMs);
347 }
348
349 if (m_advance) {
351 }
352
353 //import the geometry in the projection managers (only needs to be done once)
354 TEveScene* gs = gEve->GetGlobalScene();
355 TEveProjectionManager* rphiManager = getViewPane()->getRPhiMgr();
356 if (rphiManager) {
357 rphiManager->ImportElements(gs);
358 }
359 TEveProjectionManager* rhozManager = getViewPane()->getRhoZMgr();
360 if (rhozManager) {
361 rhozManager->ImportElements(gs);
362 }
363
364 //We want to do special things when objects are selected
365 gEve->GetSelection()->Connect("SelectionAdded(TEveElement*)", "Belle2::DisplayUI", this, "selectionHandler(TEveElement*)");
366 gEve->GetSelection()->Connect("SelectionRepeated(TEveElement*)", "Belle2::DisplayUI", this, "selectionHandler(TEveElement*)");
367 }
368
369 updateUI(); //update button state
370
372
373 m_eventData->AddElement(getViewPane()->getRPhiMgr()->ImportElements(gEve->GetEventScene()));
374 m_eventData->AddElement(getViewPane()->getRhoZMgr()->ImportElements(gEve->GetEventScene()));
375
376 for (std::string name : m_hideObjects) {
377 TGListTreeItem* eventItem = gEve->GetListTree()->FindItemByPathname("Event");
378 TGListTreeItem* item = gEve->GetListTree()->FindChildByName(eventItem, name.c_str());
379 if (item) {
380 B2INFO("hiding object '" << name << "'.");
381 TEveElement* eveItem = static_cast<TEveElement*>(item->GetUserData());
382 eveItem->SetRnrSelfChildren(false, false);
383 } else {
384 B2ERROR("hideObjects: '" << name << "' not found.");
385 }
386 }
387
388 m_reshowCurrentEvent = false;
389 if (!m_automatic) {
390 gEve->Redraw3D(false); //do not reset camera when redrawing
391
392 //restart auto-advance timer after loading event (interval already set)
393 if (m_timer)
394 m_timer->Start(-1);
395
396 //make display interactive
397 gApplication->Run(true); //return from Run()
398 //interactive part done, event data removed from scene
399 } else {
401 }
402
404}
void makeGui()
Build the buttons for event navigation.
Definition: DisplayUI.cc:406
void updateUI()
Update UI after a new event was loaded, as well as m_currentEntry.
Definition: DisplayUI.cc:139
void update()
reset for new event (try to show same object if it exists).
Definition: InfoWidget.cc:55
TEveProjectionManager * getRhoZMgr() const
return Rho-Z projection manager.
Definition: SplitGLView.h:60
TEveProjectionManager * getRPhiMgr() const
return R-Phi projection manager.
Definition: SplitGLView.h:58

◆ toggleColorScheme()

void toggleColorScheme ( )

Toggle between light and dark color scheme for viewers.

Definition at line 655 of file DisplayUI.cc.

656{
657 TEveViewerList* viewers = gEve->GetViewers();
658 TEveElement::List_ci end_it = viewers->EndChildren();
659 for (TEveElement::List_i it = viewers->BeginChildren(); it != end_it; ++it) {
660 TEveViewer* v = static_cast<TEveViewer*>(*it);
661 TGLViewer* glv = v->GetGLViewer();
662
663 bool dark = glv->ColorSet().Background().GetColorIndex() != kWhite;
664 glv->RefLightColorSet().Background().SetColor(kWhite);
665 glv->RefDarkColorSet().Background().SetColor(kBlack);
666 if (dark)
667 glv->UseLightColorSet();
668 else
669 glv->UseDarkColorSet();
670 glv->DoDraw();
671 }
672}

◆ toggleCumulative()

void toggleCumulative ( )
inline

toggle cumulative mode.

Definition at line 151 of file DisplayUI.h.

◆ togglePlayPause()

void togglePlayPause ( )

Handle Play/Pause button clicks.

Definition at line 241 of file DisplayUI.cc.

242{
243 const TString icondir(Form("%s/icons/", gSystem->Getenv("ROOTSYS")));
244 if (m_timer) {
245 //pause
246 delete m_timer;
247 m_timer = nullptr;
248 m_playPauseButton->SetPicture(gClient->GetPicture(icondir + "ed_execute.png"));
249 } else {
250 //play
251 m_timer = new TTimer();
252 const int pollIntervalMs = (int)(1000.0 * m_autoAdvanceDelay->GetNumber());
253 m_timer->Connect("Timeout()", "Belle2::DisplayUI", this, "next()");
254 m_timer->Start(pollIntervalMs);
255 m_playPauseButton->SetPicture(gClient->GetPicture(icondir + "ed_interrupt.png"));
256 }
257}

◆ toggleUndock()

void toggleUndock ( )

dock/undock active viewer.

Definition at line 674 of file DisplayUI.cc.

675{
676 TGLViewer* activeGLviewer = getViewPane()->getActiveGLViewer();
677 TEveViewerList* viewers = gEve->GetViewers();
678 TEveElement::List_ci end_it = viewers->EndChildren();
679 TEveViewer* activeViewer = nullptr;
680 for (TEveElement::List_i it = viewers->BeginChildren(); it != end_it; ++it) {
681 TEveViewer* v = static_cast<TEveViewer*>(*it);
682 if (v->GetGLViewer() == activeGLviewer) {
683 activeViewer = v;
684 break;
685 }
686 }
687
688 if (!activeViewer) {
689 B2ERROR("No active viewer. Please select one by clicking on it.");
690 return;
691 }
692
693 TEveCompositeFrameInMainFrame* packFrame = dynamic_cast<TEveCompositeFrameInMainFrame*>(activeViewer->GetEveFrame());
694 if (!packFrame) {
695 //we're docked
696 activeViewer->UndockWindow();
697 } else {
698 //we're undocked
699 packFrame->MainFrameClosed();
700 }
701}

◆ updateUI()

void updateUI ( )
private

Update UI after a new event was loaded, as well as m_currentEntry.

Definition at line 139 of file DisplayUI.cc.

140{
143
145 }
146
147 //change UI state?
148 const long numEntries = InputController::numEntries();
150 m_nextButton->SetEnabled((m_currentEntry + 1 < numEntries) or !InputController::canControlInput());
151 if (m_currentEntry != m_eventNumberWidget->GetIntNumber())
152 m_eventNumberWidget->SetIntNumber(m_currentEntry);
153 if (m_timer and InputController::canControlInput() and !m_nextButton->IsEnabled()) {
154 //reached last file entry in play mode, stop
156 }
157 if (m_flagEvent)
158 m_flagEvent->SetState(kButtonUp);
159
160 StoreObjPtr<EventMetaData> eventMetaData;
161 m_eventLabel->SetTextColor(gROOT->GetColor(kBlack));
162 if (!eventMetaData) {
163 m_eventLabel->SetText("No EventMetaData object available.");
164 } else {
165 time_t secondsSinceEpoch = eventMetaData->getTime() / 1e9;
166 //double subSecondPart = double(eventMetaData->getTime()) / 1e9 - secondsSinceEpoch;
167 char date[30] = "<Invalid time>";
168 if (secondsSinceEpoch == 0)
169 strcpy(date, "");
170 else if (auto gmt = gmtime(&secondsSinceEpoch))
171 strftime(date, 30, "<%Y-%m-%d %H:%M:%S UTC>", gmt);
172 m_eventLabel->SetText(TString::Format("Event: \t\t%u\nRun: \t\t%d\nExperiment: \t%d\n\n%s",
173 eventMetaData->getEvent(),
174 eventMetaData->getRun(), eventMetaData->getExperiment(),
175 date));
176 }
177 m_eventLabel->Resize();
178
179 gVirtualX->SetCursor(gEve->GetBrowser()->GetId(), gVirtualX->CreateCursor(kPointer));
180}
static std::string getCurrentFileName(bool independentPath=false)
Return name of current file in loaded chain (or empty string if none loaded).
static long getCurrentEntry(bool independentPath=false)
returns the entry number currently loaded.

Member Data Documentation

◆ m_advance

bool m_advance {false}
private

If true, start advancing through the events on startup.

Definition at line 189 of file DisplayUI.h.

◆ m_autoAdvanceDelay

TGNumberEntry* m_autoAdvanceDelay {nullptr}
private

Delay for automatic advance, in seconds.

Definition at line 207 of file DisplayUI.h.

◆ m_autoFileNamePrefix

TGTextEntry* m_autoFileNamePrefix {nullptr}
private

File name prefix (prefix + event number + "_" + projection + ".png").

Definition at line 219 of file DisplayUI.h.

◆ m_automatic

bool m_automatic {false}
private

If true, disable interactive control and call automaticEvent() instead.

Definition at line 186 of file DisplayUI.h.

◆ m_autoPictureWidth

TGNumberEntry* m_autoPictureWidth {nullptr}
private

width of saved PNGs.

Definition at line 222 of file DisplayUI.h.

◆ m_cumulative

bool m_cumulative {false}
private

If true, DisplayModule shouldn't clear previous data (i.e.

we want to show multiple events)

Definition at line 192 of file DisplayUI.h.

◆ m_currentEntry

long m_currentEntry {0}
private

Current entry id.

Definition at line 177 of file DisplayUI.h.

◆ m_eventData

TEveElementList* m_eventData {nullptr}
private

List of event data, including projections.

Definition at line 225 of file DisplayUI.h.

◆ m_eventLabel

TGLabel* m_eventLabel {nullptr}
private

show event/run/exp number for current event.

Definition at line 216 of file DisplayUI.h.

◆ m_eventNumberWidget

TGNumberEntry* m_eventNumberWidget {nullptr}
private

Event switcher with numeric entry.

Definition at line 204 of file DisplayUI.h.

◆ m_flagEvent

TGCheckButton* m_flagEvent {nullptr}
private

Show control for flagging events (to set module return value).

Definition at line 213 of file DisplayUI.h.

◆ m_guiInitialized

bool m_guiInitialized {false}
private

Was GUI already built?

Definition at line 180 of file DisplayUI.h.

◆ m_hideObjects

std::vector<std::string> m_hideObjects
private

objects which are to be hidden (can be manually re-enabled in tree view).

Names correspond to the object names in the 'Event Scene'.

Definition at line 234 of file DisplayUI.h.

◆ m_nextButton

TGButton* m_nextButton {nullptr}
private

Button to switch to next event.

Definition at line 201 of file DisplayUI.h.

◆ m_paramList

std::vector<Parameter> m_paramList
private

List of run time configurable module parameters.

Definition at line 195 of file DisplayUI.h.

◆ m_playPauseButton

TGPictureButton* m_playPauseButton {nullptr}
private

Play / Pause button.

Definition at line 210 of file DisplayUI.h.

◆ m_prevButton

TGButton* m_prevButton {nullptr}
private

Button to switch to previous event.

Definition at line 198 of file DisplayUI.h.

◆ m_reshowCurrentEvent

bool m_reshowCurrentEvent {false}
private

Show current event again after startDisplay() returns?

Definition at line 183 of file DisplayUI.h.

◆ m_timer

TTimer* m_timer {nullptr}
private

Polling/auto-advance timer.

Definition at line 231 of file DisplayUI.h.

◆ m_viewPane

SplitGLView* m_viewPane {nullptr}
private

pointer to right-side pane with viewers.

Definition at line 228 of file DisplayUI.h.


The documentation for this class was generated from the following files: