Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:01:20

0001 #include "Fireworks/Core/interface/FWDialogBuilder.h"
0002 #include "Fireworks/Core/interface/FWColorManager.h"
0003 #include "Fireworks/Core/src/FWGUIValidatingTextEntry.h"
0004 #include "Fireworks/Core/src/FWColorSelect.h"
0005 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
0006 
0007 #include "TGFrame.h"
0008 #include "TGLabel.h"
0009 #include "TGButton.h"
0010 #include "TG3DLine.h"
0011 #include "TGLViewer.h"
0012 #include "TGSlider.h"
0013 #include "TGTab.h"
0014 #include "TGTextView.h"
0015 #include "TGTextEdit.h"
0016 #include "TGNumberEntry.h"
0017 #include "TGHtml.h"
0018 
0019 FWLayoutBuilder::FWLayoutBuilder(TGCompositeFrame *window, bool expandY)
0020     : m_window(window),
0021       m_currentFrame(nullptr),
0022       m_floatLeft(false),
0023       m_topSpacing(0),
0024       m_leftSpacing(0),
0025       m_currentHints(nullptr),
0026       m_currentFrameHints(nullptr) {
0027   TGVerticalFrame *mainFrame = new TGVerticalFrame(window);
0028   TGLayoutHints *hints = new TGLayoutHints(expandY ? kLHintsExpandX | kLHintsExpandY : kLHintsExpandX, 0, 0, 0, 0);
0029   m_window->AddFrame(mainFrame, hints);
0030   m_framesStack.push_back(mainFrame);
0031 }
0032 
0033 FWLayoutBuilder &FWLayoutBuilder::newRow(void) {
0034   m_currentFrameHints = m_currentHints = new TGLayoutHints(kLHintsExpandX);
0035   m_currentFrame = new TGHorizontalFrame(m_framesStack.back());
0036   m_framesStack.back()->AddFrame(m_currentFrame, m_currentHints);
0037   return *this;
0038 }
0039 
0040 FWLayoutBuilder &FWLayoutBuilder::indent(int left /*= 2*/, int right /* = -1*/) {
0041   if (right < 0)
0042     right = left;
0043 
0044   TGVerticalFrame *parent = m_framesStack.back();
0045   TGLayoutHints *hints = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, left, right, 0, 0);
0046   m_currentHints = nullptr;
0047   m_framesStack.push_back(new TGVerticalFrame(parent));
0048   parent->AddFrame(m_framesStack.back(), hints);
0049   return newRow().expand(true, false);
0050 }
0051 
0052 /** Return the last vertical frame, for more control on the layout. */
0053 TGVerticalFrame *FWLayoutBuilder::verticalFrame(void) {
0054   assert(!m_framesStack.empty());
0055   return m_framesStack.back();
0056 }
0057 
0058 /** Removes all the frames on the stack since last indent. */
0059 FWLayoutBuilder &FWLayoutBuilder::unindent(void) {
0060   assert(!m_framesStack.empty());
0061   m_framesStack.pop_back();
0062   return *this;
0063 }
0064 
0065 /** Make sure that the current layout element is going to float on the 
0066     left of the next one.
0067   */
0068 FWLayoutBuilder &FWLayoutBuilder::floatLeft(size_t spacing) {
0069   m_floatLeft = true;
0070   m_leftSpacing = spacing;
0071   return *this;
0072 }
0073 
0074 FWLayoutBuilder &FWLayoutBuilder::spaceUp(size_t spacing) {
0075   if (m_currentHints)
0076     m_currentHints->SetPadTop(spacing);
0077   return *this;
0078 }
0079 
0080 FWLayoutBuilder &FWLayoutBuilder::spaceDown(size_t spacing) {
0081   if (m_currentHints)
0082     m_currentHints->SetPadBottom(spacing);
0083   return *this;
0084 }
0085 
0086 FWLayoutBuilder &FWLayoutBuilder::spaceLeft(size_t spacing) {
0087   if (m_currentHints)
0088     m_currentHints->SetPadLeft(spacing);
0089   return *this;
0090 }
0091 
0092 FWLayoutBuilder &FWLayoutBuilder::spaceRight(size_t spacing) {
0093   if (m_currentHints)
0094     m_currentHints->SetPadRight(spacing);
0095   return *this;
0096 }
0097 
0098 FWLayoutBuilder &FWLayoutBuilder::frameSpaceUp(size_t spacing) {
0099   if (m_currentFrameHints)
0100     m_currentFrameHints->SetPadTop(spacing);
0101   return *this;
0102 }
0103 
0104 FWLayoutBuilder &FWLayoutBuilder::frameSpaceDown(size_t spacing) {
0105   if (m_currentFrameHints)
0106     m_currentFrameHints->SetPadBottom(spacing);
0107   return *this;
0108 }
0109 
0110 FWLayoutBuilder &FWLayoutBuilder::frameSpaceLeft(size_t spacing) {
0111   if (m_currentFrameHints)
0112     m_currentFrameHints->SetPadLeft(spacing);
0113   return *this;
0114 }
0115 
0116 FWLayoutBuilder &FWLayoutBuilder::frameSpaceRight(size_t spacing) {
0117   if (m_currentFrameHints)
0118     m_currentFrameHints->SetPadRight(spacing);
0119   return *this;
0120 }
0121 
0122 /** Set whether or not the previous layout element should expand and
0123     in which direction.
0124   */
0125 FWLayoutBuilder &FWLayoutBuilder::expand(bool expandX /*= true*/, bool expandY /*= false*/) {
0126   UInt_t style = 0;
0127   style |= expandX ? kLHintsExpandX : 0;
0128   style |= expandY ? kLHintsExpandY : 0;
0129 
0130   if (m_currentHints)
0131     m_currentHints->SetLayoutHints(style);
0132   return *this;
0133 }
0134 
0135 // Returns the next layout to be used.
0136 TGLayoutHints *FWLayoutBuilder::nextHints() {
0137   if (m_floatLeft) {
0138     size_t left = m_leftSpacing;
0139     m_floatLeft = false;
0140     m_leftSpacing = 0;
0141     assert(m_currentHints);
0142     m_currentHints = new TGLayoutHints(kLHintsExpandX, left, 0, m_currentHints->GetPadTop(), 0);
0143   } else {
0144     size_t top = m_topSpacing;
0145     m_topSpacing = 3;
0146     m_currentHints = new TGLayoutHints(kLHintsExpandX, 0, 0, top, 0);
0147   }
0148   return m_currentHints;
0149 }
0150 
0151 TGCompositeFrame *FWLayoutBuilder::nextFrame() {
0152   if (!isFloatingLeft())
0153     newRow();
0154 
0155   return currentFrame();
0156 }
0157 
0158 void FWLayoutBuilder::frameForTab() {
0159   m_currentFrame = new TGVerticalFrame(m_framesStack.back());
0160   m_currentFrame->SetBackgroundColor(0x000000);
0161   m_framesStack.back()->AddFrame(m_currentFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0162   // m_frameStack.push_back(m_currentFrame);
0163 }
0164 
0165 /** Helper class to construct dialogs in a more readable ways.
0166 
0167     Encapsulated TGUI layout hiccups and exposes the developer an API which
0168     allows to layout items in a top->bottom, right->left manner.
0169     
0170     Example:
0171     
0172       FWDialogBuilder builder(parent);
0173       parent.newRow(2)              // New row which has a 2 pixel padding on top.
0174             .addLabel("MyLabel:")    // A new label.
0175             .indent(20)             // Whatever follows is indented 20 pixels 
0176                                     // on the right.
0177             .addLabel("MyLabel2")   // Another label.
0178             .spaceDown(4)
0179             .addTextButton("Aligned to MyLabel2 ").floatLeft()
0180             .addTextButton("Same Row as previous")
0181             .unindent()              // back one level in the indentation.
0182             .addLabel("Aligned to MyLabel:")
0183             
0184     Because in ROOT layout and parenting of widgets are mixed we need to take
0185     responsibility for creating the widget objects (sigh!), so we have one
0186     "addXYZ" method per widget that can be added. If we find our way around
0187     this it would be better to have a generic "addWidget()" method and create
0188     widgets outside this class.
0189     
0190     TODO: For higher configurability we should have an 
0191           "addWithCallback(Callbak)"  method which can be used to specify a 
0192           generic widget creation action.
0193   */
0194 FWDialogBuilder::FWDialogBuilder(TGCompositeFrame *window, FWDialogBuilder *parent /*= 0*/, bool expandY)
0195     : FWLayoutBuilder(window, expandY), m_parent(parent), m_tabs(nullptr) {}
0196 
0197 FWDialogBuilder &FWDialogBuilder::newRow() {
0198   FWLayoutBuilder::newRow();
0199   return *this;
0200 }
0201 
0202 FWDialogBuilder &FWDialogBuilder::indent(int left /* = 2*/, int right /* = -1*/) {
0203   FWLayoutBuilder::indent(left, right);
0204   return *this;
0205 }
0206 
0207 FWDialogBuilder &FWDialogBuilder::unindent(void) {
0208   FWLayoutBuilder::unindent();
0209   return *this;
0210 }
0211 
0212 FWDialogBuilder &FWDialogBuilder::addLabel(const char *text,
0213                                            size_t fontSize /*= 12*/,
0214                                            size_t weight /*= 0*/,
0215                                            TGLabel **out /*= 0*/) {
0216   TGLabel *label = new TGLabel(nextFrame(), text);
0217 
0218   if (fontSize != 0) {
0219     FontStruct_t defaultFontStruct = label->GetDefaultFontStruct();
0220     try {
0221       TGFontPool *pool = gClient->GetFontPool();
0222       TGFont *defaultFont = pool->GetFont(defaultFontStruct);
0223       FontAttributes_t attributes = defaultFont->GetFontAttributes();
0224       label->SetTextFont(pool->GetFont(attributes.fFamily, fontSize, attributes.fWeight, attributes.fSlant));
0225     } catch (...) {
0226       // Ignore exceptions.
0227     }
0228   }
0229 
0230   label->SetTextJustify(kTextLeft);
0231 
0232   TGLayoutHints *hints = nextHints();
0233   UInt_t style = hints->GetLayoutHints() | kLHintsCenterY;
0234   hints->SetLayoutHints(style);
0235   currentFrame()->AddFrame(label, hints);
0236 
0237   return extract(label, out);
0238 }
0239 
0240 FWDialogBuilder &FWDialogBuilder::addTextView(const char *defaultText /*= 0*/, TGTextView **out /*= 0*/) {
0241   TGTextView *view = new TGTextView(nextFrame(), 100, 100);
0242   if (defaultText)
0243     view->AddLine(defaultText);
0244   currentFrame()->AddFrame(view, nextHints());
0245   expand(true, true);
0246   return extract(view, out);
0247 }
0248 
0249 FWDialogBuilder &FWDialogBuilder::addHtml(TGHtml **out /*= 0*/) {
0250   TGHtml *html = new TGHtml(nextFrame(), 100, 100);
0251   currentFrame()->AddFrame(html, nextHints());
0252   expand(true, true);
0253   return extract(html, out);
0254 }
0255 
0256 FWDialogBuilder &FWDialogBuilder::addTextEdit(const char *defaultText /*= 0*/, TGTextEdit **out /*= 0 */) {
0257   TGTextEdit *edit = new TGTextEdit(nextFrame(), 100, 100);
0258   if (defaultText)
0259     edit->AddLine(defaultText);
0260   currentFrame()->AddFrame(edit, nextHints());
0261   expand(true, true);
0262   return extract(edit, out);
0263 }
0264 
0265 FWDialogBuilder &FWDialogBuilder::addColorPicker(const FWColorManager *manager, FWColorSelect **out /*= 0*/) {
0266   const char *graphicsLabel = " ";
0267   FWColorSelect *widget = new FWColorSelect(nextFrame(), graphicsLabel, 0, manager, -1);
0268 
0269   currentFrame()->AddFrame(widget, nextHints());
0270   widget->SetEnabled(kFALSE);
0271 
0272   return extract(widget, out);
0273 }
0274 
0275 FWDialogBuilder &FWDialogBuilder::addHSlider(size_t size, TGHSlider **out /*= 0*/) {
0276   TGHSlider *slider = new TGHSlider(nextFrame(), size, kSlider1);
0277   currentFrame()->AddFrame(slider, nextHints());
0278   slider->SetRange(0, 100);
0279   slider->SetPosition(100);
0280   slider->SetEnabled(false);
0281 
0282   return extract(slider, out);
0283 }
0284 
0285 FWDialogBuilder &FWDialogBuilder::addTextButton(const char *text, TGTextButton **out /*= 0*/) {
0286   TGTextButton *button = new TGTextButton(nextFrame(), text);
0287   currentFrame()->AddFrame(button, nextHints());
0288   button->SetEnabled(false);
0289 
0290   return extract(button, out);
0291 }
0292 
0293 FWDialogBuilder &FWDialogBuilder::addValidatingTextEntry(const char *defaultText,
0294                                                          FWGUIValidatingTextEntry **out /*= 0*/) {
0295   FWGUIValidatingTextEntry *entry = new FWGUIValidatingTextEntry(nextFrame());
0296   currentFrame()->AddFrame(entry, nextHints());
0297 
0298   return extract(entry, out);
0299 }
0300 
0301 FWDialogBuilder &FWDialogBuilder::addTextEntry(const char *defaultText, TGTextEntry **out) {
0302   TGTextEntry *entry = new TGTextEntry(nextFrame());
0303   currentFrame()->AddFrame(entry, nextHints());
0304   entry->SetEnabled(kFALSE);
0305 
0306   return extract(entry, out);
0307 }
0308 
0309 FWDialogBuilder &FWDialogBuilder::addNumberEntry(
0310     float defaultValue, size_t digits, TGNumberFormat::EStyle style, int min, int max, TGNumberEntry **out /*= 0*/) {
0311   TGNumberEntry *entry = new TGNumberEntry(nextFrame(),
0312                                            defaultValue,
0313                                            digits,
0314                                            -1,
0315                                            style,
0316                                            TGNumberFormat::kNEAAnyNumber,
0317                                            TGNumberFormat::kNELLimitMinMax,
0318                                            min,
0319                                            max);
0320   currentFrame()->AddFrame(entry, nextHints());
0321   entry->GetNumberEntry()->SetEnabled(kFALSE);
0322   entry->GetButtonUp()->SetEnabled(kFALSE);
0323   entry->GetButtonDown()->SetEnabled(kFALSE);
0324   return extract(entry, out);
0325 }
0326 
0327 FWDialogBuilder &FWDialogBuilder::addCheckbox(const char *text, TGCheckButton **out /*= 0*/) {
0328   TGCheckButton *button = new TGCheckButton(nextFrame(), text);
0329   button->SetState(kButtonDown, false);
0330   button->SetEnabled(false);
0331   currentFrame()->AddFrame(button, nextHints());
0332 
0333   return extract(button, out);
0334 }
0335 
0336 FWDialogBuilder &FWDialogBuilder::addTable(FWTableManagerBase *manager, FWTableWidget **out /*= 0*/) {
0337   expand(true, true);
0338   TGCompositeFrame *frame = verticalFrame();
0339   TGLayoutHints *hints = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
0340   FWTableWidget *table = new FWTableWidget(manager, frame);
0341   frame->AddFrame(table, hints);
0342   return extract(table, out);
0343 }
0344 
0345 FWDialogBuilder &FWDialogBuilder::addHSeparator(size_t horizontalPadding /*= 4*/, size_t verticalPadding /*= 3*/) {
0346   TGLayoutHints *hints =
0347       new TGLayoutHints(kLHintsExpandX, horizontalPadding, horizontalPadding, verticalPadding, verticalPadding);
0348 
0349   TGHorizontal3DLine *separator = new TGHorizontal3DLine(nextFrame(), 200, 2);
0350   currentFrame()->AddFrame(separator, hints);
0351   return newRow();
0352 }
0353 
0354 /** Support for tabs.
0355  
0356     This is done by creating a new DialogBuilder and returning it for each
0357     of the added tabs.
0358     
0359     builder.tabs()               // Adds a TGTab widget to the current frame.
0360            .beginTab("Foo")      // Add a tab to the TGTab.
0361            .textButton("In Foo") // This is inside the tab "Foo", the layouting
0362                                  // is independent from previous calls
0363                                  // since a separate builder was returned by
0364                                  // 
0365            .endTab("Foo")        // End of the tab.
0366            .beginTab("Bar")
0367            .endTab("")
0368            .untabs();            // Tabs completed.
0369            .textButton("Main scope") // This is on the same level as the TGTab.
0370     
0371   */
0372 FWDialogBuilder &FWDialogBuilder::tabs(TGTab **out) {
0373   // m_currentFrame = new TGVerticalFrame(m_framesStack.back());
0374   //m_framesStack.back()->AddFrame(m_currentFrame, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY));
0375   frameForTab();
0376 
0377   m_tabs = new TGTab(currentFrame());
0378   currentFrame()->AddFrame(m_tabs, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
0379   //expand(true, true);
0380   return extract(m_tabs, out);
0381 }
0382 
0383 FWDialogBuilder &FWDialogBuilder::untabs(void) {
0384   // No untabs() without tabs().
0385   assert(m_tabs);
0386   m_tabs = nullptr;
0387   return *this;
0388 }
0389 
0390 /** Adds a new tab called @a label.
0391     A new tab gets a new builder so that tab building is completely scoped.
0392   */
0393 FWDialogBuilder &FWDialogBuilder::beginTab(const char *label) {
0394   TGCompositeFrame *tab = m_tabs->AddTab(label);
0395 
0396   FWDialogBuilder *builder = new FWDialogBuilder(tab, this, false);
0397   return builder->newRow();
0398 }
0399 
0400 /** When we are done with the tab, we delete ourself and return the parent.
0401   */
0402 FWDialogBuilder &FWDialogBuilder::endTab(void) {
0403   FWDialogBuilder *parent = m_parent;
0404   delete this;
0405   return *parent;
0406 }
0407 
0408 FWDialogBuilder &FWDialogBuilder::floatLeft(size_t spacing /*= 3*/) {
0409   FWLayoutBuilder::floatLeft(spacing);
0410   return *this;
0411 }
0412 
0413 FWDialogBuilder &FWDialogBuilder::spaceUp(size_t spacing /*= 3*/) {
0414   FWLayoutBuilder::spaceUp(spacing);
0415   return *this;
0416 }
0417 
0418 FWDialogBuilder &FWDialogBuilder::spaceDown(size_t spacing /*= 3*/) {
0419   FWLayoutBuilder::spaceDown(spacing);
0420   return *this;
0421 }
0422 
0423 FWDialogBuilder &FWDialogBuilder::spaceUpDown(size_t spacing /*= 3*/) {
0424   FWLayoutBuilder::spaceUp(spacing);
0425   FWLayoutBuilder::spaceDown(spacing);
0426   return *this;
0427 }
0428 
0429 FWDialogBuilder &FWDialogBuilder::spaceLeft(size_t spacing) {
0430   FWLayoutBuilder::spaceLeft(spacing);
0431   return *this;
0432 }
0433 
0434 FWDialogBuilder &FWDialogBuilder::spaceRight(size_t spacing) {
0435   FWLayoutBuilder::spaceRight(spacing);
0436   return *this;
0437 }
0438 
0439 FWDialogBuilder &FWDialogBuilder::spaceLeftRight(size_t spacing) {
0440   FWLayoutBuilder::spaceLeft(spacing);
0441   FWLayoutBuilder::spaceRight(spacing);
0442   return *this;
0443 }
0444 
0445 // Frame spacing
0446 
0447 FWDialogBuilder &FWDialogBuilder::frameSpaceUp(size_t spacing /*= 3*/) {
0448   FWLayoutBuilder::frameSpaceUp(spacing);
0449   return *this;
0450 }
0451 
0452 FWDialogBuilder &FWDialogBuilder::frameSpaceDown(size_t spacing /*= 3*/) {
0453   FWLayoutBuilder::frameSpaceDown(spacing);
0454   return *this;
0455 }
0456 
0457 FWDialogBuilder &FWDialogBuilder::frameSpaceUpDown(size_t spacing /*= 3*/) {
0458   FWLayoutBuilder::frameSpaceUp(spacing);
0459   FWLayoutBuilder::frameSpaceDown(spacing);
0460   return *this;
0461 }
0462 
0463 FWDialogBuilder &FWDialogBuilder::frameSpaceLeft(size_t spacing) {
0464   FWLayoutBuilder::frameSpaceLeft(spacing);
0465   return *this;
0466 }
0467 
0468 FWDialogBuilder &FWDialogBuilder::frameSpaceRight(size_t spacing) {
0469   FWLayoutBuilder::frameSpaceRight(spacing);
0470   return *this;
0471 }
0472 
0473 FWDialogBuilder &FWDialogBuilder::frameSpaceLeftRight(size_t spacing) {
0474   FWLayoutBuilder::frameSpaceLeft(spacing);
0475   FWLayoutBuilder::frameSpaceRight(spacing);
0476   return *this;
0477 }
0478 
0479 FWDialogBuilder &FWDialogBuilder::expand(size_t expandX /*= true*/, size_t expandY /*= false*/) {
0480   FWLayoutBuilder::expand(expandX, expandY);
0481   return *this;
0482 }
0483 
0484 FWDialogBuilder &FWDialogBuilder::vSpacer(size_t size /* = 0*/) {
0485   newRow().expand(true, true);
0486 
0487   TGFrame *frame;
0488   if (size)
0489     frame = new TGFrame(nextFrame(), 1, size);
0490   else
0491     frame = new TGFrame(nextFrame());
0492 
0493   currentFrame()->AddFrame(frame, nextHints());
0494 
0495   expand(true, true);
0496 
0497   return *this;
0498 }
0499 
0500 FWDialogBuilder &FWDialogBuilder::hSpacer(size_t size /* = 0*/) {
0501   TGFrame *frame;
0502   if (size)
0503     frame = new TGFrame(nextFrame(), size, 1);
0504   else
0505     frame = new TGFrame(nextFrame());
0506 
0507   currentFrame()->AddFrame(frame, nextHints());
0508 
0509   if (!size)
0510     expand(true, false);
0511   else
0512     expand(false, false);
0513 
0514   return *this;
0515 }