From 179fa413b047bede6e32109e2ce82437c5fb8d34 Mon Sep 17 00:00:00 2001 From: MenTaLguY Date: Mon, 16 Jan 2006 02:36:01 +0000 Subject: moving trunk for module inkscape (bzr r1) --- src/widgets/sp-color-notebook.cpp | 625 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 src/widgets/sp-color-notebook.cpp (limited to 'src/widgets/sp-color-notebook.cpp') diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp new file mode 100644 index 000000000..9d92077da --- /dev/null +++ b/src/widgets/sp-color-notebook.cpp @@ -0,0 +1,625 @@ +#define __SP_COLOR_NOTEBOOK_C__ + +/* + * A block of 3 color sliders plus spinbuttons + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * + * This code is in public domain + */ + +#undef SPCS_PREVIEW + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#include "../dialogs/dialog-events.h" +#include "../prefs-utils.h" +#include "sp-color-notebook.h" +#include "spw-utilities.h" + +#include "sp-color-scales.h" +#include "sp-color-wheel-selector.h" + +struct SPColorNotebookTracker { + const gchar* name; + const gchar* className; + GType type; + guint submode; + gboolean enabledFull; + gboolean enabledBrief; + SPColorNotebook *backPointer; +}; + +static void sp_color_notebook_class_init (SPColorNotebookClass *klass); +static void sp_color_notebook_init (SPColorNotebook *slider); +static void sp_color_notebook_destroy (GtkObject *object); + +static void sp_color_notebook_show_all (GtkWidget *widget); +static void sp_color_notebook_hide_all (GtkWidget *widget); + +static SPColorSelectorClass *parent_class; + +#define XPAD 4 +#define YPAD 1 + +GtkType +sp_color_notebook_get_type (void) +{ + static GtkType type = 0; + if (!type) { + GtkTypeInfo info = { + "SPColorNotebook", + sizeof (SPColorNotebook), + sizeof (SPColorNotebookClass), + (GtkClassInitFunc) sp_color_notebook_class_init, + (GtkObjectInitFunc) sp_color_notebook_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (SP_TYPE_COLOR_SELECTOR, &info); + } + return type; +} + +static void +sp_color_notebook_class_init (SPColorNotebookClass *klass) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + SPColorSelectorClass *selector_class; + + object_class = (GtkObjectClass *) klass; + widget_class = (GtkWidgetClass *) klass; + selector_class = SP_COLOR_SELECTOR_CLASS (klass); + + parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); + + object_class->destroy = sp_color_notebook_destroy; + + widget_class->show_all = sp_color_notebook_show_all; + widget_class->hide_all = sp_color_notebook_hide_all; +} + +static void +sp_color_notebook_switch_page(GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + SPColorNotebook *colorbook) +{ + if ( colorbook ) + { + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + nb->switchPage( notebook, page, page_num ); + + // remember the page we seitched to + prefs_set_int_attribute ("colorselector", "page", page_num); + + } +} + +void ColorNotebook::switchPage(GtkNotebook*, + GtkNotebookPage*, + guint page_num) +{ + SPColorSelector* csel; + GtkWidget* widget; + + if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) >= 0 ) + { + csel = getCurrentSelector(); + csel->base->getColorAlpha(_color, &_alpha); + } + widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), page_num); + if ( widget && SP_IS_COLOR_SELECTOR (widget) ) + { + csel = SP_COLOR_SELECTOR (widget); + csel->base->setColorAlpha( _color, _alpha ); + + // Temporary workaround to undo a spurious GRABBED + _released(); + } +} + +static gint sp_color_notebook_menu_handler( GtkWidget *widget, GdkEvent *event ) +{ + if (event->type == GDK_BUTTON_PRESS) + { + SPColorSelector* csel = SP_COLOR_SELECTOR(widget); + ((ColorNotebook*)(csel->base))->menuHandler( event ); + + /* Tell calling code that we have handled this event; the buck + * stops here. */ + return TRUE; + } + + /* Tell calling code that we have not handled this event; pass it on. */ + return FALSE; +} + +gint ColorNotebook::menuHandler( GdkEvent* event ) +{ + GdkEventButton *bevent = (GdkEventButton *) event; + gtk_menu_popup (GTK_MENU( _popup ), NULL, NULL, NULL, NULL, + bevent->button, bevent->time); + return TRUE; +} + +static void sp_color_notebook_menuitem_response (GtkMenuItem *menuitem, gpointer user_data) +{ + gboolean active = FALSE; + + active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)); + SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (user_data); + if ( entry ) + { + if ( active ) + { + ((ColorNotebook*)(SP_COLOR_SELECTOR(entry->backPointer)->base))->addPage(entry->type, entry->submode); + } + else + { + ((ColorNotebook*)(SP_COLOR_SELECTOR(entry->backPointer)->base))->removePage(entry->type, entry->submode); + } + } +} + +static void +sp_color_notebook_init (SPColorNotebook *colorbook) +{ + SP_COLOR_SELECTOR(colorbook)->base = new ColorNotebook( SP_COLOR_SELECTOR(colorbook) ); + + if ( SP_COLOR_SELECTOR(colorbook)->base ) + { + SP_COLOR_SELECTOR(colorbook)->base->init(); + } +} + +void ColorNotebook::init() +{ + GtkWidget* table = 0; + guint row = 0; + guint i = 0; + guint j = 0; + GType *selector_types = 0; + guint selector_type_count = 0; + + GtkTooltips *tt = gtk_tooltips_new (); + + /* tempory hardcoding to get types loaded */ + SP_TYPE_COLOR_SCALES; + SP_TYPE_COLOR_WHEEL_SELECTOR; + + /* REJON: Comment out the next line to not use the normal GTK Color + wheel. */ + +// SP_TYPE_COLOR_GTKSELECTOR; + + _updating = FALSE; + _updatingrgba = FALSE; + _btn = 0; + _popup = 0; + _trackerList = g_ptr_array_new (); + + _book = gtk_notebook_new (); + gtk_widget_show (_book); + + selector_types = g_type_children (SP_TYPE_COLOR_SELECTOR, &selector_type_count); + + for ( i = 0; i < selector_type_count; i++ ) + { + if (!g_type_is_a (selector_types[i], SP_TYPE_COLOR_NOTEBOOK)) + { + guint howmany = 1; + gpointer klass = gtk_type_class (selector_types[i]); + if ( klass && SP_IS_COLOR_SELECTOR_CLASS (klass) ) + { + SPColorSelectorClass *ck = SP_COLOR_SELECTOR_CLASS (klass); + howmany = MAX (1, ck->submode_count); + for ( j = 0; j < howmany; j++ ) + { + SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (malloc(sizeof(SPColorNotebookTracker))); + if ( entry ) + { + memset( entry, 0, sizeof(SPColorNotebookTracker) ); + entry->name = ck->name[j]; + entry->type = selector_types[i]; + entry->submode = j; + entry->enabledFull = TRUE; + entry->enabledBrief = TRUE; + entry->backPointer = SP_COLOR_NOTEBOOK(_csel); + + g_ptr_array_add (_trackerList, entry); + } + } + } + } + } + + for ( i = 0; i < _trackerList->len; i++ ) + { + SPColorNotebookTracker *entry = + reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i)); + if ( entry ) + { + addPage(entry->type, entry->submode); + } + } + + table = gtk_table_new (2, 3, FALSE); + gtk_widget_show (table); + + gtk_box_pack_start (GTK_BOX (_csel), table, TRUE, TRUE, 0); + + gtk_table_attach (GTK_TABLE (table), _book, 0, 2, row, row + 1, + static_cast(GTK_EXPAND|GTK_FILL), + static_cast(GTK_EXPAND|GTK_FILL), + XPAD, YPAD); + + // restore the last active page + gtk_notebook_set_current_page (GTK_NOTEBOOK (_book), prefs_get_int_attribute ("colorselector", "page", 0)); + + { + gboolean found = FALSE; + + _popup = gtk_menu_new(); + GtkMenu *menu = GTK_MENU (_popup); + + for ( i = 0; i < _trackerList->len; i++ ) + { + SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i)); + if ( entry ) + { + GtkWidget *item = gtk_check_menu_item_new_with_label (_(entry->name)); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), entry->enabledFull); + gtk_widget_show (item); + gtk_menu_append (menu, item); + + g_signal_connect (G_OBJECT (item), "activate", + G_CALLBACK (sp_color_notebook_menuitem_response), + reinterpret_cast< gpointer > (entry) ); + found = TRUE; + } + } + + GtkWidget *arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE); + gtk_widget_show (arrow); + + _btn = gtk_button_new (); + gtk_widget_show (_btn); + gtk_container_add (GTK_CONTAINER (_btn), arrow); + + GtkWidget *align = gtk_alignment_new (1.0, 0.0, 0.0, 0.0); + gtk_widget_show (align); + gtk_container_add (GTK_CONTAINER (align), _btn); + + // uncomment to reenable the "show/hide modes" menu, + // but first fix it so it remembers its settings in prefs and does not take that much space (entire vertical column!) + //gtk_table_attach (GTK_TABLE (table), align, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); + + gtk_signal_connect_object(GTK_OBJECT(_btn), "event", GTK_SIGNAL_FUNC (sp_color_notebook_menu_handler), GTK_OBJECT(_csel)); + if ( !found ) + { + gtk_widget_set_sensitive (_btn, FALSE); + } + } + + row++; + + /* Create RGBA entry and color preview */ + GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0); + + _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:")); + gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5); + gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2); + + _rgbae = gtk_entry_new (); + sp_dialog_defocus_on_enter (_rgbae); + gtk_entry_set_max_length (GTK_ENTRY (_rgbae), 8); + gtk_entry_set_width_chars (GTK_ENTRY (_rgbae), 8); + gtk_tooltips_set_tip (tt, _rgbae, _("Hexadecimal RGBA value of the color"), NULL); + gtk_box_pack_start(GTK_BOX(rgbabox), _rgbae, FALSE, FALSE, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL(_rgbal), _rgbae); + + sp_set_font_size_smaller (rgbabox); + gtk_widget_show_all (rgbabox); + gtk_table_attach (GTK_TABLE (table), rgbabox, 1, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD); + +#ifdef SPCS_PREVIEW + _p = sp_color_preview_new (0xffffffff); + gtk_widget_show (_p); + gtk_table_attach (GTK_TABLE (table), _p, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); +#endif + + _switchId = g_signal_connect(GTK_OBJECT (_book), "switch-page", + GTK_SIGNAL_FUNC (sp_color_notebook_switch_page), SP_COLOR_NOTEBOOK(_csel)); + + _entryId = gtk_signal_connect (GTK_OBJECT (_rgbae), "changed", GTK_SIGNAL_FUNC (ColorNotebook::_rgbaEntryChangedHook), _csel); +} + +static void +sp_color_notebook_destroy (GtkObject *object) +{ + if (((GtkObjectClass *) (parent_class))->destroy) + (* ((GtkObjectClass *) (parent_class))->destroy) (object); +} + +ColorNotebook::~ColorNotebook() +{ + if ( _trackerList ) + { + g_ptr_array_free (_trackerList, TRUE); + _trackerList = 0; + } + + if ( _switchId ) + { + if ( _book ) + { + g_signal_handler_disconnect (_book, _switchId); + _switchId = 0; + } + } +} + +static void +sp_color_notebook_show_all (GtkWidget *widget) +{ + gtk_widget_show (widget); +} + +static void +sp_color_notebook_hide_all (GtkWidget *widget) +{ + gtk_widget_hide (widget); +} + +GtkWidget * +sp_color_notebook_new (void) +{ + SPColorNotebook *colorbook; + + colorbook = (SPColorNotebook*)gtk_type_new (SP_TYPE_COLOR_NOTEBOOK); + + return GTK_WIDGET (colorbook); +} + +ColorNotebook::ColorNotebook( SPColorSelector* csel ) + : ColorSelector( csel ) +{ +} + +SPColorSelector* ColorNotebook::getCurrentSelector() +{ + SPColorSelector* csel = NULL; + gint current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)); + + if ( current_page >= 0 ) + { + GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), current_page); + if ( SP_IS_COLOR_SELECTOR (widget) ) + { + csel = SP_COLOR_SELECTOR (widget); + } + } + + return csel; +} + +void ColorNotebook::_colorChanged(const SPColor& color, gfloat alpha) +{ + SPColorSelector* cselPage = 0; + + g_return_if_fail (_csel != NULL); + g_return_if_fail (SP_IS_COLOR_NOTEBOOK (_csel)); + g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); + + cselPage = getCurrentSelector(); + if ( cselPage ) + { + cselPage->base->setColorAlpha( color, alpha ); + } + + _updateRgbaEntry( color, alpha ); +} + +void ColorNotebook::_rgbaEntryChangedHook(GtkEntry *entry, SPColorNotebook *colorbook) +{ + ((ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base))->_rgbaEntryChanged( entry ); +} + +void ColorNotebook::_rgbaEntryChanged(GtkEntry* entry) +{ + const gchar *t; + gchar *e; + SPColor color; + guint rgba; + + if (_updating) return; + if (_updatingrgba) return; + + t = gtk_entry_get_text (entry); + + if (t) { + rgba = strtoul (t, &e, 16); + if ( e != t ) { + ptrdiff_t len=e-t; + if ( len < 8 ) { + rgba = rgba << ( 4 * ( 8 - len ) ); + } + _updatingrgba = TRUE; + sp_color_set_rgb_rgba32 (&color, rgba); + setColorAlpha( color, SP_RGBA32_A_F(rgba), true); + _updatingrgba = FALSE; + } + } +} + +void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) +{ + g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); + + if ( !_updatingrgba ) + { + gchar s[32]; + guint32 rgba; + + /* Update RGBA entry */ + rgba = sp_color_get_rgba32_falpha (&color, alpha); + + g_snprintf (s, 32, "%08x", rgba); + const gchar* oldText = gtk_entry_get_text( GTK_ENTRY( _rgbae ) ); + if ( strcmp( oldText, s ) != 0 ) + { + g_signal_handler_block( _rgbae, _entryId ); + gtk_entry_set_text( GTK_ENTRY(_rgbae), s ); + g_signal_handler_unblock( _rgbae, _entryId ); + } + } +} + +void ColorNotebook::_entryGrabbed (SPColorSelector *, SPColorNotebook *colorbook) +{ + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + nb->_grabbed(); +} + +void ColorNotebook::_entryDragged (SPColorSelector *csel, SPColorNotebook *colorbook) +{ + gboolean oldState; + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + + oldState = nb->_dragging; + + nb->_dragging = TRUE; + nb->_entryModified( csel, colorbook ); + + nb->_dragging = oldState; +} + +void ColorNotebook::_entryReleased (SPColorSelector *, SPColorNotebook *colorbook) +{ + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + nb->_released(); +} + +void ColorNotebook::_entryChanged (SPColorSelector *csel, SPColorNotebook *colorbook) +{ + gboolean oldState; + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + + oldState = nb->_dragging; + + nb->_dragging = FALSE; + nb->_entryModified( csel, colorbook ); + + nb->_dragging = oldState; +} + +void ColorNotebook::_entryModified (SPColorSelector *csel, SPColorNotebook *colorbook) +{ + g_return_if_fail (colorbook != NULL); + g_return_if_fail (SP_IS_COLOR_NOTEBOOK (colorbook)); + g_return_if_fail (csel != NULL); + g_return_if_fail (SP_IS_COLOR_SELECTOR (csel)); + + ColorNotebook* nb = (ColorNotebook*)(SP_COLOR_SELECTOR(colorbook)->base); + SPColor color; + gfloat alpha = 1.0; + + csel->base->getColorAlpha( color, &alpha ); + nb->_updateRgbaEntry( color, alpha ); + nb->_updateInternals( color, alpha, nb->_dragging ); +} + +GtkWidget* ColorNotebook::addPage(GType page_type, guint submode) +{ + GtkWidget *page; + + page = sp_color_selector_new ( page_type, SP_COLORSPACE_TYPE_NONE); + if ( page ) + { + GtkWidget* tab_label = 0; + SPColorSelector* csel; + + csel = SP_COLOR_SELECTOR (page); + if ( submode > 0 ) + { + csel->base->setSubmode( submode ); + } + gtk_widget_show (page); + int index = csel->base ? csel->base->getSubmode() : 0; + const gchar* str = _(SP_COLOR_SELECTOR_GET_CLASS (csel)->name[index]); +// g_message( "Hitting up for tab for '%s'", str ); + tab_label = gtk_label_new(_(str)); + gtk_notebook_append_page( GTK_NOTEBOOK (_book), page, tab_label ); + gtk_signal_connect (GTK_OBJECT (page), "grabbed", GTK_SIGNAL_FUNC (_entryGrabbed), _csel); + gtk_signal_connect (GTK_OBJECT (page), "dragged", GTK_SIGNAL_FUNC (_entryDragged), _csel); + gtk_signal_connect (GTK_OBJECT (page), "released", GTK_SIGNAL_FUNC (_entryReleased), _csel); + gtk_signal_connect (GTK_OBJECT (page), "changed", GTK_SIGNAL_FUNC (_entryChanged), _csel); + } + + return page; +} + +GtkWidget* ColorNotebook::getPage(GType page_type, guint submode) +{ + gint count = 0; + gint i = 0; + GtkWidget* page = 0; + +// count = gtk_notebook_get_n_pages (_book); + count = 200; + for ( i = 0; i < count && !page; i++ ) + { + page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), i); + if ( page ) + { + SPColorSelector* csel; + guint pagemode; + csel = SP_COLOR_SELECTOR (page); + pagemode = csel->base->getSubmode(); + if ( G_TYPE_FROM_INSTANCE (page) == page_type + && pagemode == submode ) + { + // found it. + break; + } + else + { + page = 0; + } + } + else + { + break; + } + } + return page; +} + +void ColorNotebook::removePage( GType page_type, guint submode ) +{ + GtkWidget *page = 0; + + page = getPage(page_type, submode); + if ( page ) + { + gint where = gtk_notebook_page_num (GTK_NOTEBOOK (_book), page); + if ( where >= 0 ) + { + if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) == where ) + { +// getColorAlpha(_color, &_alpha); + } + gtk_notebook_remove_page (GTK_NOTEBOOK (_book), where); + } + } +} -- cgit v1.2.3