Revision
61
Author
emsmith
Date
2006-12-06 15:28:23 -0800 (Wed, 06 Dec 2006)

Log Message

drag and drop toolbar customization - todo: seperators and spaces, save changes, reset to default bar, change icon size and toolbar style drop downs

Modified Paths

Diff

Modified: desktop/trunk/lib/actions.class.php (60 => 61)


--- desktop/trunk/lib/actions.class.php	2006-12-04 18:04:13 UTC (rev 60)
+++ desktop/trunk/lib/actions.class.php	2006-12-06 23:28:23 UTC (rev 61)
@@ -91,9 +91,11 @@
 	public function create_menu_item($group, $action)
 	{
 		$tips = CC_Tooltips::instance();
-		$action = $this->get_action($group, $action);
-		$widget = $action->create_menu_item();
-		$tips->set_tip($widget, $action->get_property('tooltip'));
+		$item = $this->get_action($group, $action);
+		$widget = $item->create_menu_item();
+		$tips->set_tip($widget, $item->get_property('tooltip'));
+		$widget->set_data('group', $group);
+		$widget->set_data('action', $action);
 		return $widget;
 	}
 
@@ -111,10 +113,12 @@
 	public function create_tool_item($group, $action)
 	{
 		$tips = CC_Tooltips::instance();
-		$action = $this->get_action($group, $action);
-		$widget = $action->create_tool_item();
+		$item = $this->get_action($group, $action);
+		$widget = $item->create_tool_item();
 		$widget->set_use_underline(TRUE);
-		$tips->set_tip($widget, $action->get_property('tooltip'));
+		$tips->set_tip($widget, $item->get_property('tooltip'));
+		$widget->set_data('group', $group);
+		$widget->set_data('action', $action);
 		return $widget;
 	}
 
