Author: tgoettlicher
Date: Fri Mar 6 15:37:51 2009
New Revision: 55978
URL: http://svn.opensuse.org/viewcvs/yast?rev=55978&view=rev
Log:
added missing files for context menu
Added:
trunk/libyui/src/YContextMenu.cc
trunk/libyui/src/YContextMenu.h
trunk/ycp-ui-bindings/examples/ContextMenu.ycp
Added: trunk/libyui/src/YContextMenu.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/libyui/src/YContextMenu.cc?rev=55978&view=auto
==============================================================================
--- trunk/libyui/src/YContextMenu.cc (added)
+++ trunk/libyui/src/YContextMenu.cc Fri Mar 6 15:37:51 2009
@@ -0,0 +1,200 @@
+/*---------------------------------------------------------------------\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ V / _` \___ \ | | __) | |
+| | | (_| |___) || | / __/ |
+| |_|\__,_|____/ |_| |_____| |
+| |
+| core system |
+| (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+ File: YContextMenu.cc
+
+ Author: Thomas Goettlicher
+
+/-*/
+
+
+#define YUILogComponent "ui"
+#include "YUILog.h"
+
+#include "YUISymbols.h"
+#include "YContextMenu.h"
+#include "YMenuItem.h"
+
+
+struct YContextMenuPrivate
+{
+ YContextMenuPrivate()
+ : nextSerialNo( 0 )
+ {}
+
+ int nextSerialNo;
+};
+
+
+
+
+YContextMenu::YContextMenu( )
+ : YSelectionWidget( NULL, "test",
+ false ) // enforceSingleSelection
+ , priv( new YContextMenuPrivate() )
+{
+ yuiWarning() << "YContextMenu";
+
+ YUI_CHECK_NEW( priv );
+}
+
+
+YContextMenu::~YContextMenu()
+{
+ // NOP
+}
+
+
+void
+YContextMenu::addItems( const YItemCollection & itemCollection )
+{
+ YSelectionWidget::addItems( itemCollection );
+ resolveShortcutConflicts();
+ rebuildMenuTree();
+}
+
+
+void
+YContextMenu::addItem( YItem * item )
+{
+ YSelectionWidget::addItem( item );
+ item->setIndex( ++(priv->nextSerialNo) );
+
+ if ( item->hasChildren() )
+ assignUniqueIndex( item->childrenBegin(), item->childrenEnd() );
+}
+
+
+void
+YContextMenu::assignUniqueIndex( YItemIterator begin, YItemIterator end )
+{
+ for ( YItemIterator it = begin; it != end; ++it )
+ {
+ YItem * item = *it;
+
+ item->setIndex( ++(priv->nextSerialNo) );
+
+ if ( item->hasChildren() )
+ assignUniqueIndex( item->childrenBegin(), item->childrenEnd() );
+ }
+}
+
+
+void
+YContextMenu::deleteAllItems()
+{
+ YSelectionWidget::deleteAllItems();
+ priv->nextSerialNo = 0;
+}
+
+
+YMenuItem *
+YContextMenu::findMenuItem( int index )
+{
+ return findMenuItem( index, itemsBegin(), itemsEnd() );
+}
+
+
+YMenuItem *
+YContextMenu::findMenuItem( int wantedIndex, YItemConstIterator begin, YItemConstIterator end )
+{
+ for ( YItemConstIterator it = begin; it != end; ++it )
+ {
+ YMenuItem * item = dynamic_cast (*it);
+
+ if ( item )
+ {
+ if ( item->index() == wantedIndex )
+ return item;
+
+ if ( item->hasChildren() )
+ {
+ YMenuItem * result = findMenuItem( wantedIndex, item->childrenBegin(), item->childrenEnd() );
+
+ if ( result )
+ return result;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+void
+YContextMenu::resolveShortcutConflicts()
+{
+ // TO DO
+ // TO DO
+ // TO DO
+
+ // For every menu level, make sure keyboard shortcuts are unique within that menu level.
+ // If necessary, change some of them (move the '&' character to some other character).
+
+
+ // See YShortcutManager for more hints.
+}
+
+
+const YPropertySet &
+YContextMenu::propertySet()
+{
+ static YPropertySet propSet;
+
+ if ( propSet.isEmpty() )
+ {
+ /*
+ * @property string Label Label on the menu button
+ * @property itemList Items All menu items and submenus
+ * @property string IconPath Base path for icons (on menu items)
+ */
+ propSet.add( YProperty( YUIProperty_Label, YStringProperty ) );
+ propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) );
+ propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) );
+ propSet.add( YWidget::propertySet() );
+ }
+
+ return propSet;
+}
+
+
+bool
+YContextMenu::setProperty( const string & propertyName, const YPropertyValue & val )
+{
+ propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch
+
+ if ( propertyName == YUIProperty_Label ) setLabel( val.stringVal() );
+ else if ( propertyName == YUIProperty_Items ) return false; // Needs special handling
+ else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() );
+ else
+ {
+ return YWidget::setProperty( propertyName, val );
+ }
+
+ return true; // success -- no special processing necessary
+}
+
+
+YPropertyValue
+YContextMenu::getProperty( const string & propertyName )
+{
+ propertySet().check( propertyName ); // throws exceptions if not found
+
+ if ( propertyName == YUIProperty_Label ) return YPropertyValue( label() );
+ else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty );
+ else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() );
+ else
+ {
+ return YWidget::getProperty( propertyName );
+ }
+}
+
Added: trunk/libyui/src/YContextMenu.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/libyui/src/YContextMenu.h?rev=55978&view=auto
==============================================================================
--- trunk/libyui/src/YContextMenu.h (added)
+++ trunk/libyui/src/YContextMenu.h Fri Mar 6 15:37:51 2009
@@ -0,0 +1,179 @@
+/*---------------------------------------------------------------------\
+| |
+| __ __ ____ _____ ____ |
+| \ \ / /_ _/ ___|_ _|___ \ |
+| \ V / _` \___ \ | | __) | |
+| | | (_| |___) || | / __/ |
+| |_|\__,_|____/ |_| |_____| |
+| |
+| core system |
+| (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+ File: YContextMenu.h
+
+ Author: Stefan Hundhammer
+
+/-*/
+
+#ifndef YContextMenu_h
+#define YContextMenu_h
+
+#include "YSelectionWidget.h"
+#include "YMenuItem.h"
+
+class YMenuItem;
+class YContextMenuPrivate;
+
+
+/**
+ * ContextMenu: Similar to PushButton, but with several actions: Upon clicking
+ * on a ContextMenu (or activating it with the keyboard), a pop-up menu opens
+ * where the user can activate an action. Menu items in that pop-up menu can
+ * have submenus (that will pop up in separate pop-up menus).
+ *
+ * Internally, this widget is more similar to the Tree widget. The difference
+ * is that it does not keep a "selected" status, but triggers an action right
+ * away, just like a PushButton. Like PushButton, ContextMenu sends an event
+ * right away when the user selects an item (clicks on a menu item or activates
+ * it with the keyboard). Items that have a submenu never send an event, they
+ * simply open their submenu when activated.
+ **/
+class YContextMenu : public YSelectionWidget
+{
+protected:
+ /**
+ * Constructor.
+ *
+ * 'label' is the user-visible text on the button (not above it like all
+ * other SelectionWidgets).
+ **/
+ YContextMenu();
+
+public:
+ /**
+ * Destructor.
+ **/
+ virtual ~YContextMenu();
+
+ /**
+ * Returns a descriptive name of this widget class for logging,
+ * debugging etc.
+ **/
+ virtual const char * widgetClass() const { return "YContextMenu"; }
+
+ /**
+ * Rebuild the displayed menu tree from the internally stored YMenuItems.
+ *
+ * The application should call this (once) after all items have been added
+ * with addItem(). YContextMenu::addItems() calls this automatically.
+ *
+ * Derived classes are required to implement this.
+ **/
+ virtual void rebuildMenuTree() = 0;
+
+ /**
+ * Add multiple items. For some UIs, this can be more efficient than
+ * calling addItem() multiple times. This function also automatically calls
+ * resolveShortcutConflicts() and rebuildMenuTree() at the end.
+ *
+ * Derived classes can overwrite this function, but they should call this
+ * base class function at the end of the new implementation.
+ *
+ * Reimplemented from YSelectionWidget.
+ **/
+ virtual void addItems( const YItemCollection & itemCollection );
+
+ /**
+ * Add one item. This widget assumes ownership of the item object and will
+ * delete it in its destructor.
+ *
+ * This reimplementation will an index to the item that is unique for all
+ * items in this ContextMenu. That index can be used later with
+ * findMenuItem() to find the item by that index.
+ *
+ * Reimplemented from YSelectionWidget.
+ **/
+ virtual void addItem( YItem * item_disown );
+
+ /**
+ * Delete all items.
+ *
+ * Reimplemented from YSelectionWidget.
+ **/
+ virtual void deleteAllItems();
+
+ /**
+ * Resolve keyboard shortcut conflicts: Change shortcuts of menu items if
+ * there are duplicates in the respective menu level.
+ *
+ * This has to be called after all items are added, but before rebuildMenuTree()
+ * (see above). YContextMenu::addItems() calls this automatically.
+ **/
+ void resolveShortcutConflicts();
+
+ /**
+ * Set a property.
+ * Reimplemented from YWidget.
+ *
+ * This function may throw YUIPropertyExceptions.
+ *
+ * This function returns 'true' if the value was successfully set and
+ * 'false' if that value requires special handling (not in error cases:
+ * those are covered by exceptions).
+ **/
+ virtual bool setProperty( const string & propertyName,
+ const YPropertyValue & val );
+
+ /**
+ * Get a property.
+ * Reimplemented from YWidget.
+ *
+ * This method may throw YUIPropertyExceptions.
+ **/
+ virtual YPropertyValue getProperty( const string & propertyName );
+
+ /**
+ * Return this class's property set.
+ * This also initializes the property upon the first call.
+ *
+ * Reimplemented from YWidget.
+ **/
+ virtual const YPropertySet & propertySet();
+
+protected:
+
+ /**
+ * Recursively find the first menu item with the specified index.
+ * Returns 0 if there is no such item.
+ **/
+ YMenuItem * findMenuItem( int index );
+
+ /**
+ * Recursively find the first menu item with the specified index
+ * from iterator 'begin' to iterator 'end'.
+ *
+ * Returns 0 if there is no such item.
+ **/
+ YMenuItem * findMenuItem( int index, YItemConstIterator begin, YItemConstIterator end );
+
+ /**
+ * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour
+ * with YSelectionWidget::itemAt().
+ **/
+ YMenuItem * itemAt( int index )
+ { return findMenuItem( index ); }
+
+private:
+
+ /**
+ * Assign a unique index to all items from iterator 'begin' to iterator 'end'.
+ **/
+ void assignUniqueIndex( YItemIterator begin, YItemIterator end );
+
+
+ ImplPtr<YContextMenuPrivate> priv;
+};
+
+
+#endif // YContextMenu_h
Added: trunk/ycp-ui-bindings/examples/ContextMenu.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/ycp-ui-bindings/examples/ContextMenu.ycp?rev=55978&view=auto
==============================================================================
--- trunk/ycp-ui-bindings/examples/ContextMenu.ycp (added)
+++ trunk/ycp-ui-bindings/examples/ContextMenu.ycp Fri Mar 6 15:37:51 2009
@@ -0,0 +1,85 @@
+{
+ string formatEvent( map event )
+ {
+ string html = "<h3>Event:</h3><p>";
+ y2milestone ("formatEvent(%1)", event);
+ foreach (string key, any value, event, ``{
+ html = html + "<font color=blue>" + key + "</font>: " + tostring (value) + "<br>";
+ });
+ html = html + "</p>";
+ return html;
+ };
+
+
+ string event_display = "<i>No event yet - click something (or wait for timeout)</i>";
+
+
+ if ( ! UI::HasSpecialWidget(`Slider) )
+ {
+ UI::OpenDialog(
+ `VBox(
+ `Label("ContextMenu not supported!"),
+ `PushButton(`opt(`default), "&Oops!")
+ )
+ );
+ UI::UserInput();
+ UI::CloseDialog();
+ return;
+ }
+
+
+
+
+
+ UI::OpenDialog(
+ `VBox(
+ `SelectionBox( `id(`sport), `opt(`notify,`immediate, `contextMenu),
+ "Select your sport:",
+ [
+ "Swimming",
+ "Cycling",
+ "Running"
+ ] ),
+ `RichText(`id(`event_display), event_display ),
+ `PushButton(`id(`close), "&OK")
+ ) );
+
+ //
+ // Event loop
+ //
+
+ map event = $[];
+
+
+ repeat
+ {
+ event = UI::WaitForEvent( 100000 );
+ if ( event != nil )
+ {
+ UI::ChangeWidget(`event_display, `Value, formatEvent( event ) );
+ }
+
+ if ( event != nil && event["EventReason"]:"" == "ContextMenuActivated" )
+ {
+/* UI::OpenContextMenu( `menu(
+ [ `item(`id(`folder), "&Folder"),
+ `item(`id(`text), "&Text File" ),
+ `item(`id(`image), "&Image" )
+ ])); */
+
+
+UI::OpenContextMenu( `menu(
+ [ `item(`id(`instruct), "Instruc&tions" ),
+ `menu( "&Execute",
+ [ `item(`id(`training),
+ "&Training" ),
+ `item(`id(`race),
+ "&Race" ) ]) ] ));
+
+
+ }
+ } until ( event["ID"]:nil == `close );
+
+
+ UI::CloseDialog();
+}
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org