From e4c269f5d435d2227fc148f27c457f2426e018e3 Mon Sep 17 00:00:00 2001 From: paolo Date: Fri, 18 Aug 2006 19:54:24 +0000 Subject: [PATCH] - modified cairo_widget and simulation_widget to support scaling git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@908 3ecf2c5c-341e-0410-92b4-d18e462d057c --- src/cairo_widget.cc | 173 +++++++++++---------------------------- src/cairo_widget.hh | 8 +- src/gui_builder.cc | 4 +- src/simulation_widget.cc | 45 +++++++--- src/simulation_widget.hh | 5 +- 5 files changed, 93 insertions(+), 142 deletions(-) diff --git a/src/cairo_widget.cc b/src/cairo_widget.cc index f3f51cd..fb4a387 100644 --- a/src/cairo_widget.cc +++ b/src/cairo_widget.cc @@ -19,23 +19,13 @@ // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -/* - the widget's event sequence... - - on_size_request, requisition->width : 0, requisition->height : 0 - on_realize, alloc.get_width() : 673, alloc.get_height() : 485 - on_expose_event START... on_expose_event CONTINUE. - on_size_request, requisition->width : 120, requisition->height : 120 - on_expose_event START... on_expose_event CONTINUE. - on_expose_event START... on_expose_event CONTINUE. - et cetera... -*/ #include "cairo_elements.hh" #include "cairo_widget.hh" #include + #include #include #include @@ -45,7 +35,8 @@ using namespace sgpem; CairoWidget::CairoWidget() : Glib::ObjectBase("sgpem_CairoWidget"), - Gtk::Widget(), _draw_w(1), _draw_h(1), _buf(NULL), + Gtk::Widget(), + _draw_w(1), _draw_h(1), _buf(NULL), _client_w(0), _client_h(0), _pixmap_w(0), _pixmap_h(0), _need_redraw(true), _scaling_mode(scaling_none) { @@ -62,35 +53,6 @@ CairoWidget::set_scaling_mode(CairoWidget::scaling_mode scaling) { CairoWidget::scaling_mode old_scaling = _scaling_mode; _scaling_mode = scaling; - /* - if(_scaling_mode==scaling_none) - set_size_request(_draw_w, _draw_h); - else - set_size_request(_client_w, _client_h); - */ - - switch(_scaling_mode) - { - case scaling_none: - set_size_request(100, 100); - break; - case scaling_to_w: - set_size_request(150, 150); - break; - case scaling_to_h: - set_size_request(200, 200); - break; - case scaling_min: - set_size_request(250, 250); - break; - case scaling_max: - set_size_request(300, 300); - break; - case scaling_all: - set_size_request(350, 350); - break; - } - return old_scaling; } @@ -100,11 +62,10 @@ CairoWidget::get_scaling_mode() return _scaling_mode; } - void CairoWidget::on_realize() { - std::cout << " on_realize" << std::endl; + // std::cout << " on_realize" << std::endl; if (is_realized()) return; Gtk::Widget::on_realize(); @@ -120,7 +81,7 @@ CairoWidget::on_realize() attributes.width = alloc.get_width(); attributes.height = alloc.get_height(); attributes.wclass = GDK_INPUT_OUTPUT; - attributes.event_mask = get_events() | GDK_EXPOSURE_MASK; + attributes.event_mask = get_events() | GDK_EXPOSURE_MASK | GDK_ALL_EVENTS_MASK; attributes.window_type = GDK_WINDOW_CHILD; attributes.visual = get_visual()->gobj(); attributes.colormap = get_colormap()->gobj(); @@ -128,8 +89,8 @@ CairoWidget::on_realize() _client_w = alloc.get_width(); _client_h = alloc.get_height(); - std::cout << " on_realize, alloc.get_width() : " << alloc.get_width() << ", alloc.get_height() : " << alloc.get_height() << std::endl; - + // std::cout << " on_realize, alloc.get_width() : " << alloc.get_width() << ", alloc.get_height() : " << alloc.get_height() << std::endl; + static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y | Gdk::WA_WMCLASS | Gdk::WA_VISUAL | Gdk::WA_COLORMAP; @@ -146,11 +107,10 @@ CairoWidget::on_realize() get_style()->set_background(window, Gtk::STATE_ACTIVE); } - void CairoWidget::on_size_allocate(const Gtk::Allocation& allocation) { - std::cout << " on_size_allocate, allocation.get_width() : " << allocation.get_width() << ", allocation.get_height() : " << allocation.get_height() << std::endl; + // std::cout << " on_size_allocate, allocation.get_width() : " << allocation.get_width() << ", allocation.get_height() : " << allocation.get_height() << std::endl; set_allocation(allocation); if (is_realized()) @@ -169,68 +129,59 @@ CairoWidget::on_size_request(Gtk::Requisition* requisition) { // Gtk+ asks the desired widget dimension - std::cout << " on_size_request, requisition->width : " << requisition->width << ", requisition->height : " << requisition->height << std::endl; - // the response is - what allocated before... - /* - switch(_scaling_mode) - { - case scaling_none: - *requisition = Gtk::Requisition(); - requisition->width = _draw_w; - requisition->height = _draw_h; - break; - case scaling_to_w: - case scaling_to_h: - case scaling_min: - case scaling_max: - case scaling_all: - Glib::RefPtrparent_w = get_parent_window(); - if(parent_w) - { - int w, h; - parent_w->get_size(w, h); - requisition->width = w; - requisition->height = h; - } - break; - } - */ + // std::cout << " on_size_request, requisition->width : " << requisition->width << ", requisition->height : " << requisition->height << std::endl; + calc_widget_size(_client_w, _client_h); + requisition->width = _client_w; + requisition->height = _client_h; + } bool CairoWidget::on_expose_event(GdkEventExpose* event) { - std::cout << " on_expose_event START..."; + // std::cout << " on_expose_event START..."; if (event == NULL || event->count > 0) return false; - std::cout << " on_expose_event CONTINUE." << std::endl; + // std::cout << " on_expose_event CONTINUE." << std::endl; + + int actual_w = get_width(); + int actual_h = get_height(); + + // std::cout << " get_width() : " << actual_w << ", get_height() : " << actual_h << std::endl; + // std::cout << " _client_w : " << _client_w << ", _client_h : " << _client_h << std::endl; + // std::cout << " _pixmap_w : " << _pixmap_w << ", _pixmap_h : " << _pixmap_h << std::endl; - if(_need_redraw) + if(_need_redraw || actual_w!=_client_w || actual_h!=_client_h) { _need_redraw = false; + _client_w = actual_w; + _client_h = actual_h; + // lazy technique: allocate only if growing... if(_client_w>_pixmap_w || _client_h>_pixmap_h) { - std::cout << " on_expose_event CREATE Pixmap." << std::endl; - _buf = Gdk::Pixmap::create(get_window(), _client_w, _client_h); - _pixmap_w = _client_w; - _pixmap_h = _client_h; + // previdence in the code: allocate more than actually needed + _pixmap_w = (size_t) (_client_w*1.2); + _pixmap_h = (size_t) (_client_h*1.2); + std::cout << " on_expose_event CREATE Pixmap. w : " << _pixmap_w << ", h : " << _pixmap_h<< std::endl; + _buf = Gdk::Pixmap::create(get_window(), _pixmap_w, _pixmap_h); } // Draw the widget background as the first thing. // I've seen this is how it's done in the very Gtk+ toolkit // for the GtkProgressBar widget. GtkStyle* gStyle = get_style()->gobj(); - std::cout << " on_expose_event gtk_paint_box." << std::endl; + // std::cout << " on_expose_event gtk_paint_box." << std::endl; gtk_paint_box(gStyle, _buf->gobj(), GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_IN, - NULL, this->gobj(), "through", + NULL, (GtkWidget*)this->gobj(), "through", 0, 0, _client_w, _client_h); cairo_t* ctx = gdk_cairo_create(_buf->gobj()); // Determine the final drawing dimensions before to start drawing - calc_size(_draw_w, _draw_h); + _draw_w = _draw_h = 0; // default no scaling + calc_drawing_size(_draw_w, _draw_h); // do the drawing... if(_scaling_mode!=scaling_none && _draw_w>0 && _draw_h>0) { @@ -265,7 +216,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event) } cairo_scale(ctx, sx, sy); } - std::cout << " on_expose_event Dimensions, w : " << _draw_w << ", h : " << _draw_h << std::endl; + // std::cout << " on_expose_event Dimensions, w : " << _draw_w << ", h : " << _draw_h << std::endl; draw_widget(ctx); cairo_destroy(ctx); } @@ -287,10 +238,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event) bool CairoWidget::on_button_press_event(GdkEventButton* event) { - std::cout << " on_button_press_event " << std::endl; - change_scaling_mode(); - // Not here. Yet. - return true; + return false; } void @@ -301,42 +249,13 @@ CairoWidget::redraw() queue_draw(); } -void -CairoWidget::change_scaling_mode() -{ - std::cout << " change_scaling_mode " << std::endl; - switch(_scaling_mode) - { - case scaling_none: - set_scaling_mode(scaling_to_w); - break; - case scaling_to_w: - case scaling_to_h: - case scaling_min: - case scaling_max: - set_scaling_mode((scaling_mode)(_scaling_mode << 1)); - break; - case scaling_all: - set_scaling_mode(scaling_none); - break; - } - redraw(); -/* switch(_scaling_mode) - { - case scaling_none: - _scaling_mode = scaling_to_w; - break; - case scaling_to_w: - case scaling_to_h: - case scaling_min: - case scaling_max: - _scaling_mode = (scaling_mode)(_scaling_mode << 1); - break; - case scaling_all: - _scaling_mode = scaling_none; - break; - } - redraw(); -*/ -} \ No newline at end of file +void +CairoWidget::calc_drawing_size(size_t& width, size_t& height) const +{ +} + +void +CairoWidget::calc_widget_size(size_t& width, size_t& height) const +{ +} diff --git a/src/cairo_widget.hh b/src/cairo_widget.hh index 5b316e4..06d856d 100644 --- a/src/cairo_widget.hh +++ b/src/cairo_widget.hh @@ -24,6 +24,7 @@ #include "config.h" #include +#include #include #include @@ -60,8 +61,11 @@ namespace sgpem // in this method the implemented widget must "do the things" virtual void draw_widget(cairo_t* ctx) = 0; - // with this method CairoWidget the needed drawing dimensions - virtual void calc_size(size_t& width, size_t& height) const = 0; + // with this method CairoWidget tells the needed drawing dimensions + virtual void calc_drawing_size(size_t& width, size_t& height) const; + + // with this method CairoWidget tells the needed widgwt dimensions + virtual void calc_widget_size(size_t& width, size_t& height) const; void redraw(); diff --git a/src/gui_builder.cc b/src/gui_builder.cc index 87059b9..1e0d6f2 100644 --- a/src/gui_builder.cc +++ b/src/gui_builder.cc @@ -130,7 +130,7 @@ GuiBuilder::on_file_open_activate() void GuiBuilder::on_file_save_activate() { - _simulation_widget->change_scaling_mode(); + // _simulation_widget->change_scaling_mode(); } void @@ -258,12 +258,14 @@ GuiBuilder::GuiBuilder(const std::string& gladefile) // Main simulation widget + ScrolledWindow* simulation_window = NULL; _refXml->get_widget("SimulationScrolledWindow", simulation_window); _simulation_widget = new SimulationWidget(); SimulationWidget* simulation_widget = manage(_simulation_widget); simulation_window->add(*simulation_widget); simulation_widget->show(); + } diff --git a/src/simulation_widget.cc b/src/simulation_widget.cc index ac3414b..462580a 100644 --- a/src/simulation_widget.cc +++ b/src/simulation_widget.cc @@ -117,21 +117,44 @@ SimulationWidget::draw_widget(cairo_t* ctx) void -SimulationWidget::calc_size(size_t& width, size_t& height) const +SimulationWidget::calc_drawing_size(size_t& width, size_t& height) const { // FIXME: write me // some magic here! - width = 300; - height = 350; + width = 150; + height = 150; } -/* -void -SimulationWidget::calc_size(const History& history, size_t& width, size_t& height) const +bool +SimulationWidget::on_button_press_event(GdkEventButton* event) { - // FIXME: write me - width = get_allocation().get_width(); - height = get_allocation().get_height(); - + std::cout << " on_button_press_event " << std::endl; + change_scaling_mode(); + // Not here. Yet. + return true; +} + + +void +SimulationWidget::change_scaling_mode() +{ + + std::cout << " change_scaling_mode " << std::endl; + scaling_mode scaling = get_scaling_mode(); + switch(scaling) + { + case scaling_none: + set_scaling_mode(scaling_to_w); + break; + case scaling_to_w: + case scaling_to_h: + case scaling_min: + case scaling_max: + set_scaling_mode((scaling_mode)(scaling << 1)); + break; + case scaling_all: + set_scaling_mode(scaling_none); + break; + } + redraw(); } -*/ diff --git a/src/simulation_widget.hh b/src/simulation_widget.hh index 6dafb88..5f6d4b7 100644 --- a/src/simulation_widget.hh +++ b/src/simulation_widget.hh @@ -36,9 +36,12 @@ namespace sgpem void update(const History& history); protected: + virtual bool on_button_press_event(GdkEventButton* event); + void change_scaling_mode(); + void draw_widget(cairo_t* ctx); - virtual void calc_size(size_t& width, size_t& height) const; + virtual void calc_drawing_size(size_t& width, size_t& height) const; // void calc_size(const History& history, size_t& width, size_t& height) const; private: int _n_update;