diff options
| author | John Smith <john.smith7545@yahoo.com> | 2012-03-12 09:55:25 +0000 |
|---|---|---|
| committer | John Smith <removethis.john.q.public@bigmail.com> | 2012-03-12 09:55:25 +0000 |
| commit | da6b3a2529230d8983fe72e82c919c6fa611695c (patch) | |
| tree | b4f33f45a0172a1146bc00733d88304cf1e97ccc /src/widgets/dash-selector.cpp | |
| parent | Replace deprecated GtkSignal API (diff) | |
| download | inkscape-da6b3a2529230d8983fe72e82c919c6fa611695c.tar.gz inkscape-da6b3a2529230d8983fe72e82c919c6fa611695c.zip | |
Fix for 903671 : GtkOptionMenu needs replacing with GtkComboBox. Fill and Stroke Dashes
(bzr r11072)
Diffstat (limited to 'src/widgets/dash-selector.cpp')
| -rw-r--r-- | src/widgets/dash-selector.cpp | 239 |
1 files changed, 68 insertions, 171 deletions
diff --git a/src/widgets/dash-selector.cpp b/src/widgets/dash-selector.cpp index d30c0c328..7f36b91f5 100644 --- a/src/widgets/dash-selector.cpp +++ b/src/widgets/dash-selector.cpp @@ -1,6 +1,6 @@ /** * @file - * Option menu for selecting dash patterns - implementation. + * Combobox for selecting dash patterns - implementation. */ /* Author: * Lauris Kaplinski <lauris@kaplinski.com> @@ -12,9 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#define DASH_PREVIEW_WIDTH 2 -#define DASH_PREVIEW_LENGTH 80 - #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -24,16 +21,14 @@ #include <cstring> #include <string> #include <glibmm/i18n.h> +#include <gtkmm/adjustment.h> #include <2geom/coord.h> #include "style.h" #include "dialogs/dialog-events.h" #include "preferences.h" - -#include <gtkmm/optionmenu.h> -#include <gtkmm/adjustment.h> #include "ui/widget/spinbutton.h" - +#include "display/cairo-utils.h" gchar const *const SPDashSelector::_prefs_path = "/palette/dashes"; @@ -48,34 +43,40 @@ static double *builtin_dashes[] = {dash_0, dash_1_1, dash_2_1, dash_4_1, dash_1_ static double **dashes = NULL; -static void sp_dash_selector_menu_item_image_realize(Gtk::Image *px, double *pattern); - -SPDashSelector::SPDashSelector() { +SPDashSelector::SPDashSelector() + : preview_width(80), + preview_height(16), + preview_lineheight(2) +{ // TODO: find something more sensible here!! init_dashes(); - dash = new Gtk::OptionMenu(); - dash->set_tooltip_text(_("Dash pattern")); - dash->show(); - this->pack_start(*dash, false, false, 0); + dash_store = Gtk::ListStore::create(dash_columns); + dash_combo.set_model(dash_store); + dash_combo.pack_start(image_renderer); + dash_combo.set_cell_data_func(image_renderer, sigc::mem_fun(*this, &SPDashSelector::prepareImageRenderer)); + dash_combo.set_tooltip_text(_("Dash pattern")); + dash_combo.show(); + dash_combo.signal_changed().connect( sigc::mem_fun(*this, &SPDashSelector::on_selection) ); - Gtk::Menu *m = new Gtk::Menu(); - m->show(); - for (int i = 0; dashes[i]; i++) { - Gtk::MenuItem *mi = menu_item_new(dashes[i]); - mi->show(); - m->append(*mi); - } - dash->set_menu(*m); + this->pack_start(dash_combo, false, false, 0); offset = new Gtk::Adjustment(0.0, 0.0, 10.0, 0.1, 1.0, 0.0); + offset->signal_value_changed().connect(sigc::mem_fun(*this, &SPDashSelector::offset_value_changed)); Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton(*offset, 0.1, 2); sb->set_tooltip_text(_("Pattern offset")); - sp_dialog_defocus_on_enter_cpp(sb); sb->show(); + this->pack_start(*sb, false, false, 0); - offset->signal_value_changed().connect(sigc::mem_fun(*this, &SPDashSelector::offset_value_changed)); + + + for (int i = 0; dashes[i]; i++) { + // Add the dashes to the combobox + Gtk::TreeModel::Row row = *(dash_store->append()); + row[dash_columns.dash] = dashes[i]; + row[dash_columns.pixbuf] = Glib::wrap(sp_dash_to_pixbuf(dashes[i])); + } this->set_data("pattern", dashes[0]); } @@ -83,14 +84,18 @@ SPDashSelector::SPDashSelector() { SPDashSelector::~SPDashSelector() { // FIXME: for some reason this doesn't get called; does the call to manage() in // sp_stroke_style_line_widget_new() not processed correctly? - delete dash; delete offset; } -void -SPDashSelector::init_dashes() { +void SPDashSelector::prepareImageRenderer( Gtk::TreeModel::const_iterator const &row ) { + + Glib::RefPtr<Gdk::Pixbuf> pixbuf = (*row)[dash_columns.pixbuf]; + image_renderer.property_pixbuf() = pixbuf; +} + +void SPDashSelector::init_dashes() { + if (!dashes) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); std::vector<Glib::ustring> dash_prefs = prefs->getAllDirs(_prefs_path); @@ -122,8 +127,7 @@ SPDashSelector::init_dashes() { } } -void -SPDashSelector::set_dash (int ndash, double *dash, double o) +void SPDashSelector::set_dash (int ndash, double *dash, double o) { int pos = 0; if (ndash > 0) { @@ -152,12 +156,11 @@ SPDashSelector::set_dash (int ndash, double *dash, double o) } this->set_data("pattern", dashes[pos]); - this->dash->set_history(pos); + this->dash_combo.set_active(pos); this->offset->set_value(o); } -void -SPDashSelector::get_dash(int *ndash, double **dash, double *off) +void SPDashSelector::get_dash(int *ndash, double **dash, double *off) { double *pattern = (double*) this->get_data("pattern"); @@ -184,152 +187,46 @@ SPDashSelector::get_dash(int *ndash, double **dash, double *off) } } -Gtk::MenuItem * -SPDashSelector::menu_item_new(double *pattern) -{ - Gtk::MenuItem *mi = new Gtk::MenuItem(); - Gtk::Image *px = new Gtk::Image(); - - px->show(); - mi->add(*px); - - mi->set_data("pattern", pattern); - mi->set_data("px", px); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SPDashSelector::dash_activate), mi)); - - px->signal_realize().connect(sigc::bind(sigc::ptr_fun(&sp_dash_selector_menu_item_image_realize), px, pattern)); - - return mi; -} - -static bool -all_even_are_zero (double *pattern, int n) -{ - for (int i = 0; i < n; i += 2) { - if (pattern[i] != 0) - return false; - } - return true; -} - -static bool -all_odd_are_zero (double *pattern, int n) -{ - for (int i = 1; i < n; i += 2) { - if (pattern[i] != 0) - return false; - } - return true; +/** + * Fill a pixbuf with the dash pattern using standard cairo drawing + */ +GdkPixbuf* SPDashSelector::sp_dash_to_pixbuf(double *pattern) { + + int n_dashes; + for (n_dashes = 0; pattern[n_dashes] >= 0.0; n_dashes ++) ; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, preview_width, preview_height); + cairo_t *ct = cairo_create(s); + + cairo_set_line_width (ct, preview_lineheight); + cairo_scale (ct, preview_lineheight, 1); + //cairo_set_source_rgb (ct, 0, 0, 0); + cairo_move_to (ct, 0, preview_height/2); + cairo_line_to (ct, preview_width, preview_height/2); + cairo_set_dash(ct, pattern, n_dashes, 0); + cairo_stroke (ct); + + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), + GDK_COLORSPACE_RGB, TRUE, 8, + preview_width, preview_height, cairo_image_surface_get_stride(s), + ink_cairo_pixbuf_cleanup, s); + convert_pixbuf_argb32_to_normal(pixbuf); + return pixbuf; } -static void sp_dash_selector_menu_item_image_realize(Gtk::Image *px, double *pattern) { - Glib::RefPtr<Gdk::Pixmap> pixmap = Gdk::Pixmap::create(px->get_window(), DASH_PREVIEW_LENGTH + 4, 16, -1); - Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create(pixmap); - - gc->set_rgb_fg_color(Gdk::Color("#ffffff")); - pixmap->draw_rectangle(gc, true, 0, 0, DASH_PREVIEW_LENGTH + 4, 16); - - // FIXME: all of the below twibblering is due to the limitations of gdk_gc_set_dashes (only integers, no zeroes). - // Perhaps would make sense to rework this with manually drawn dashes. - - // Fill in the integer array of pixel-lengths, for display - gint8 pixels_i[64]; - gdouble pixels_d[64]; - int n_source_dashes = 0; - int n_pixel_dashes = 0; - - signed int i_s, i_p; - for (i_s = 0, i_p = 0; pattern[i_s] >= 0.0; i_s ++, i_p ++) { - pixels_d[i_p] = 0.0; - } - - n_source_dashes = i_s; - - for (i_s = 0, i_p = 0; i_s < n_source_dashes; i_s ++, i_p ++) { - // calculate the pixel length corresponding to the current dash - gdouble pixels = DASH_PREVIEW_WIDTH * pattern[i_s]; - - if (pixels > 0.0) - pixels_d [i_p] += pixels; - else { - if (i_p >= 1) { - // dash is zero, skip this element in the array, and set pointer backwards - // so the next dash is added to the previous - i_p -= 2; - } else { - // the first dash is zero; bad luck, gdk cannot start pattern with non-stroke, so we - // put a 1-pixel stub here (it may turn out not shown, though, see special cases below) - pixels_d [i_p] = 1.0; - } - } - } - - n_pixel_dashes = i_p; - gdouble longest_dash = 0.0; - - // after summation, convert double dash lengths to ints - for (i_p = 0; i_p < n_pixel_dashes; i_p ++) { - pixels_i [i_p] = (gint8) (pixels_d [i_p] + 0.5); - // zero-length dashes are already eliminated, so the <1 dash is short but not zero; - // we approximate it with a one-pixel mark - if (pixels_i [i_p] < 1) - pixels_i [i_p] = 1; - if (i_p % 2 == 0) { // it's a dash - if (pixels_d [i_p] > longest_dash) - longest_dash = pixels_d [i_p]; - } - } - - Gdk::Color color; - if (longest_dash > 1e-18 && longest_dash < 0.5) { - // fake "shortening" of one-pixel marks by painting them lighter-than-black - gint rgb = 0xffff - (gint) (0xffff * longest_dash / 0.5); - color.set_rgb(rgb, rgb, rgb); - gc->set_rgb_fg_color(color); - } else { - color.set_rgb(0, 0, 0); - gc->set_rgb_fg_color(color); - } - - if (n_source_dashes > 0) { - // special cases: - if (all_even_are_zero (pattern, n_source_dashes)) { - ; // do not draw anything, only gaps are non-zero - } else if (all_odd_are_zero (pattern, n_source_dashes)) { - // draw solid line, only dashes are non-zero - gc->set_line_attributes(DASH_PREVIEW_WIDTH, - Gdk::LINE_SOLID, Gdk::CAP_BUTT, - Gdk::JOIN_MITER); - pixmap->draw_line(gc, 4, 8, DASH_PREVIEW_LENGTH, 8); - } else { - // regular pattern with both gaps and dashes non-zero - gc->set_line_attributes(DASH_PREVIEW_WIDTH, Gdk::LINE_ON_OFF_DASH, Gdk::CAP_BUTT, Gdk::JOIN_MITER); - gc->set_dashes(0, pixels_i, n_pixel_dashes); - pixmap->draw_line(gc, 4, 8, DASH_PREVIEW_LENGTH, 8); - } - } else { - // no pattern, draw solid line - gc->set_line_attributes(DASH_PREVIEW_WIDTH, Gdk::LINE_SOLID, Gdk::CAP_BUTT, Gdk::JOIN_MITER); - pixmap->draw_line(gc, 4, 8, DASH_PREVIEW_LENGTH, 8); - } - - Glib::RefPtr<Gdk::Bitmap> null_ptr; - px->set(pixmap, null_ptr); -} - -void -SPDashSelector::dash_activate (Gtk::MenuItem *mi) +void SPDashSelector::on_selection () { - double *pattern = (double*) mi->get_data("pattern"); + double *pattern = dash_combo.get_active()->get_value(dash_columns.dash); this->set_data ("pattern", pattern); changed_signal.emit(); } - -void -SPDashSelector::offset_value_changed() +void SPDashSelector::offset_value_changed() { changed_signal.emit(); } |