@@ -131,12 +135,12 @@
 	public function create_button_item($group, $action)
 	{
 		$tips = CC_Tooltips::instance();
-		$action = $this->get_action($group, $action);
-		if($action instanceof GtkRadioAction)
+		$item = $this->get_action($group, $action);
+		if($item instanceof GtkRadioAction)
 		{
 			$button = new GtkRadioButton();
 		}
-		elseif($action instanceof GtkToggleAction)
+		elseif($item instanceof GtkToggleAction)
 		{
 			$button = new GtkCheckButton();
 		}
@@ -144,12 +148,53 @@
 		{
 			$button = new GtkButton();
 		}
-		$tips->set_tip($button, $action->get_property('tooltip'));
-		$action->connect_proxy($button);
+		$tips->set_tip($button, $item->get_property('tooltip'));
+		$item->connect_proxy($button);
+		$button->set_data('group', $group);
+		$button->set_data('action', $action);
 		return $button;
 	}
 
 	/**
+	 * public function create_icon
+	 *
+	 * creates a icon and does tooltip
+	 *
+	 * @param string $group name of action group to get
+	 * @param string $action name of action to get
+	 * @return object instanceof GtkImage
+	 */
+	public function create_icon($group, $action, $size = CC::DND)
+	{
+		$tips = CC_Tooltips::instance();
+		$item = $this->get_action($group, $action);
+		$image = $item->create_icon($size);
+		$tips->set_tip($image, $item->get_property('tooltip'));
+		$image->set_data('group', $group);
+		$image->set_data('action', $action);
+		return $image;
+	}
+
+	/**
+	 * public function connect_proxy
+	 *
+	 * shortcut for connect proxy
+	 *
+	 * @param string $group name of action group to get
+	 * @param string $action name of action to get
+	 * @return object instanceof GtkWidget
+	 */
+	public function connect_proxy($widget, $group, $action)
+	{
+		$tips = CC_Tooltips::instance();
+		$item = $this->get_action($group, $action);
+		$widget->set_data('group', $group);
+		$widget->set_data('action', $action);
+		$tips->set_tip($widget, $item->get_property('tooltip'));
+		return $item->connect_proxy($widget);
+	}
+
+	/**
 	 * public function get_group
 	 *
 	 * returns action group

Modified: desktop/trunk/lib/toolbar.class.php (60 => 61)


--- desktop/trunk/lib/toolbar.class.php	2006-12-04 18:04:13 UTC (rev 60)
+++ desktop/trunk/lib/toolbar.class.php	2006-12-06 23:28:23 UTC (rev 61)
@@ -52,6 +52,18 @@
 	public $menu;
 
 	/**
+	 * during customize dnd, highlighted button
+	 * @var $highlight object instanceof GtkToolItem
+	 */
+	protected $highlight;
+
+	/**
+	 * icon view for customize
+	 * @var $view object instanceof GtkIconView
+	 */
+	protected $view;
+
+	/**
 	 * public function __construct
 	 *
 	 * just sets a name for the toolbar, should be unique
@@ -63,6 +75,9 @@
 	{
 		parent::__construct();
 		$this->set_name($name);
+		$this->connect('drag-motion', array($this, 'dragMotion'));
+		$this->connect('drag-drop', array($this, 'dragDrop'));
+		$this->connect('drag-leave', array($this, 'dragLeave'));
 		return;
 	}
 
@@ -156,6 +171,7 @@
 			if($item === 'separator')
 			{
 				$this->insert($item = new GtkSeparatorToolItem(), -1);
+				$item->connect('drag-begin', array($this, 'dragBegin'));
 			}
 			else
 			{
@@ -164,6 +180,7 @@
 				$item->child->set_events($item->get_events() | Gdk::BUTTON_PRESS_MASK);
 				$item->child->connect('button-press-event', array($this, 'doPopup'));
 				$item->child->connect_simple('popup-menu', array($this, 'popup'));
+				$item->connect('drag-begin', array($this, 'dragBegin'));
 			}
 		}
 		return;
@@ -306,9 +323,235 @@
 	 */
 	public function onCustomize()
 	{
-		$window = new CC_Customize($this->parent->parent, $this->parent->parent->customize);
-		$response = $window->run();
+		// make all buttons non-clickable and reorderable on the toolbar
+		$buttons = $this->get_children();
+		foreach($buttons as $button)
+		{
+			$button->set_use_drag_window(TRUE);
+			$button->drag_source_set(Gdk::BUTTON1_MASK,
+				array(array('application/x-toolbar-item', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
+		}
+		$this->drag_dest_set(Gtk::DEST_DEFAULT_ALL,
+			array( array('application/x-toolbar-item', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
+		
+		$window = $this->buildDialog();
+		$window->show_all();
+		$window->connect('destroy', array($this, 'stopDrag'));
 		return;
 	}
+
+	/**
+	 * public function dragBegin
+	 *
+	 *  stores toolbutton item and sets appropriate dnd pixmap if needed
+	 *
+	 * @return void
+	 */
+	public function dragBegin($widget, $context)
+	{
+		if($widget instanceof GtkIconView)
+		{
+			$iter = $widget->get_selected_items();
+			$model = $widget->get_model();
+			$iter = $model->get_iter($iter[0]);
+			$pixbuf = $model->get_value($iter, 2);
+			$widget->drag_source_set_icon_pixbuf($pixbuf);
+			$this->highlight = $iter;
+			return;
+		}
+		elseif(!($widget instanceof GtkSeparatorToolItem))
+		{
+			$pixbuf = $this->render_icon($widget->get_property('stock-id'), Gtk::ICON_SIZE_DND);
+			$widget->drag_source_set_icon_pixbuf($pixbuf);
+		}
+		$this->highlight = $widget;
+		return;
+	}
+
+	/**
+	 * public function dragMotion
+	 *
+	 * sets the highlight button, and if needed removes the button we're moving
+	 *
+	 * @return void
+	 */
+	public function dragMotion($toolbar, $context, $x, $y, $time)
+	{
+		$index = $toolbar->get_drop_index($x, $y);
+		if($this->highlight instanceof GtkToolItem)
+		{
+			$this->highlight->hide();
+			$toolbar->set_drop_highlight_item(GtkToolButton::new_from_stock($this->highlight->get_property('stock-id')), $index);
+		}
+		else
+		{
+			$model = $this->view->get_model();
+			$action = CC_Actions::instance()->get_action($model->get_value($this->highlight, 0), $model->get_value($this->highlight, 1));
+			$toolbar->set_drop_highlight_item(GtkToolButton::new_from_stock($action->get_property('stock-id')), $index);
+		}
+		return;
+	}
+
+	/**
+	 * public function dragBegin
+	 *
+	 * turns off highlighting and replace removed item in old location
+	 *
+	 * @return void
+	 */
+	public function dragLeave($toolbar, $context, $time)
+	{
+		$toolbar->set_drop_highlight_item(NULL, 0);
+		if($this->highlight instanceof GtkToolItem)
+		{
+			$this->highlight->show();
+		}
+		return;
+	}
+
+	/**
+	 * public function removeButton
+	 *
+	 * strip a button out of the toolbar and put it in the iconview
+	 *
+	 * @return void
+	 */
+	public function removeButton($view, $context, $x, $y, $time)
+	{
+		$group = $this->highlight->get_data('group');
+		$action = $this->highlight->get_data('action');
+		$item = CC_Actions::instance()->get_action($group, $action);
+		$pixbuf = $this->render_icon($item->get_property('stock-id'),  CC::$DND);
+		$view->get_model()->append(array($group, $action, $pixbuf, preg_replace('/(?<!_)_|\.\.\./', '', $item->get_property('label'))));
+		$this->remove($this->highlight);
+		return;
+	}
+
+	/**
+	 * public function stopDrag
+	 *
+	 * turns draggable buttons back to normal
+	 *
+	 * @return void
+	 */
+	public function stopDrag()
+	{
+		// make all buttons non-clickable and reorderable on the toolbar
+		$buttons = $this->get_children();
+		foreach($buttons as $button)
+		{
+			$button->set_use_drag_window(FALSE);
+			$button->drag_source_unset();
+		}
+		$this->drag_dest_unset();
+		return;
+	}
+
+	/**
+	 * public function dragDrop
+	 *
+	 * moves any dragged and dropped item to the new location and rewrites the
+	 * current array
+	 *
+	 * @return void
+	 */
+	public function dragDrop($toolbar, $context, $x, $y, $time)
+	{
+		$index = $toolbar->get_drop_index($x, $y);
+		if($this->highlight instanceof GtkToolItem)
+		{
+			$current = $toolbar->get_item_index($this->highlight);
+			$toolbar->remove($this->highlight);
+			if($current < $index)
+			{
+				$index--;
+			}
+			$toolbar->insert($this->highlight, $index);
+		}
+		else
+		{
+			$model = $this->view->get_model();
+			// toolbar->highlight needs a button
+			$item = CC_Actions::instance()->create_tool_item($model->get_value($this->highlight, 0), $model->get_value($this->highlight, 1));
+			$item->child->set_events($item->get_events() | Gdk::BUTTON_PRESS_MASK);
+			$item->child->connect('button-press-event', array($this, 'doPopup'));
+			$item->child->connect_simple('popup-menu', array($this, 'popup'));
+			$item->set_use_drag_window(TRUE);
+			$item->drag_source_set(Gdk::BUTTON1_MASK,
+				array(array('application/x-toolbar-item', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
+			$item->connect('drag-begin', array($this, 'dragBegin'));
+			$toolbar->insert($item, $index);
+			$model->remove($this->highlight);
+			$this->view->select_path(0);
+		}
+		return;
+	}
+
+	/**
+	 * public function buildDialog
+	 *
+	 * builds a dialog for customizing toolbar
+	 *
+	 * @return void
+	 */
+	protected function buildDialog()
+	{
+		$window = new GtkDialog(CC::i18n('%s :: %s', $this->parent->parent->program, 'Customize'),
+			$this->parent->parent, Gtk::DIALOG_DESTROY_WITH_PARENT | Gtk::DIALOG_NO_SEPARATOR);
+		$window->set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
+		$window->set_default_size('300', '400');
+		$window->set_border_width(10);
+
+		$actions = CC_Actions::instance();
+		$label = new GtkLabel();
+		$label->set_markup(CC::i18n('<b><big>%s</big></b>',
+			'Add items by dragging them from this window onto the toolbar.' . "\n"
+			. 'Remove items by dragging them from the toolbar into this window.' . "\n"
+			. 'Reorder toolbar items by dragging them to their new position.'));
+		$window->vbox->pack_start($label, FALSE, FALSE);
+		$button = $window->add_button(Gtk::STOCK_CLOSE, Gtk::RESPONSE_CLOSE);
+		$button->connect_simple('clicked', array($window, 'destroy'));
+
+		// create iconview to hold all possible items
+		$this->view = $view = new GtkIconView();
+
+		$model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING, GdkPixbuf::gtype, Gtk::TYPE_STRING);
+		$view->set_model($model);
+		$list = array_diff($this->options, $this->current);
+
+		// fill the model with default actions
+		foreach($list as $item)
+		{
+			list($group, $action) = explode(':', $item);
+			$item = $actions->get_action($group, $action);
+			$pixbuf = $this->render_icon($item->get_property('stock-id'),  CC::$DND);
+			$model->append(array($group, $action, $pixbuf, preg_replace('/(?<!_)_|\.\.\./', '', $item->get_property('label'))));
+		}
+		$view->set_pixbuf_column(2);
+		$view->set_markup_column(3);
+		$view->set_columns(0);
+		$view->set_selection_mode(Gtk::SELECTION_BROWSE);
+		$view->drag_source_set(Gdk::BUTTON1_MASK,
+				array(array('application/x-toolbar-item', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
+		$view->connect('drag-begin', array($this, 'dragBegin'));
+		$view->drag_dest_set(Gtk::DEST_DEFAULT_ALL,
+			array( array('application/x-toolbar-item', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE);
+		$view->connect('drag-drop', array($this, 'removeButton'));
+		$view->select_path(0);
+
+		// scrolling window
+		$scroll = new GtkScrolledWindow();
+		$scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+		$scroll->add($view);
+		$window->vbox->add($scroll);
+
+		// getting this positioned is not fun
+		list($x, $y) = $this->get_parent_window()->get_origin();
+		$position = $this->get_allocation();
+		// y is y position toolbar height allocation + toolbar y position
+		$y += $position->height + $position->y;
+		$window->move($x, $y);
+		return $window;
+	}
 }
 ?>
\ No newline at end of file

Modified: desktop/trunk/lib/window.class.php (60 => 61)


--- desktop/trunk/lib/window.class.php	2006-12-04 18:04:13 UTC (rev 60)
+++ desktop/trunk/lib/window.class.php	2006-12-06 23:28:23 UTC (rev 61)
@@ -29,6 +29,12 @@
 {
 
 	/**
+	 * program name for app
+	 * @var $program string
+	 */
+	public $program;
+
+	/**
 	 * main vbox for window
 	 * @var $vbox object instanceof GtkVBox
 	 */
@@ -53,12 +59,6 @@
 	public $statusbar;
 
 	/**
-	 * customize style for window
-	 * @var $customize int
-	 */
-	public $customize = CC_Customize::ICONVIEW;
-
-	/**
 	 * windows can be minimized, maximized and fullscreened
 	 * @var $minimized bool
 	 */
@@ -127,7 +127,11 @@
 	 */
 	public function set_title($title, $program = 'Callicore')
 	{
-		parent::set_title(CC::i18n('%s :: %s', $program, $title));
+		if(empty($this->program))
+		{
+			$this->program = $program;
+		}
+		parent::set_title(CC::i18n('%s :: %s', $this->program, $title));
 		return;
 	}
 

Modified: desktop/trunk/programs/writer/lib/writer.class.php (60 => 61)


--- desktop/trunk/programs/writer/lib/writer.class.php	2006-12-04 18:04:13 UTC (rev 60)
+++ desktop/trunk/programs/writer/lib/writer.class.php	2006-12-06 23:28:23 UTC (rev 61)
@@ -381,7 +381,7 @@
 			'separator', 'manage:import', 'manage:export', 'separator',
 			'file:print', 'manage:properties');
 
-		$this->toolbar->options = array('separator', 'file:new', 'file:open',
+		$this->toolbar->options = array('file:new', 'file:open',
 			'file:close','file:delete', 'file:save', 'file:saveas',
 			'file:revert', 'file:print', 'file:quit','manage:wizard',
 			'manage:import', 'manage:export', 'manage:properties',