27 #define YUILogComponent "ui-dialog-spy"
30 #include <YDialogSpy.h>
31 #include <YWidgetFactory.h>
32 #include <YWidgetID.h>
37 #include <YTreeItem.h>
38 #include <YLayoutBox.h>
39 #include <YAlignment.h>
40 #include <YButtonBox.h>
41 #include <YPushButton.h>
42 #include <YMenuButton.h>
43 #include <YComboBox.h>
44 #include <YInputField.h>
45 #include <YCheckBox.h>
46 #include <YRadioButton.h>
47 #include <YProgressBar.h>
48 #include <YRichText.h>
49 #include <YBusyIndicator.h>
50 #include <YSelectionBox.h>
51 #include <YMultiSelectionBox.h>
52 #include <YMultiLineEdit.h>
55 #include <YIntField.h>
60 #include <YPackageSelector.h>
61 #include <YReplacePoint.h>
62 #include <YPropertyEditor.h>
63 #include <YPopupInternal.h>
64 #include <YAlignment.h>
65 #include <YCheckBoxFrame.h>
66 #include <YRadioButtonGroup.h>
69 #define TREE_VWEIGHT 40
70 #define PROP_VWEIGHT 60
74 #define TREE_HEIGHT 10
77 #define PROP_HEIGHT 12
109 YWidget * widget()
const {
return _widget; }
114 void setWidgetLabel()
116 std::ostringstream str;
128 YWidgetListConstIterator begin,
129 YWidgetListConstIterator end,
139 : targetDialog(
nullptr )
140 , spyDialog(
nullptr )
141 , widgetTree(
nullptr )
142 , propButton(
nullptr )
143 , propReplacePoint(
nullptr )
144 , propTable(
nullptr )
171 void moveSelectedUp() { moveSelected(MOVE_UP); }
172 void moveSelectedDown() { moveSelected(MOVE_DOWN); }
182 void moveSelected( Direction direction );
183 void showProperties();
184 void hideProperties();
185 bool propertiesShown()
const;
186 void targetDialogUpdated();
187 void refreshButtonStates();
188 void editWidget(
YWidget *widget,
const string & property=
"Label" );
209 YUI_CHECK_NEW( rootItem );
211 widgetTree->
addItem( rootItem );
222 if ( ! targetDialog )
225 priv->targetDialog = targetDialog;
228 priv->spyDialog = fac->createPopupDialog();
229 YAlignment * diaMin = fac->createMinHeight( priv->spyDialog, DIA_HEIGHT );
230 YLayoutBox * vbox = fac->createVBox( diaMin );
232 auto alignment = fac->createLeft( vbox );
233 auto fileMenu = fac->createMenuButton( alignment,
"&File" );
236 priv->exportMenu =
new YMenuItem(
"Export (TODO)" );
237 items.push_back( priv->exportMenu );
238 fileMenu->addItems( items );
240 auto minSize = fac->createMinSize( vbox, TREE_WIDTH, TREE_HEIGHT );
241 minSize->
setWeight( YD_VERT, TREE_VWEIGHT );
242 priv->widgetTree = fac->createTree( minSize,
"Widget &Tree",
false );
245 fillWidgetTree(priv->targetDialog, priv->widgetTree);
247 auto hbox = fac->createHBox( vbox );
248 priv->propButton = fac->createPushButton( hbox,
"&Properties >>>" );
250 priv->addButton = fac->createMenuButton( hbox,
"&Add" );
259 add_items.push_back( menu_info );
260 add_items.push_back( menu_buttons );
261 add_items.push_back( menu_input );
262 add_items.push_back( menu_align );
263 add_items.push_back( menu_size );
264 add_items.push_back( menu_containers );
265 add_items.push_back( menu_special );
270 new YMenuItem( menu_info,
"ProgressBar" );
271 new YMenuItem( menu_info,
"BusyIndicator" );
274 new YMenuItem( menu_buttons,
"PushButton" );
275 new YMenuItem( menu_buttons,
"CheckBox" );
276 new YMenuItem( menu_buttons,
"ComboBox" );
277 new YMenuItem( menu_buttons,
"MenuButton" );
278 new YMenuItem( menu_buttons,
"RadioButton" );
280 new YMenuItem( menu_input,
"InputField" );
282 new YMenuItem( menu_input,
"MultiLineEdit" );
283 new YMenuItem( menu_input,
"MultiSelectionBox" );
285 new YMenuItem( menu_input,
"SelectionBox" );
304 new YMenuItem( menu_containers,
"MarginBox" );
305 new YMenuItem( menu_containers,
"ButtonBox" );
306 new YMenuItem( menu_containers,
"CheckBoxFrame" );
307 new YMenuItem( menu_containers,
"Frame" );
308 new YMenuItem( menu_containers,
"HBox" );
309 new YMenuItem( menu_containers,
"HSpacing" );
310 new YMenuItem( menu_containers,
"ReplacePoint" );
311 new YMenuItem( menu_containers,
"VBox" );
312 new YMenuItem( menu_containers,
"VSpacing" );
315 new YMenuItem( menu_special,
"BarGraph" );
316 new YMenuItem( menu_special,
"DateField" );
317 new YMenuItem( menu_special,
"DumbTab" );
320 new YMenuItem( menu_input,
"TimeField" );
321 new YMenuItem( menu_special,
"TimezoneSelector" );
323 priv->addButton->
addItems( add_items );
325 priv->deleteButton = fac->createPushButton( hbox,
"&Delete" );
326 priv->upButton = fac->createPushButton( hbox,
"⬆ Up" );
327 priv->downButton = fac->createPushButton( hbox,
"⬇ Down" );
329 priv->propReplacePoint = fac->createReplacePoint( vbox );
330 fac->createEmpty( priv->propReplacePoint );
340 if ( priv->spyDialog )
347 bool YDialogSpyPrivate::propertiesShown()
const
349 return propTable !=
nullptr;
363 void YDialogSpyPrivate::showProperties()
365 if ( propertiesShown() )
return;
368 propReplacePoint->
setWeight( YD_VERT, PROP_VWEIGHT );
371 auto minSize = fac->createMinSize( propReplacePoint,
372 PROP_WIDTH, PROP_HEIGHT );
374 YUI_CHECK_NEW( header );
375 header->addColumn(
"Property" );
376 header->addColumn(
"Value" );
377 header->addColumn(
"Type" );
379 propTable = fac->createTable( minSize, header );
382 propButton->
setLabel(
"<<< &Properties" );
390 void YDialogSpyPrivate::hideProperties()
392 if ( !propertiesShown() )
return;
395 propReplacePoint->
setWeight( YD_VERT, 0 );
399 propButton->
setLabel(
"&Properties >>>" );
410 bool ret = !propertiesShown();
440 auto propSet = widget->propertySet();
441 items.reserve( propSet.size() );
443 for ( YPropertySet::const_iterator it = propSet.propertiesBegin();
444 it != propSet.propertiesEnd();
451 switch ( prop.
type() )
453 case YStringProperty:
458 propValStr = propVal.boolVal() ?
"true" :
"false";
461 case YIntegerProperty:
462 propValStr = std::to_string(propVal.integerVal());
471 YUI_CHECK_NEW( item );
472 items.push_back( item );
487 YWidgetListConstIterator begin,
488 YWidgetListConstIterator end,
491 for ( YWidgetListConstIterator it = begin; it != end; ++it )
506 YUI_CHECK_PTR( priv->spyDialog );
511 yuiMilestone() <<
"event: " << event;
512 if (!event)
continue;
515 if ( event->eventType() == YEvent::CancelEvent )
break;
516 else if ( event->eventType() == YEvent::MenuEvent)
521 if (menu_item == priv->exportMenu)
continue;
527 auto menu_label = menu_item->
label();
528 yuiMilestone() <<
"Activated menu item: " << menu_label << endl;
536 if (!event->widget())
continue;
538 if ( event->widget() == priv->upButton ) priv->moveSelectedUp();
539 else if ( event->widget() == priv->downButton) priv->moveSelectedDown();
541 else if ( event->widget() == priv->deleteButton) priv->
deleteWidget();
542 else if ( event->widget() == priv->propTable ) priv->
editProperty();
561 YUI_CAUGHT( exception );
574 return item ? item->widget() :
nullptr;
584 refreshButtonStates();
593 if (!selected_item)
return;
595 auto cell = selected_item->
cell(0);
596 yuiMilestone() <<
"editing property: " << cell->label();
611 auto parent = w->
parent();
614 yuiMilestone() <<
"removing widget: " << w << endl;
615 parent->removeChild(w);
630 targetDialogUpdated();
638 bool isBox(
const YWidget *widget)
640 return dynamic_cast<const YLayoutBox *
>(widget);
648 bool isVBox(
const YWidget *widget)
650 auto box =
dynamic_cast<const YLayoutBox *
>(widget);
651 return box && box->
primary() == YD_VERT;
660 void YDialogSpyPrivate::moveSelected(Direction direction)
663 if (!target_widget)
return;
665 auto parent = target_widget->
parent();
666 if (!parent || !isBox(parent))
return;
668 if (direction == MOVE_UP)
671 if (target_widget == parent->firstChild())
return;
679 std::swap(*other, *i);
686 if (target_widget == parent->lastChild())
return;
694 std::swap(*other, *i);
698 targetDialogUpdated();
714 if (type ==
"Bottom")
715 editWidget(f->createBottom(widget));
716 else if (type ==
"BusyIndicator")
717 editWidget(f->createBusyIndicator(widget,
"Busy Indicator", 10000));
718 else if (type ==
"ButtonBox")
719 editWidget(f->createButtonBox(widget));
720 else if (type ==
"ComboBox")
722 auto cb = f->createComboBox(widget,
"Combo Box");
729 for(
auto&& str: items) add_items.push_back(
new YMenuItem( str ) );
730 cb->addItems( add_items );
732 else if (type ==
"Empty")
733 editWidget(f->createEmpty(widget));
734 else if (type ==
"Frame")
735 editWidget(f->createFrame(widget,
"Frame"));
736 else if (type ==
"HBox")
737 editWidget(f->createHBox(widget));
738 else if (type ==
"Heading")
739 editWidget(f->createHeading(widget,
"Heading"));
740 else if (type ==
"HSpacing")
741 editWidget(f->createHSpacing(widget));
742 else if (type ==
"HStretch")
743 editWidget(f->createHStretch(widget));
744 else if (type ==
"CheckBox")
745 editWidget(f->createCheckBox(widget,
"Check Box"));
746 else if (type ==
"CheckBoxFrame")
748 editWidget(f->createCheckBoxFrame(widget,
"Check Box Frame",
true));
749 else if (type ==
"Image")
750 editWidget(f->createImage(widget,
""));
751 else if (type ==
"InputField")
752 editWidget(f->createInputField(widget,
"Input"));
753 else if (type ==
"IntField")
754 editWidget(f->createIntField(widget,
"Integer Field", 0, 100, 50));
755 else if (type ==
"Label")
756 editWidget(f->createLabel(widget,
"Label"));
757 else if (type ==
"Left")
758 editWidget(f->createLeft(widget));
759 else if (type ==
"LogView")
760 editWidget(f->createLogView(widget,
"Log View", 12));
761 else if (type ==
"MenuButton")
763 auto menu = f->createMenuButton( widget,
"Menu" );
770 for(
auto&& str: items) add_items.push_back(
new YMenuItem( str ) );
771 menu->addItems( add_items );
773 else if (type ==
"MinHeight")
774 editWidget(f->createMinHeight(widget, 10));
775 else if (type ==
"MinWidth")
776 editWidget(f->createMinWidth(widget, 10));
777 else if (type ==
"MinSize")
778 editWidget(f->createMinSize(widget, 10, 10));
779 else if (type ==
"MultiLineEdit")
780 editWidget(f->createMultiLineEdit(widget,
"MultiLineEdit"));
781 else if (type ==
"MultiSelectionBox")
783 auto msb = f->createMultiSelectionBox(widget,
"MultiSelection Box");
789 for(
auto&& str: items) msb->addItem(str);
791 else if (type ==
"OutputField")
792 editWidget(f->createOutputField(widget,
"Output Field"));
793 else if (type ==
"Password")
794 editWidget(f->createPasswordField(widget,
"Password"));
795 else if (type ==
"ProgressBar")
796 editWidget(f->createProgressBar(widget,
"Progress"));
797 else if (type ==
"PushButton")
798 editWidget(f->createPushButton(widget,
"Button"));
799 else if (type ==
"RadioButton")
800 editWidget(f->createRadioButton(widget,
"Radio Button"));
801 else if (type ==
"RadioButtonGroup")
802 editWidget(f->createRadioButtonGroup(widget));
803 else if (type ==
"ReplacePoint")
804 editWidget(f->createReplacePoint(widget));
805 else if (type ==
"Right")
806 editWidget(f->createRight(widget));
807 else if (type ==
"RichText")
808 editWidget(f->createRichText(widget,
"This is a <b>RichText</b>."));
809 else if (type ==
"SelectionBox")
810 editWidget(f->createSelectionBox(widget,
"Selection Box"));
811 else if (type ==
"Table")
821 for(
auto&& str: items) header->addColumn(str);
823 editWidget(f->createTable(widget, header));
826 else if (type ==
"Top")
827 editWidget(f->createTop(widget));
828 else if (type ==
"Tree")
829 editWidget(f->createTree(widget,
"Tree"));
830 else if (type ==
"VBox")
831 editWidget(f->createVBox(widget));
832 else if (type ==
"VSpacing")
833 editWidget(f->createVSpacing(widget));
834 else if (type ==
"VStretch")
835 editWidget(f->createVStretch(widget));
839 "Adding \"" + type +
"\" widget type is not supported.");
843 targetDialogUpdated();
855 void YDialogSpyPrivate::targetDialogUpdated()
862 fillWidgetTree(targetDialog, widgetTree);
868 void YDialogSpyPrivate::refreshButtonStates()
871 auto parent = widget ? widget->
parent() :
nullptr;
875 if (widget && parent && isBox(parent))
877 upButton->
setEnabled(widget != parent->firstChild());
878 upButton->
setLabel(isVBox(parent) ?
"⬆ Up" :
"⬅ Left");
879 downButton->
setEnabled(widget != parent->lastChild());
880 downButton->
setLabel(isVBox(parent) ?
"⬇ Down" :
"➡ Right");
903 void YDialogSpyPrivate::editWidget(
YWidget *widget,
const string &property)
911 editor.edit(property);