- 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
This commit is contained in:
parent
df24fafb06
commit
e4c269f5d4
|
@ -19,23 +19,13 @@
|
||||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
// 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_elements.hh"
|
||||||
#include "cairo_widget.hh"
|
#include "cairo_widget.hh"
|
||||||
|
|
||||||
|
|
||||||
#include <gdkmm/window.h>
|
#include <gdkmm/window.h>
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -45,7 +35,8 @@ using namespace sgpem;
|
||||||
|
|
||||||
CairoWidget::CairoWidget()
|
CairoWidget::CairoWidget()
|
||||||
: Glib::ObjectBase("sgpem_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),
|
_client_w(0), _client_h(0), _pixmap_w(0), _pixmap_h(0),
|
||||||
_need_redraw(true), _scaling_mode(scaling_none)
|
_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;
|
CairoWidget::scaling_mode old_scaling = _scaling_mode;
|
||||||
_scaling_mode = scaling;
|
_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;
|
return old_scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,11 +62,10 @@ CairoWidget::get_scaling_mode()
|
||||||
return _scaling_mode;
|
return _scaling_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CairoWidget::on_realize()
|
CairoWidget::on_realize()
|
||||||
{
|
{
|
||||||
std::cout << " on_realize" << std::endl;
|
// std::cout << " on_realize" << std::endl;
|
||||||
if (is_realized()) return;
|
if (is_realized()) return;
|
||||||
|
|
||||||
Gtk::Widget::on_realize();
|
Gtk::Widget::on_realize();
|
||||||
|
@ -120,7 +81,7 @@ CairoWidget::on_realize()
|
||||||
attributes.width = alloc.get_width();
|
attributes.width = alloc.get_width();
|
||||||
attributes.height = alloc.get_height();
|
attributes.height = alloc.get_height();
|
||||||
attributes.wclass = GDK_INPUT_OUTPUT;
|
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.window_type = GDK_WINDOW_CHILD;
|
||||||
attributes.visual = get_visual()->gobj();
|
attributes.visual = get_visual()->gobj();
|
||||||
attributes.colormap = get_colormap()->gobj();
|
attributes.colormap = get_colormap()->gobj();
|
||||||
|
@ -128,8 +89,8 @@ CairoWidget::on_realize()
|
||||||
_client_w = alloc.get_width();
|
_client_w = alloc.get_width();
|
||||||
_client_h = alloc.get_height();
|
_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
|
static const gint attributes_mask = Gdk::WA_X | Gdk::WA_Y | Gdk::WA_WMCLASS
|
||||||
| Gdk::WA_VISUAL | Gdk::WA_COLORMAP;
|
| Gdk::WA_VISUAL | Gdk::WA_COLORMAP;
|
||||||
|
|
||||||
|
@ -146,11 +107,10 @@ CairoWidget::on_realize()
|
||||||
get_style()->set_background(window, Gtk::STATE_ACTIVE);
|
get_style()->set_background(window, Gtk::STATE_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CairoWidget::on_size_allocate(const Gtk::Allocation& allocation)
|
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);
|
set_allocation(allocation);
|
||||||
|
|
||||||
if (is_realized())
|
if (is_realized())
|
||||||
|
@ -169,68 +129,59 @@ CairoWidget::on_size_request(Gtk::Requisition* requisition)
|
||||||
{
|
{
|
||||||
// Gtk+ asks the desired widget dimension
|
// Gtk+ asks the desired widget dimension
|
||||||
|
|
||||||
std::cout << " on_size_request, requisition->width : " << requisition->width << ", requisition->height : " << requisition->height << std::endl;
|
// std::cout << " on_size_request, requisition->width : " << requisition->width << ", requisition->height : " << requisition->height << std::endl;
|
||||||
// the response is - what allocated before...
|
calc_widget_size(_client_w, _client_h);
|
||||||
/*
|
requisition->width = _client_w;
|
||||||
switch(_scaling_mode)
|
requisition->height = _client_h;
|
||||||
{
|
|
||||||
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::RefPtr<Gdk::Window>parent_w = get_parent_window();
|
|
||||||
if(parent_w)
|
|
||||||
{
|
|
||||||
int w, h;
|
|
||||||
parent_w->get_size(w, h);
|
|
||||||
requisition->width = w;
|
|
||||||
requisition->height = h;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CairoWidget::on_expose_event(GdkEventExpose* event)
|
CairoWidget::on_expose_event(GdkEventExpose* event)
|
||||||
{
|
{
|
||||||
std::cout << " on_expose_event START...";
|
// std::cout << " on_expose_event START...";
|
||||||
if (event == NULL || event->count > 0)
|
if (event == NULL || event->count > 0)
|
||||||
return false;
|
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;
|
_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)
|
if(_client_w>_pixmap_w || _client_h>_pixmap_h)
|
||||||
{
|
{
|
||||||
std::cout << " on_expose_event CREATE Pixmap." << std::endl;
|
// previdence in the code: allocate more than actually needed
|
||||||
_buf = Gdk::Pixmap::create(get_window(), _client_w, _client_h);
|
_pixmap_w = (size_t) (_client_w*1.2);
|
||||||
_pixmap_w = _client_w;
|
_pixmap_h = (size_t) (_client_h*1.2);
|
||||||
_pixmap_h = _client_h;
|
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.
|
// Draw the widget background as the first thing.
|
||||||
// I've seen this is how it's done in the very Gtk+ toolkit
|
// I've seen this is how it's done in the very Gtk+ toolkit
|
||||||
// for the GtkProgressBar widget.
|
// for the GtkProgressBar widget.
|
||||||
GtkStyle* gStyle = get_style()->gobj();
|
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_paint_box(gStyle, _buf->gobj(),
|
||||||
GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_IN,
|
GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_IN,
|
||||||
NULL, this->gobj(), "through",
|
NULL, (GtkWidget*)this->gobj(), "through",
|
||||||
0, 0, _client_w, _client_h);
|
0, 0, _client_w, _client_h);
|
||||||
|
|
||||||
cairo_t* ctx = gdk_cairo_create(_buf->gobj());
|
cairo_t* ctx = gdk_cairo_create(_buf->gobj());
|
||||||
|
|
||||||
// Determine the final drawing dimensions before to start drawing
|
// 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...
|
// do the drawing...
|
||||||
if(_scaling_mode!=scaling_none && _draw_w>0 && _draw_h>0)
|
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);
|
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);
|
draw_widget(ctx);
|
||||||
cairo_destroy(ctx);
|
cairo_destroy(ctx);
|
||||||
}
|
}
|
||||||
|
@ -287,10 +238,7 @@ CairoWidget::on_expose_event(GdkEventExpose* event)
|
||||||
bool
|
bool
|
||||||
CairoWidget::on_button_press_event(GdkEventButton* event)
|
CairoWidget::on_button_press_event(GdkEventButton* event)
|
||||||
{
|
{
|
||||||
std::cout << " on_button_press_event " << std::endl;
|
return false;
|
||||||
change_scaling_mode();
|
|
||||||
// Not here. Yet.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -301,42 +249,13 @@ CairoWidget::redraw()
|
||||||
queue_draw();
|
queue_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CairoWidget::change_scaling_mode()
|
|
||||||
{
|
|
||||||
|
|
||||||
std::cout << " change_scaling_mode " << std::endl;
|
void
|
||||||
switch(_scaling_mode)
|
CairoWidget::calc_drawing_size(size_t& width, size_t& height) const
|
||||||
{
|
{
|
||||||
case scaling_none:
|
}
|
||||||
set_scaling_mode(scaling_to_w);
|
|
||||||
break;
|
void
|
||||||
case scaling_to_w:
|
CairoWidget::calc_widget_size(size_t& width, size_t& height) const
|
||||||
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();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
|
#include <gtkmm/drawingarea.h>
|
||||||
#include <gtkmm/widget.h>
|
#include <gtkmm/widget.h>
|
||||||
#include <gdkmm/pixmap.h>
|
#include <gdkmm/pixmap.h>
|
||||||
|
|
||||||
|
@ -60,8 +61,11 @@ namespace sgpem
|
||||||
// in this method the implemented widget must "do the things"
|
// in this method the implemented widget must "do the things"
|
||||||
virtual void draw_widget(cairo_t* ctx) = 0;
|
virtual void draw_widget(cairo_t* ctx) = 0;
|
||||||
|
|
||||||
// with this method CairoWidget the needed drawing dimensions
|
// with this method CairoWidget tells the needed drawing dimensions
|
||||||
virtual void calc_size(size_t& width, size_t& height) const = 0;
|
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();
|
void redraw();
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ GuiBuilder::on_file_open_activate()
|
||||||
void
|
void
|
||||||
GuiBuilder::on_file_save_activate()
|
GuiBuilder::on_file_save_activate()
|
||||||
{
|
{
|
||||||
_simulation_widget->change_scaling_mode();
|
// _simulation_widget->change_scaling_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -258,12 +258,14 @@ GuiBuilder::GuiBuilder(const std::string& gladefile)
|
||||||
|
|
||||||
|
|
||||||
// Main simulation widget
|
// Main simulation widget
|
||||||
|
|
||||||
ScrolledWindow* simulation_window = NULL;
|
ScrolledWindow* simulation_window = NULL;
|
||||||
_refXml->get_widget("SimulationScrolledWindow", simulation_window);
|
_refXml->get_widget("SimulationScrolledWindow", simulation_window);
|
||||||
_simulation_widget = new SimulationWidget();
|
_simulation_widget = new SimulationWidget();
|
||||||
SimulationWidget* simulation_widget = manage(_simulation_widget);
|
SimulationWidget* simulation_widget = manage(_simulation_widget);
|
||||||
simulation_window->add(*simulation_widget);
|
simulation_window->add(*simulation_widget);
|
||||||
simulation_widget->show();
|
simulation_widget->show();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,21 +117,44 @@ SimulationWidget::draw_widget(cairo_t* ctx)
|
||||||
|
|
||||||
|
|
||||||
void
|
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
|
// FIXME: write me
|
||||||
// some magic here!
|
// some magic here!
|
||||||
width = 300;
|
width = 150;
|
||||||
height = 350;
|
height = 150;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
bool
|
||||||
void
|
SimulationWidget::on_button_press_event(GdkEventButton* event)
|
||||||
SimulationWidget::calc_size(const History& history, size_t& width, size_t& height) const
|
|
||||||
{
|
{
|
||||||
// FIXME: write me
|
std::cout << " on_button_press_event " << std::endl;
|
||||||
width = get_allocation().get_width();
|
change_scaling_mode();
|
||||||
height = get_allocation().get_height();
|
// 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();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -36,9 +36,12 @@ namespace sgpem
|
||||||
void update(const History& history);
|
void update(const History& history);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool on_button_press_event(GdkEventButton* event);
|
||||||
|
void change_scaling_mode();
|
||||||
|
|
||||||
void draw_widget(cairo_t* ctx);
|
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;
|
// void calc_size(const History& history, size_t& width, size_t& height) const;
|
||||||
private:
|
private:
|
||||||
int _n_update;
|
int _n_update;
|
||||||
|
|
Loading…
Reference in New Issue