27 #define YUILogComponent "ui-dialog-spy"
30 #include <YDialogSpy.h>
31 #include <YWidgetFactory.h>
36 #include <YTreeItem.h>
37 #include <YLayoutBox.h>
38 #include <YAlignment.h>
39 #include <YButtonBox.h>
40 #include <YPushButton.h>
41 #include <YMenuButton.h>
42 #include <YComboBox.h>
43 #include <YInputField.h>
44 #include <YCheckBox.h>
45 #include <YRadioButton.h>
46 #include <YProgressBar.h>
47 #include <YRichText.h>
48 #include <YBusyIndicator.h>
49 #include <YSelectionBox.h>
50 #include <YMultiSelectionBox.h>
51 #include <YMultiLineEdit.h>
54 #include <YIntField.h>
59 #include <YPackageSelector.h>
60 #include <YReplacePoint.h>
61 #include <YPropertyEditor.h>
62 #include <YPopupInternal.h>
63 #include <YAlignment.h>
64 #include <YCheckBoxFrame.h>
65 #include <YRadioButtonGroup.h>
68 #define TREE_VWEIGHT 40
69 #define PROP_VWEIGHT 60
73 #define TREE_HEIGHT 10
76 #define PROP_HEIGHT 12
103 YWidget * widget()
const {
return _widget; }
108 void setWidgetLabel()
110 std::ostringstream str;
121 YWidgetListConstIterator begin,
122 YWidgetListConstIterator end,
133 : targetDialog(
nullptr )
134 , spyDialog(
nullptr )
135 , widgetTree(
nullptr )
136 , propButton(
nullptr )
137 , propReplacePoint(
nullptr )
138 , propTable(
nullptr )
164 void moveSelectedUp() { moveSelected(MOVE_UP); }
165 void moveSelectedDown() { moveSelected(MOVE_DOWN); }
174 void moveSelected(Direction direction);
175 void showProperties();
176 void hideProperties();
177 bool propertiesShown()
const;
178 void targetDialogUpdated();
179 void refreshButtonStates();
180 void editWidget(
YWidget *widget,
const std::string &property=
"Label");
197 YUI_CHECK_NEW( rootItem );
199 widgetTree->
addItem( rootItem );
208 if ( ! targetDialog )
211 priv->targetDialog = targetDialog;
214 priv->spyDialog = fac->createPopupDialog();
215 YAlignment * diaMin = fac->createMinHeight( priv->spyDialog, DIA_HEIGHT );
216 YLayoutBox * vbox = fac->createVBox( diaMin );
218 auto alignment = fac->createLeft( vbox );
219 auto fileMenu = fac->createMenuButton( alignment,
"&File" );
222 priv->exportMenu =
new YMenuItem(
"Export (TODO)" );
223 items.push_back( priv->exportMenu );
224 fileMenu->addItems( items );
226 auto minSize = fac->createMinSize( vbox, TREE_WIDTH, TREE_HEIGHT );
227 minSize->
setWeight( YD_VERT, TREE_VWEIGHT );
228 priv->widgetTree = fac->createTree( minSize,
"Widget &Tree",
false );
231 fillWidgetTree(priv->targetDialog, priv->widgetTree);
233 auto hbox = fac->createHBox( vbox );
234 priv->propButton = fac->createPushButton( hbox,
"&Properties >>>" );
236 priv->addButton = fac->createMenuButton( hbox,
"&Add" );
245 add_items.push_back( menu_info );
246 add_items.push_back( menu_buttons );
247 add_items.push_back( menu_input );
248 add_items.push_back( menu_align );
249 add_items.push_back( menu_size );
250 add_items.push_back( menu_containers );
251 add_items.push_back( menu_special );
256 new YMenuItem( menu_info,
"ProgressBar" );
257 new YMenuItem( menu_info,
"BusyIndicator" );
260 new YMenuItem( menu_buttons,
"PushButton" );
261 new YMenuItem( menu_buttons,
"CheckBox" );
262 new YMenuItem( menu_buttons,
"ComboBox" );
263 new YMenuItem( menu_buttons,
"MenuButton" );
264 new YMenuItem( menu_buttons,
"RadioButton" );
266 new YMenuItem( menu_input,
"InputField" );
268 new YMenuItem( menu_input,
"MultiLineEdit" );
269 new YMenuItem( menu_input,
"MultiSelectionBox" );
271 new YMenuItem( menu_input,
"SelectionBox" );
290 new YMenuItem( menu_containers,
"MarginBox" );
291 new YMenuItem( menu_containers,
"ButtonBox" );
292 new YMenuItem( menu_containers,
"CheckBoxFrame" );
293 new YMenuItem( menu_containers,
"Frame" );
294 new YMenuItem( menu_containers,
"HBox" );
295 new YMenuItem( menu_containers,
"HSpacing" );
296 new YMenuItem( menu_containers,
"ReplacePoint" );
297 new YMenuItem( menu_containers,
"VBox" );
298 new YMenuItem( menu_containers,
"VSpacing" );
301 new YMenuItem( menu_special,
"BarGraph" );
302 new YMenuItem( menu_special,
"DateField" );
303 new YMenuItem( menu_special,
"DumbTab" );
306 new YMenuItem( menu_input,
"TimeField" );
307 new YMenuItem( menu_special,
"TimezoneSelector" );
309 priv->addButton->
addItems( add_items );
311 priv->deleteButton = fac->createPushButton( hbox,
"&Delete" );
312 priv->upButton = fac->createPushButton( hbox,
"⬆ Up" );
313 priv->downButton = fac->createPushButton( hbox,
"⬇ Down" );
315 priv->propReplacePoint = fac->createReplacePoint( vbox );
316 fac->createEmpty( priv->propReplacePoint );
326 if ( priv->spyDialog )
333 bool YDialogSpyPrivate::propertiesShown()
const
335 return propTable !=
nullptr;
349 void YDialogSpyPrivate::showProperties()
351 if ( propertiesShown() )
return;
354 propReplacePoint->
setWeight( YD_VERT, PROP_VWEIGHT );
357 auto minSize = fac->createMinSize( propReplacePoint,
358 PROP_WIDTH, PROP_HEIGHT );
360 YUI_CHECK_NEW( header );
361 header->addColumn(
"Property" );
362 header->addColumn(
"Value" );
363 header->addColumn(
"Type" );
365 propTable = fac->createTable( minSize, header );
368 propButton->
setLabel(
"<<< &Properties" );
376 void YDialogSpyPrivate::hideProperties()
378 if ( !propertiesShown() )
return;
381 propReplacePoint->
setWeight( YD_VERT, 0 );
385 propButton->
setLabel(
"&Properties >>>" );
396 bool ret = !propertiesShown();
422 auto propSet = widget->propertySet();
424 items.reserve( propSet.size() );
426 for ( YPropertySet::const_iterator it = propSet.propertiesBegin();
427 it != propSet.propertiesEnd();
432 std::string propValStr;
434 switch ( prop.
type() )
436 case YStringProperty:
441 propValStr = propVal.boolVal() ?
"true" :
"false";
444 case YIntegerProperty:
445 propValStr = std::to_string(propVal.integerVal());
454 YUI_CHECK_NEW( item );
455 items.push_back( item );
470 YWidgetListConstIterator begin,
471 YWidgetListConstIterator end,
474 for ( YWidgetListConstIterator it = begin; it != end; ++it )
489 YUI_CHECK_PTR( priv->spyDialog );
494 yuiMilestone() <<
"event: " << event;
495 if (!event)
continue;
498 if ( event->eventType() == YEvent::CancelEvent )
break;
499 else if ( event->eventType() == YEvent::MenuEvent)
504 if (menu_item == priv->exportMenu)
continue;
510 auto menu_label = menu_item->
label();
511 yuiMilestone() <<
"Activated menu item: " << menu_label << std::endl;
519 if (!event->widget())
continue;
521 if ( event->widget() == priv->upButton ) priv->moveSelectedUp();
522 else if ( event->widget() == priv->downButton) priv->moveSelectedDown();
524 else if ( event->widget() == priv->deleteButton) priv->
deleteWidget();
525 else if ( event->widget() == priv->propTable ) priv->
editProperty();
544 YUI_CAUGHT( exception );
557 return item ? item->widget() :
nullptr;
567 refreshButtonStates();
576 if (!selected_item)
return;
578 auto cell = selected_item->
cell(0);
579 yuiMilestone() <<
"editing property: " << cell->label();
594 auto parent = w->
parent();
597 yuiMilestone() <<
"removing widget: " << w << std::endl;
598 parent->removeChild(w);
613 targetDialogUpdated();
621 bool isBox(
const YWidget *widget)
623 return dynamic_cast<const YLayoutBox *
>(widget);
631 bool isVBox(
const YWidget *widget)
633 auto box =
dynamic_cast<const YLayoutBox *
>(widget);
634 return box && box->
primary() == YD_VERT;
643 void YDialogSpyPrivate::moveSelected(Direction direction)
646 if (!target_widget)
return;
648 auto parent = target_widget->
parent();
649 if (!parent || !isBox(parent))
return;
651 if (direction == MOVE_UP)
654 if (target_widget == parent->firstChild())
return;
662 std::swap(*other, *i);
669 if (target_widget == parent->lastChild())
return;
677 std::swap(*other, *i);
681 targetDialogUpdated();
697 if (type ==
"Bottom")
698 editWidget(f->createBottom(widget));
699 else if (type ==
"BusyIndicator")
700 editWidget(f->createBusyIndicator(widget,
"Busy Indicator", 10000));
701 else if (type ==
"ButtonBox")
702 editWidget(f->createButtonBox(widget));
703 else if (type ==
"ComboBox")
705 auto cb = f->createComboBox(widget,
"Combo Box");
712 for(
auto&& str: items) add_items.push_back(
new YMenuItem( str ) );
713 cb->addItems( add_items );
715 else if (type ==
"Empty")
716 editWidget(f->createEmpty(widget));
717 else if (type ==
"Frame")
718 editWidget(f->createFrame(widget,
"Frame"));
719 else if (type ==
"HBox")
720 editWidget(f->createHBox(widget));
721 else if (type ==
"Heading")
722 editWidget(f->createHeading(widget,
"Heading"));
723 else if (type ==
"HSpacing")
724 editWidget(f->createHSpacing(widget));
725 else if (type ==
"HStretch")
726 editWidget(f->createHStretch(widget));
727 else if (type ==
"CheckBox")
728 editWidget(f->createCheckBox(widget,
"Check Box"));
729 else if (type ==
"CheckBoxFrame")
731 editWidget(f->createCheckBoxFrame(widget,
"Check Box Frame",
true));
732 else if (type ==
"Image")
733 editWidget(f->createImage(widget,
""));
734 else if (type ==
"InputField")
735 editWidget(f->createInputField(widget,
"Input"));
736 else if (type ==
"IntField")
737 editWidget(f->createIntField(widget,
"Integer Field", 0, 100, 50));
738 else if (type ==
"Label")
739 editWidget(f->createLabel(widget,
"Label"));
740 else if (type ==
"Left")
741 editWidget(f->createLeft(widget));
742 else if (type ==
"LogView")
743 editWidget(f->createLogView(widget,
"Log View", 12));
744 else if (type ==
"MenuButton")
746 auto menu = f->createMenuButton( widget,
"Menu" );
753 for(
auto&& str: items) add_items.push_back(
new YMenuItem( str ) );
754 menu->addItems( add_items );
756 else if (type ==
"MinHeight")
757 editWidget(f->createMinHeight(widget, 10));
758 else if (type ==
"MinWidth")
759 editWidget(f->createMinWidth(widget, 10));
760 else if (type ==
"MinSize")
761 editWidget(f->createMinSize(widget, 10, 10));
762 else if (type ==
"MultiLineEdit")
763 editWidget(f->createMultiLineEdit(widget,
"MultiLineEdit"));
764 else if (type ==
"MultiSelectionBox")
766 auto msb = f->createMultiSelectionBox(widget,
"MultiSelection Box");
772 for(
auto&& str: items) msb->addItem(str);
774 else if (type ==
"OutputField")
775 editWidget(f->createOutputField(widget,
"Output Field"));
776 else if (type ==
"Password")
777 editWidget(f->createPasswordField(widget,
"Password"));
778 else if (type ==
"ProgressBar")
779 editWidget(f->createProgressBar(widget,
"Progress"));
780 else if (type ==
"PushButton")
781 editWidget(f->createPushButton(widget,
"Button"));
782 else if (type ==
"RadioButton")
783 editWidget(f->createRadioButton(widget,
"Radio Button"));
784 else if (type ==
"RadioButtonGroup")
785 editWidget(f->createRadioButtonGroup(widget));
786 else if (type ==
"ReplacePoint")
787 editWidget(f->createReplacePoint(widget));
788 else if (type ==
"Right")
789 editWidget(f->createRight(widget));
790 else if (type ==
"RichText")
791 editWidget(f->createRichText(widget,
"This is a <b>RichText</b>."));
792 else if (type ==
"SelectionBox")
793 editWidget(f->createSelectionBox(widget,
"Selection Box"));
794 else if (type ==
"Table")
804 for(
auto&& str: items) header->addColumn(str);
806 editWidget(f->createTable(widget, header));
809 else if (type ==
"Top")
810 editWidget(f->createTop(widget));
811 else if (type ==
"Tree")
812 editWidget(f->createTree(widget,
"Tree"));
813 else if (type ==
"VBox")
814 editWidget(f->createVBox(widget));
815 else if (type ==
"VSpacing")
816 editWidget(f->createVSpacing(widget));
817 else if (type ==
"VStretch")
818 editWidget(f->createVStretch(widget));
822 "Adding \"" + type +
"\" widget type is not supported.");
826 targetDialogUpdated();
838 void YDialogSpyPrivate::targetDialogUpdated()
845 fillWidgetTree(targetDialog, widgetTree);
851 void YDialogSpyPrivate::refreshButtonStates()
854 auto parent = widget ? widget->
parent() :
nullptr;
858 if (widget && parent && isBox(parent))
860 upButton->
setEnabled(widget != parent->firstChild());
861 upButton->
setLabel(isVBox(parent) ?
"⬆ Up" :
"⬅ Left");
862 downButton->
setEnabled(widget != parent->lastChild());
863 downButton->
setLabel(isVBox(parent) ?
"⬇ Down" :
"➡ Right");
886 void YDialogSpyPrivate::editWidget(
YWidget *widget,
const std::string &property)
894 editor.edit(property);