summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 13ebe98)
raw | patch | inline | side by side (parent: 13ebe98)
author | joncruz <joncruz@users.sourceforge.net> | |
Thu, 5 Apr 2007 00:35:22 +0000 (00:35 +0000) | ||
committer | joncruz <joncruz@users.sourceforge.net> | |
Thu, 5 Apr 2007 00:35:22 +0000 (00:35 +0000) |
src/Makefile_insert | patch | blob | history | |
src/ege-select-one-action.cpp | [new file with mode: 0644] | patch | blob |
src/ege-select-one-action.h | [new file with mode: 0644] | patch | blob |
src/helper/Makefile_insert | patch | blob | history | |
src/helper/unit-tracker.cpp | [new file with mode: 0644] | patch | blob |
src/helper/unit-tracker.h | [new file with mode: 0644] | patch | blob |
src/widgets/select-toolbar.cpp | patch | blob | history |
diff --git a/src/Makefile_insert b/src/Makefile_insert
index edf63b7b8774bbd4cd2f9678f6cfe57f0bc799ee..77bd4e7e5bfc5384031c5d4d4306fd76bf9162c4 100644 (file)
--- a/src/Makefile_insert
+++ b/src/Makefile_insert
ege-adjustment-action.h \
ege-output-action.cpp \
ege-output-action.h \
+ ege-select-one-action.cpp \
+ ege-select-one-action.h \
fill-or-stroke.h \
filter-chemistry.cpp filter-chemistry.h \
fixes.cpp \
diff --git a/src/ege-select-one-action.cpp b/src/ege-select-one-action.cpp
--- /dev/null
@@ -0,0 +1,407 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Select One Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <string.h>
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtktoolitem.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtkcelllayout.h>
+#include <gtk/gtkradiomenuitem.h>
+
+#include "ege-select-one-action.h"
+
+enum {
+ CHANGED = 0,
+ LAST_SIGNAL};
+
+
+static void ege_select_one_action_class_init( EgeSelectOneActionClass* klass );
+static void ege_select_one_action_init( EgeSelectOneAction* action );
+static void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
+static void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
+
+static void resync_active( EgeSelectOneAction* act, gint active );
+static void combo_changed_cb( GtkComboBox* widget, gpointer user_data );
+static void menu_toggled_cb( GtkWidget* obj, gpointer data );
+
+static GtkWidget* create_menu_item( GtkAction* action );
+static GtkWidget* create_tool_item( GtkAction* action );
+static void connect_proxy( GtkAction *action, GtkWidget *proxy );
+static void disconnect_proxy( GtkAction *action, GtkWidget *proxy );
+
+static GtkActionClass* gParentClass = 0;
+static guint signals[LAST_SIGNAL] = {0};
+static GQuark gDataName = 0;
+
+
+struct _EgeSelectOneActionPrivate
+{
+ GtkTreeModel* model;
+ gint active;
+ gint column;
+};
+
+#define EGE_SELECT_ONE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionPrivate ) )
+
+enum {
+ PROP_MODEL = 1,
+ PROP_ACTIVE,
+ PROP_COLUMN
+};
+
+GType ege_select_one_action_get_type( void )
+{
+ static GType myType = 0;
+ if ( !myType ) {
+ static const GTypeInfo myInfo = {
+ sizeof( EgeSelectOneActionClass ),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)ege_select_one_action_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof( EgeSelectOneAction ),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc)ege_select_one_action_init,
+ NULL
+ };
+
+ myType = g_type_register_static( GTK_TYPE_ACTION, "EgeSelectOneAction", &myInfo, (GTypeFlags)0 );
+ }
+
+ return myType;
+}
+
+void ege_select_one_action_class_init( EgeSelectOneActionClass* klass )
+{
+ if ( klass ) {
+ gParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
+ GObjectClass* objClass = G_OBJECT_CLASS( klass );
+
+ gDataName = g_quark_from_string("ege-select1-action");
+
+ objClass->get_property = ege_select_one_action_get_property;
+ objClass->set_property = ege_select_one_action_set_property;
+
+ klass->parent_class.create_menu_item = create_menu_item;
+ klass->parent_class.create_tool_item = create_tool_item;
+ klass->parent_class.connect_proxy = connect_proxy;
+ klass->parent_class.disconnect_proxy = disconnect_proxy;
+
+ g_object_class_install_property( objClass,
+ PROP_MODEL,
+ g_param_spec_object( "model",
+ "Tree Model",
+ "Tree model of possible items",
+ GTK_TYPE_TREE_MODEL,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_ACTIVE,
+ g_param_spec_int( "active",
+ "Active Selection",
+ "The index of the selected item",
+ 0, 20, 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ g_object_class_install_property( objClass,
+ PROP_COLUMN,
+ g_param_spec_int( "column",
+ "Display Column",
+ "The column of the model that holds display strings",
+ 0, 20, 0,
+ (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
+
+ signals[CHANGED] = g_signal_new( "changed",
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(EgeSelectOneActionClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ g_type_class_add_private( klass, sizeof(EgeSelectOneActionClass) );
+ }
+}
+
+
+void ege_select_one_action_init( EgeSelectOneAction* action )
+{
+ action->private_data = EGE_SELECT_ONE_ACTION_GET_PRIVATE( action );
+ action->private_data->model = 0;
+
+/* g_signal_connect( action, "notify", G_CALLBACK( fixup_labels ), NULL ); */
+}
+
+EgeSelectOneAction* ege_select_one_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel* model )
+{
+ GObject* obj = (GObject*)g_object_new( EGE_SELECT_ONE_ACTION_TYPE,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock_id", stock_id,
+ "model", model,
+ "active", 0,
+ NULL );
+
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+
+ return action;
+}
+
+
+gint ege_select_one_action_get_active( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->active;
+}
+
+void ege_select_one_action_set_active( EgeSelectOneAction* action, gint val )
+{
+ g_object_set( G_OBJECT(action), "active", val, NULL );
+}
+
+gint ege_select_one_action_get_label_column( EgeSelectOneAction* action )
+{
+ g_return_val_if_fail( IS_EGE_SELECT_ONE_ACTION(action), 0 );
+ return action->private_data->column;
+}
+
+void ege_select_one_action_set_label_column( EgeSelectOneAction* action, gint col )
+{
+ g_object_set( G_OBJECT(action), "column", col, NULL );
+}
+
+
+void ege_select_one_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
+{
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+ switch ( propId ) {
+ case PROP_MODEL:
+ g_value_set_object( value, action->private_data->model );
+ break;
+
+ case PROP_ACTIVE:
+ g_value_set_int( value, action->private_data->active );
+ break;
+
+ case PROP_COLUMN:
+ g_value_set_int( value, action->private_data->column );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+void ege_select_one_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
+{
+ EgeSelectOneAction* action = EGE_SELECT_ONE_ACTION( obj );
+ switch ( propId ) {
+ case PROP_MODEL:
+ {
+ action->private_data->model = GTK_TREE_MODEL( g_value_get_object( value ) );
+ }
+ break;
+
+ case PROP_ACTIVE:
+ {
+ resync_active( action, g_value_get_int( value ) );
+ }
+ break;
+
+ case PROP_COLUMN:
+ {
+ action->private_data->column = g_value_get_int( value );
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
+ }
+}
+
+GtkWidget* create_menu_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_SELECT_ONE_ACTION(action) ) {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( action );
+ gchar* sss = 0;
+ gboolean valid = FALSE;
+ gint index = 0;
+ GtkTreeIter iter;
+ GSList* group = 0;
+ GtkWidget* subby = gtk_menu_new();
+
+ g_object_get( G_OBJECT(action), "label", &sss, NULL );
+
+ item = gtk_menu_item_new_with_label( sss );
+
+ valid = gtk_tree_model_get_iter_first( act->private_data->model, &iter );
+ while ( valid ) {
+ gchar* str = 0;
+ gtk_tree_model_get( act->private_data->model, &iter,
+ act->private_data->column, &str,
+ -1 );
+
+ GtkWidget *item = gtk_radio_menu_item_new_with_label( group, str );
+ group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item) );
+ gtk_menu_shell_append( GTK_MENU_SHELL(subby), item );
+ g_object_set_qdata( G_OBJECT(item), gDataName, act );
+
+ gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item), index == act->private_data->active );
+
+ g_free(str);
+
+ g_signal_connect( G_OBJECT(item), "toggled", G_CALLBACK(menu_toggled_cb), GINT_TO_POINTER(index) );
+
+ index++;
+ valid = gtk_tree_model_iter_next( act->private_data->model, &iter );
+ }
+
+ gtk_menu_item_set_submenu( GTK_MENU_ITEM(item), subby );
+ gtk_widget_show_all( subby );
+
+ g_free(sss);
+ } else {
+ item = gParentClass->create_menu_item( action );
+ }
+
+ return item;
+}
+
+GtkWidget* create_tool_item( GtkAction* action )
+{
+ GtkWidget* item = 0;
+
+ if ( IS_EGE_SELECT_ONE_ACTION(action) && EGE_SELECT_ONE_ACTION(action)->private_data->model )
+ {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action);
+ item = GTK_WIDGET( gtk_tool_item_new() );
+
+ GtkWidget* normal = gtk_combo_box_new_with_model( act->private_data->model );
+
+ GtkCellRenderer * renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(normal), renderer, TRUE );
+ gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT(normal), renderer, "text", act->private_data->column, (gchar*)0);
+
+ gtk_combo_box_set_active( GTK_COMBO_BOX(normal), act->private_data->active );
+
+ g_signal_connect( G_OBJECT(normal), "changed", G_CALLBACK(combo_changed_cb), action );
+
+ gtk_container_add( GTK_CONTAINER(item), normal );
+
+ gtk_widget_show_all( item );
+ } else {
+ item = gParentClass->create_tool_item( action );
+ }
+
+ return item;
+}
+
+void connect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ gParentClass->connect_proxy( action, proxy );
+}
+
+void disconnect_proxy( GtkAction *action, GtkWidget *proxy )
+{
+ gParentClass->disconnect_proxy( action, proxy );
+}
+
+
+void resync_active( EgeSelectOneAction* act, gint active )
+{
+ if ( act->private_data->active != active ) {
+ act->private_data->active = active;
+ GSList* proxies = gtk_action_get_proxies( GTK_ACTION(act) );
+ while ( proxies ) {
+ if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
+ /* Search for the things we built up in create_tool_item() */
+ GList* children = gtk_container_get_children( GTK_CONTAINER(proxies->data) );
+ if ( children && children->data ) {
+ GtkComboBox* combo = GTK_COMBO_BOX(children->data);
+ if ( gtk_combo_box_get_active(combo) != active ) {
+ gtk_combo_box_set_active( combo, active );
+ }
+ }
+ } else if ( GTK_IS_MENU_ITEM(proxies->data) ) {
+ GtkWidget* subMenu = gtk_menu_item_get_submenu( GTK_MENU_ITEM(proxies->data) );
+ GList* children = gtk_container_get_children( GTK_CONTAINER(subMenu) );
+ if ( children && (g_list_length(children) > (guint)active) ) {
+ gpointer data = g_list_nth_data( children, active );
+ gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(data), TRUE );
+ }
+ }
+
+ proxies = g_slist_next( proxies );
+ }
+
+ g_signal_emit( G_OBJECT(act), signals[CHANGED], 0);
+ }
+}
+
+void combo_changed_cb( GtkComboBox* widget, gpointer user_data )
+{
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(user_data);
+ gint newActive = gtk_combo_box_get_active(widget);
+ if (newActive != act->private_data->active) {
+ g_object_set( G_OBJECT(act), "active", newActive, NULL );
+ }
+}
+
+void menu_toggled_cb( GtkWidget* obj, gpointer data )
+{
+ GtkCheckMenuItem* item = GTK_CHECK_MENU_ITEM(obj);
+ EgeSelectOneAction* act = (EgeSelectOneAction*)g_object_get_qdata( G_OBJECT(obj), gDataName );
+ gint newActive = GPOINTER_TO_INT(data);
+ if ( gtk_check_menu_item_get_active(item) && (newActive != act->private_data->active) ) {
+ g_object_set( G_OBJECT(act), "active", newActive, NULL );
+ }
+}
diff --git a/src/ege-select-one-action.h b/src/ege-select-one-action.h
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef SEEN_EGE_SELECT_ONE_ACTION
+#define SEEN_EGE_SELECT_ONE_ACTION
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is EGE Select One Action.
+ *
+ * The Initial Developer of the Original Code is
+ * Jon A. Cruz.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* Note: this file should be kept compilable as both .cpp and .c */
+
+#include <glib.h>
+#include <gtk/gtkaction.h>
+#include <gtk/gtktreemodel.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+
+#define EGE_SELECT_ONE_ACTION_TYPE ( ege_select_one_action_get_type() )
+#define EGE_SELECT_ONE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneAction) )
+#define EGE_SELECT_ONE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionClass) )
+#define IS_EGE_SELECT_ONE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_SELECT_ONE_ACTION_TYPE) )
+#define IS_EGE_SELECT_ONE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_SELECT_ONE_ACTION_TYPE) )
+#define EGE_SELECT_ONE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_SELECT_ONE_ACTION_TYPE, EgeSelectOneActionClass) )
+
+typedef struct _EgeSelectOneAction EgeSelectOneAction;
+typedef struct _EgeSelectOneActionClass EgeSelectOneActionClass;
+typedef struct _EgeSelectOneActionPrivate EgeSelectOneActionPrivate;
+
+struct _EgeSelectOneAction
+{
+ GtkAction action;
+ EgeSelectOneActionPrivate *private_data;
+};
+
+struct _EgeSelectOneActionClass
+{
+ GtkActionClass parent_class;
+ void (*changed) (EgeSelectOneAction* action);
+};
+
+GType ege_select_one_action_get_type( void );
+
+EgeSelectOneAction* ege_select_one_action_new( const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id,
+ GtkTreeModel* model );
+
+gint ege_select_one_action_get_active( EgeSelectOneAction* action );
+void ege_select_one_action_set_active( EgeSelectOneAction* action, gint val );
+
+gint ege_select_one_action_get_label_column( EgeSelectOneAction* action );
+void ege_select_one_action_set_label_column( EgeSelectOneAction* action, gint col );
+
+G_END_DECLS
+
+#endif /* SEEN_EGE_SELECT_ONE_ACTION */
index 9f061c090f3d41e191d73de01d91e54eea81ac68..f781332d00ebfe37d63fe30e15738be008ff50dd 100644 (file)
helper/stlport.h \
helper/unit-menu.cpp \
helper/unit-menu.h \
+ helper/unit-tracker.cpp \
+ helper/unit-tracker.h \
helper/units.cpp \
helper/units.h \
helper/window.cpp \
diff --git a/src/helper/unit-tracker.cpp b/src/helper/unit-tracker.cpp
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Inkscape::UnitTracker - Simple mediator to synchronize changes to a set
+ * of possible units
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtk/gtkliststore.h>
+
+#include "unit-tracker.h"
+#include "ege-select-one-action.h"
+
+namespace Inkscape {
+
+enum {
+ COLUMN_STRING,
+ COLUMN_SPUNIT,
+ N_COLUMNS
+};
+
+UnitTracker::UnitTracker( guint bases ) :
+ _active(0),
+ _isUpdating(false),
+ _activeUnit(0),
+ _store(0),
+ _unitList(0),
+ _actionList(0),
+ _adjList(0),
+ _priorValues()
+{
+ _store = gtk_list_store_new( N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER );
+ setBase( bases );
+}
+
+UnitTracker::~UnitTracker()
+{
+ if ( _unitList ) {
+ sp_unit_free_list( _unitList );
+ }
+
+ // Unhook weak references to GtkActions
+ while ( _actionList ) {
+ g_signal_handlers_disconnect_by_func( G_OBJECT(_actionList->data), (gpointer)_unitChangedCB, this );
+ g_object_weak_unref( G_OBJECT(_actionList->data), _actionFinalizedCB, this );
+ _actionList = g_slist_delete_link( _actionList, _actionList );
+ }
+
+ // Unhook wek references to GtkAdjustments
+ while ( _adjList ) {
+ g_object_weak_unref( G_OBJECT(_adjList->data), _adjustmentFinalizedCB, this );
+ _adjList = g_slist_delete_link( _adjList, _adjList );
+ }
+}
+
+void UnitTracker::setBase( guint bases )
+{
+ GtkTreeIter iter;
+ _unitList = sp_unit_get_list( bases );
+ for ( GSList* cur = _unitList; cur; cur = g_slist_next(cur) ) {
+ SPUnit* unit = static_cast<SPUnit*>(cur->data);
+ gtk_list_store_append( _store, &iter );
+ gtk_list_store_set( _store, &iter, COLUMN_STRING, unit->abbr, COLUMN_SPUNIT, unit, -1 );
+ }
+ gint count = gtk_tree_model_iter_n_children( GTK_TREE_MODEL(_store), 0 );
+ if ( (count > 0) && (_active > count) ) {
+ _setActive( count - 1 );
+ }
+}
+
+void UnitTracker::addUnit( SPUnitId id, gint index )
+{
+ GtkTreeIter iter;
+ const SPUnit* percentUnit = &sp_unit_get_by_id( id );
+ gtk_list_store_insert( _store, &iter, index );
+ gtk_list_store_set( _store, &iter, COLUMN_STRING, percentUnit->abbr, COLUMN_SPUNIT, percentUnit, -1 );
+}
+
+bool UnitTracker::isUpdating() const
+{
+ return _isUpdating;
+}
+
+SPUnit const* UnitTracker::getActiveUnit() const
+{
+ return _activeUnit;
+}
+
+void UnitTracker::setActiveUnit( SPUnit const *unit )
+{
+ if ( unit ) {
+ GtkTreeIter iter;
+ int index = 0;
+ gboolean found = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(_store), &iter );
+ while ( found ) {
+ SPUnit* storedUnit = 0;
+ gtk_tree_model_get( GTK_TREE_MODEL(_store), &iter, COLUMN_SPUNIT, &storedUnit, -1 );
+ if ( storedUnit && (storedUnit->unit_id == unit->unit_id) ) {
+ _setActive(index);
+ break;
+ }
+
+ found = gtk_tree_model_iter_next( GTK_TREE_MODEL(_store), &iter );
+ index++;
+ }
+ }
+}
+
+void UnitTracker::addAdjustment( GtkAdjustment* adj )
+{
+ if ( !g_slist_find( _adjList, adj ) ) {
+ g_object_weak_ref( G_OBJECT(adj), _adjustmentFinalizedCB, this );
+ _adjList = g_slist_append( _adjList, adj );
+ }
+}
+
+void UnitTracker::setFullVal( GtkAdjustment* adj, gdouble val )
+{
+ _priorValues[adj] = val;
+}
+
+GtkAction* UnitTracker::createAction( gchar const* name, gchar const* label, gchar const* tooltip )
+{
+ EgeSelectOneAction* act1 = ege_select_one_action_new( name, label, tooltip, NULL, GTK_TREE_MODEL(_store) );
+ ege_select_one_action_set_label_column( act1, COLUMN_STRING );
+ if ( _active ) {
+ ege_select_one_action_set_active( act1, _active );
+ }
+
+ g_object_weak_ref( G_OBJECT(act1), _actionFinalizedCB, this );
+ g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK( _unitChangedCB ), this );
+ _actionList = g_slist_append( _actionList, act1 );
+
+ return GTK_ACTION(act1);
+}
+
+void UnitTracker::_unitChangedCB( GtkAction* action, gpointer data )
+{
+ if ( action && data ) {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION(action);
+ gint active = ege_select_one_action_get_active( act );
+ UnitTracker* self = reinterpret_cast<UnitTracker*>(data);
+ self->_setActive(active);
+ }
+}
+
+void UnitTracker::_actionFinalizedCB( gpointer data, GObject *where_the_object_was )
+{
+ if ( data && where_the_object_was ) {
+ UnitTracker* self = reinterpret_cast<UnitTracker*>(data);
+ self->_actionFinalized( where_the_object_was );
+ }
+}
+
+void UnitTracker::_adjustmentFinalizedCB( gpointer data, GObject *where_the_object_was )
+{
+ if ( data && where_the_object_was ) {
+ UnitTracker* self = reinterpret_cast<UnitTracker*>(data);
+ self->_adjustmentFinalized( where_the_object_was );
+ }
+}
+
+void UnitTracker::_actionFinalized( GObject *where_the_object_was )
+{
+ GSList* target = g_slist_find( _actionList, where_the_object_was );
+ if ( target ) {
+ _actionList = g_slist_remove( _actionList, where_the_object_was );
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was );
+ }
+}
+
+void UnitTracker::_adjustmentFinalized( GObject *where_the_object_was )
+{
+ GSList* target = g_slist_find( _adjList, where_the_object_was );
+ if ( target ) {
+ _adjList = g_slist_remove( _adjList, where_the_object_was );
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was );
+ }
+}
+
+void UnitTracker::_setActive( gint active )
+{
+ if ( active != _active ) {
+ gint oldActive = _active;
+
+ GtkTreeIter iter;
+ gboolean found = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(_store), &iter, NULL, oldActive );
+ if ( found ) {
+ SPUnit* unit = 0;
+ gtk_tree_model_get( GTK_TREE_MODEL(_store), &iter, COLUMN_SPUNIT, &unit, -1 );
+
+ found = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(_store), &iter, NULL, active );
+ if ( found ) {
+ SPUnit* newUnit = 0;
+ gtk_tree_model_get( GTK_TREE_MODEL(_store), &iter, COLUMN_SPUNIT, &newUnit, -1 );
+ _activeUnit = newUnit;
+
+ if ( _adjList ) {
+ _fixupAdjustments( unit, newUnit );
+ }
+
+ } else {
+ g_warning("Did not find new unit");
+ }
+ } else {
+ g_warning("Did not find old unit");
+ }
+
+ _active = active;
+
+ for ( GSList* cur = _actionList; cur; cur = g_slist_next(cur) ) {
+ if ( IS_EGE_SELECT_ONE_ACTION( cur->data ) ) {
+ EgeSelectOneAction* act = EGE_SELECT_ONE_ACTION( cur->data );
+ ege_select_one_action_set_active( act, active );
+ }
+ }
+ }
+}
+
+void UnitTracker::_fixupAdjustments( SPUnit const* oldUnit, SPUnit const *newUnit )
+{
+ _isUpdating = true;
+ for ( GSList* cur = _adjList; cur; cur = g_slist_next(cur) ) {
+ GtkAdjustment* adj = GTK_ADJUSTMENT(cur->data);
+ gdouble oldVal = gtk_adjustment_get_value(adj);
+ gdouble val = oldVal;
+
+ if ((oldUnit->base == SP_UNIT_ABSOLUTE || oldUnit->base == SP_UNIT_DEVICE)
+ && (newUnit->base == SP_UNIT_DIMENSIONLESS))
+ {
+ val = 1.0 / newUnit->unittobase;
+ _priorValues[adj] = sp_units_get_pixels( oldVal, *oldUnit );
+ } else if ((oldUnit->base == SP_UNIT_DIMENSIONLESS)
+ && (newUnit->base == SP_UNIT_ABSOLUTE || newUnit->base == SP_UNIT_DEVICE)) {
+ if ( _priorValues.find(adj) != _priorValues.end() ) {
+ val = sp_pixels_get_units( _priorValues[adj], *newUnit );
+ }
+ } else {
+ val = sp_convert_distance_full( oldVal, *oldUnit, *newUnit );
+ }
+
+ gtk_adjustment_set_value( adj, val );
+ }
+ _isUpdating = false;
+}
+
+}
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/helper/unit-tracker.h b/src/helper/unit-tracker.h
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Inkscape::UnitTracker - Simple mediator to synchronize changes to a set
+ * of possible units
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_INKSCAPE_UNIT_TRACKER_H
+#define SEEN_INKSCAPE_UNIT_TRACKER_H
+
+#include <map>
+
+#include <gtk/gtkaction.h>
+
+#include "helper/units.h"
+
+namespace Inkscape {
+
+class UnitTracker
+{
+public:
+ UnitTracker( guint bases = (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE) );
+ ~UnitTracker();
+
+ void setBase( guint bases ); // SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE
+ void addUnit( SPUnitId id, gint index );
+
+ bool isUpdating() const;
+
+ void setActiveUnit( SPUnit const *unit );
+ SPUnit const* getActiveUnit() const;
+
+ void addAdjustment( GtkAdjustment* adj );
+ void setFullVal( GtkAdjustment* adj, gdouble val );
+
+ GtkAction* createAction( gchar const* name, gchar const* label, gchar const* tooltip );
+
+private:
+ static void _unitChangedCB( GtkAction* action, gpointer data );
+ static void _actionFinalizedCB( gpointer data, GObject *where_the_object_was );
+ static void _adjustmentFinalizedCB( gpointer data, GObject *where_the_object_was );
+ void _setActive( gint index );
+ void _fixupAdjustments( SPUnit const* oldUnit, SPUnit const *newUnit );
+ void _actionFinalized( GObject *where_the_object_was );
+ void _adjustmentFinalized( GObject *where_the_object_was );
+
+ gint _active;
+ bool _isUpdating;
+ SPUnit* _activeUnit;
+ GtkListStore* _store;
+ GSList* _unitList;
+ GSList* _actionList;
+ GSList* _adjList;
+ std::map <GtkAdjustment*, gdouble> _priorValues;
+};
+
+}
+
+#endif // SEEN_INKSCAPE_UNIT_TRACKER_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 0d64409cc1ec959fba58b8d7ef4d63f528c58b02..30ce00ca214f210a529142aa0c950b0c1688b758 100644 (file)
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
+ * Jon A. Cruz <jon@joncruz.org>
*
* Copyright (C) 2003-2005 authors
*
#endif
#include <gtk/gtk.h>
+#include <gtk/gtkaction.h>
#include "widgets/button.h"
#include "widgets/spw-utilities.h"
#include "sp-item-transform.h"
#include "message-stack.h"
#include "display/sp-canvas.h"
+#include "ege-select-one-action.h"
+#include "helper/unit-tracker.h"
+
+using Inkscape::UnitTracker;
static void
sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel)
if ( sel && !sel->isEmpty() ) {
NR::Maybe<NR::Rect> const bbox(sel->bounds());
if ( bbox && !bbox->isEmpty() ) {
- GtkWidget *us = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "units");
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
+ UnitTracker *tracker = reinterpret_cast<UnitTracker*>(gtk_object_get_data(GTK_OBJECT(spw), "tracker"));
+ SPUnit const &unit = *tracker->getActiveUnit();
+
+ struct { char const *key; double val; } const keyval[] = {
+ { "X", bbox->min()[X] },
+ { "Y", bbox->min()[Y] },
+ { "width", bbox->extent(X) },
+ { "height", bbox->extent(Y) }
+ };
if (unit.base == SP_UNIT_DIMENSIONLESS) {
- char const * const keys[] = {"X", "Y", "width", "height"};
double const val = 1. / unit.unittobase;
- for (unsigned i = 0; i < G_N_ELEMENTS(keys); ++i) {
- GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keys[i]);
+ for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) {
+ GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keyval[i].key);
gtk_adjustment_set_value(a, val);
+ tracker->setFullVal( a, keyval[i].val );
}
} else {
- struct { char const *key; double val; } const keyval[] = {
- { "X", bbox->min()[X] },
- { "Y", bbox->min()[Y] },
- { "width", bbox->extent(X) },
- { "height", bbox->extent(Y) }
- };
for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) {
GtkAdjustment *a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), keyval[i].key);
gtk_adjustment_set_value(a, sp_pixels_get_units(keyval[i].val, unit));
return;
}
- GtkWidget *us = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(spw), "units");
- SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us));
- if (sp_unit_selector_update_test(SP_UNIT_SELECTOR(us))) {
+ UnitTracker *tracker = reinterpret_cast<UnitTracker*>(gtk_object_get_data(GTK_OBJECT(spw), "tracker"));
+ if ( !tracker || tracker->isUpdating() ) {
/*
* When only units are being changed, don't treat changes
* to adjuster values as object changes.
return;
}
- gdouble x0, y0, x1, y1, xrel, yrel;
- GtkAdjustment *a_w;
- GtkAdjustment *a_h;
+ gdouble x0 = 0;
+ gdouble y0 = 0;
+ gdouble x1 = 0;
+ gdouble y1 = 0;
+ gdouble xrel = 0;
+ gdouble yrel = 0;
+ SPUnit const &unit = *tracker->getActiveUnit();
+
+ GtkAdjustment* a_x = (GtkAdjustment *)gtk_object_get_data( GTK_OBJECT(spw), "X" );
+ GtkAdjustment* a_y = (GtkAdjustment *)gtk_object_get_data( GTK_OBJECT(spw), "Y" );
+ GtkAdjustment* a_w = (GtkAdjustment *)gtk_object_get_data( GTK_OBJECT(spw), "width" );
+ GtkAdjustment* a_h = (GtkAdjustment *)gtk_object_get_data( GTK_OBJECT(spw), "height" );
if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) {
- GtkAdjustment *a;
- a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "X");
- x0 = sp_units_get_pixels (a->value, unit);
- a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "Y");
- y0 = sp_units_get_pixels (a->value, unit);
- a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width");
+ x0 = sp_units_get_pixels (a_x->value, unit);
+ y0 = sp_units_get_pixels (a_y->value, unit);
x1 = x0 + sp_units_get_pixels (a_w->value, unit);
xrel = sp_units_get_pixels (a_w->value, unit) / bbox->extent(NR::X);
- a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height");
y1 = y0 + sp_units_get_pixels (a_h->value, unit);
yrel = sp_units_get_pixels (a_h->value, unit) / bbox->extent(NR::Y);
} else {
- GtkAdjustment *a;
- a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "X");
- double const x0_propn = a->value * unit.unittobase;
+ double const x0_propn = a_x->value * unit.unittobase;
x0 = bbox->min()[NR::X] * x0_propn;
- a = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "Y");
- double const y0_propn = a->value * unit.unittobase;
+ double const y0_propn = a_y->value * unit.unittobase;
y0 = y0_propn * bbox->min()[NR::Y];
- a_w = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "width");
xrel = a_w->value * unit.unittobase;
x1 = x0 + xrel * bbox->extent(NR::X);
- a_h = (GtkAdjustment *) gtk_object_get_data(GTK_OBJECT(spw), "height");
yrel = a_h->value * unit.unittobase;
y1 = y0 + yrel * bbox->extent(NR::Y);
}
// the value was changed by the user, the difference will be at least that much; otherwise it's
// just rounding difference between the spinbox value and actual value, so no action is
// performed
- char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" :
- sh > 5e-4 ? "selector:toolbar:scale:horizontal" :
- mv > 5e-4 ? "selector:toolbar:move:vertical" :
+ char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" :
+ sh > 5e-4 ? "selector:toolbar:scale:horizontal" :
+ mv > 5e-4 ? "selector:toolbar:move:vertical" :
sv > 5e-4 ? "selector:toolbar:scale:vertical" : NULL );
if (actionkey != NULL) {
NR::Matrix scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1);
sp_selection_apply_affine(selection, scaler);
- sp_document_maybe_done (document, actionkey, SP_VERB_CONTEXT_SELECT,
+ sp_document_maybe_done (document, actionkey, SP_VERB_CONTEXT_SELECT,
_("Transform by toolbar"));
// defocus spinbuttons by moving focus to the canvas, unless "stay" is on
}
GtkWidget *
-sp_select_toolbox_spinbutton(gchar *label, gchar *data, float lower_limit, GtkWidget *us, GtkWidget *spw, gchar *tooltip, gboolean altx)
+sp_select_toolbox_spinbutton(gchar *label, gchar *data, float lower_limit, UnitTracker* tracker, GtkWidget *spw, gchar *tooltip, gboolean altx)
{
GtkTooltips *tt = gtk_tooltips_new();
@@ -248,7 +253,9 @@ sp_select_toolbox_spinbutton(gchar *label, gchar *data, float lower_limit, GtkWi
gtk_container_add(GTK_CONTAINER(hb), l);
GtkObject *a = gtk_adjustment_new(0.0, lower_limit, 1e6, SPIN_STEP, SPIN_PAGE_STEP, SPIN_PAGE_STEP);
- sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(us), GTK_ADJUSTMENT(a));
+ if ( tracker ) {
+ tracker->addAdjustment( GTK_ADJUSTMENT(a) );
+ }
gtk_object_set_data(GTK_OBJECT(spw), data, a);
GtkWidget *sb = gtk_spin_button_new(GTK_ADJUSTMENT(a), SPIN_STEP, 3);
@@ -268,79 +275,6 @@ sp_select_toolbox_spinbutton(gchar *label, gchar *data, float lower_limit, GtkWi
return hb;
}
-static gboolean aux_set_unit(SPUnitSelector *,
- SPUnit const *old,
- SPUnit const *new_units,
- GObject *dlg)
-{
- SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
- if (!desktop) {
- return FALSE;
- }
-
- Inkscape::Selection *selection = sp_desktop_selection(desktop);
-
- if (selection->isEmpty())
- return FALSE;
-
- if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE)
- && (new_units->base == SP_UNIT_DIMENSIONLESS))
- {
-
- NR::Maybe<NR::Rect> bbox = selection->bounds();
- if (!bbox) {
- return FALSE;
- }
-
- /* Absolute to percentage */
- g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE));
-
- GtkAdjustment *ax = GTK_ADJUSTMENT(g_object_get_data(dlg, "X"));
- GtkAdjustment *ay = GTK_ADJUSTMENT(g_object_get_data(dlg, "Y"));
- GtkAdjustment *aw = GTK_ADJUSTMENT(g_object_get_data(dlg, "width"));
- GtkAdjustment *ah = GTK_ADJUSTMENT(g_object_get_data(dlg, "height"));
-
- double const x = sp_units_get_pixels (ax->value, *old);
- double const y = sp_units_get_pixels (ay->value, *old);
- double const w = sp_units_get_pixels (aw->value, *old);
- double const h = sp_units_get_pixels (ah->value, *old);
-
- gtk_adjustment_set_value(ax, fabs(bbox->min()[NR::X]) > 1e-6? 100.0 * x / bbox->min()[NR::X] : 100.0);
- gtk_adjustment_set_value(ay, fabs(bbox->min()[NR::Y]) > 1e-6? 100.0 * y / bbox->min()[NR::Y] : 100.0);
- gtk_adjustment_set_value(aw, fabs(bbox->extent(NR::X)) > 1e-6? 100.0 * w / bbox->extent(NR::X) : 100.0);
- gtk_adjustment_set_value(ah, fabs(bbox->extent(NR::Y)) > 1e-6? 100.0 * h / bbox->extent(NR::Y) : 100.0);
-
- g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE));
- return TRUE;
- } else if ((old->base == SP_UNIT_DIMENSIONLESS)
- && (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) {
-
- NR::Maybe<NR::Rect> bbox = selection->bounds();
- if (!bbox) {
- return FALSE;
- }
-
- /* Percentage to absolute */
- g_object_set_data(dlg, "update", GUINT_TO_POINTER(TRUE));
-
- GtkAdjustment *ax = GTK_ADJUSTMENT(g_object_get_data(dlg, "X"));
- GtkAdjustment *ay = GTK_ADJUSTMENT(g_object_get_data(dlg, "Y"));
- GtkAdjustment *aw = GTK_ADJUSTMENT(g_object_get_data(dlg, "width"));
- GtkAdjustment *ah = GTK_ADJUSTMENT(g_object_get_data(dlg, "height"));
-
- gtk_adjustment_set_value(ax, sp_pixels_get_units(0.01 * ax->value * bbox->min()[NR::X], *new_units));
- gtk_adjustment_set_value(ay, sp_pixels_get_units(0.01 * ay->value * bbox->min()[NR::Y], *new_units));
- gtk_adjustment_set_value(aw, sp_pixels_get_units(0.01 * aw->value * bbox->extent(NR::X), *new_units));
- gtk_adjustment_set_value(ah, sp_pixels_get_units(0.01 * ah->value * bbox->extent(NR::Y), *new_units));
-
- g_object_set_data(dlg, "update", GUINT_TO_POINTER(FALSE));
- return TRUE;
- }
-
- return FALSE;
-}
-
// toggle button callbacks and updaters
static void toggle_stroke (GtkWidget *button, gpointer data) {
}
}
+static void destroy_tracker( GtkObject* obj, gpointer /*user_data*/ )
+{
+ UnitTracker *tracker = reinterpret_cast<UnitTracker*>(gtk_object_get_data(obj, "tracker"));
+ if ( tracker ) {
+ delete tracker;
+ gtk_object_set_data( obj, "tracker", 0 );
+ }
+}
+
GtkWidget *
sp_select_toolbox_new(SPDesktop *desktop)
{
gtk_object_set_data(GTK_OBJECT(spw), "frame", vb);
// Create the units menu.
- GtkWidget *us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
- sp_unit_selector_setsize(us, AUX_OPTION_MENU_WIDTH, AUX_OPTION_MENU_HEIGHT);
- sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0);
- sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us), sp_desktop_namedview(desktop)->doc_units);
- g_signal_connect(G_OBJECT(us), "set_unit", G_CALLBACK(aux_set_unit), spw);
+ UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
+ tracker->addUnit( SP_UNIT_PERCENT, 0 );
+ tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units );
+
+ gtk_object_set_data( GTK_OBJECT(spw), "tracker", tracker );
+ g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw );
+
// four spinbuttons
gtk_container_add(GTK_CONTAINER(vb),
- //TRANSLATORS: only translate "string" in "context|string".
+ //TRANSLATORS: only translate "string" in "context|string".
// For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
- sp_select_toolbox_spinbutton(_("select_toolbar|X"), "X", -1e6, us, spw, _("Horizontal coordinate of selection"), TRUE));
+ sp_select_toolbox_spinbutton(_("select_toolbar|X"), "X", -1e6, tracker, spw, _("Horizontal coordinate of selection"), TRUE));
aux_toolbox_space(vb, AUX_BETWEEN_SPINBUTTONS);
gtk_container_add(GTK_CONTAINER(vb),
- //TRANSLATORS: only translate "string" in "context|string".
+ //TRANSLATORS: only translate "string" in "context|string".
// For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
- sp_select_toolbox_spinbutton(_("select_toolbar|Y"), "Y", -1e6, us, spw, _("Vertical coordinate of selection"), FALSE));
+ sp_select_toolbox_spinbutton(_("select_toolbar|Y"), "Y", -1e6, tracker, spw, _("Vertical coordinate of selection"), FALSE));
aux_toolbox_space(vb, AUX_BETWEEN_BUTTON_GROUPS);
gtk_container_add(GTK_CONTAINER(vb),
- //TRANSLATORS: only translate "string" in "context|string".
+ //TRANSLATORS: only translate "string" in "context|string".
// For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
- sp_select_toolbox_spinbutton(_("select_toolbar|W"), "width", 1e-3, us, spw, _("Width of selection"), FALSE));
+ sp_select_toolbox_spinbutton(_("select_toolbar|W"), "width", 1e-3, tracker, spw, _("Width of selection"), FALSE));
// lock toggle
GtkWidget *lockbox = gtk_vbox_new(TRUE, 0);
g_signal_connect_after (G_OBJECT (lock), "clicked", G_CALLBACK (toggle_lock), desktop);
gtk_container_add(GTK_CONTAINER(vb),
- //TRANSLATORS: only translate "string" in "context|string".
+ //TRANSLATORS: only translate "string" in "context|string".
// For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
- sp_select_toolbox_spinbutton(_("select_toolbar|H"), "height", 1e-3, us, spw, _("Height of selection"), FALSE));
+ sp_select_toolbox_spinbutton(_("select_toolbar|H"), "height", 1e-3, tracker, spw, _("Height of selection"), FALSE));
aux_toolbox_space(vb, 2);
// Add the units menu.
- gtk_widget_show(us);
- gtk_container_add(GTK_CONTAINER(vb), us);
- gtk_object_set_data(GTK_OBJECT(spw), "units", us);
+ {
+ GtkAction* act = tracker->createAction( "UnitAction", _("Units"), _("") );
+
+ GtkWidget* normal = gtk_action_create_tool_item( act );
+ gtk_widget_show( normal );
+ gtk_container_add( GTK_CONTAINER(vb), normal );
+ }
// Set font size.
sp_set_font_size_smaller (vb);