From e8e438f5ee6aa850eec8dbb2343f697b2c2731d7 Mon Sep 17 00:00:00 2001 From: neoraider Date: Wed, 9 Apr 2008 16:08:01 +0000 Subject: * Working scrollbars! * More forward declarations: Compiles faster now --- src/Gui/RenderArea.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++----- src/Gui/RenderArea.h | 19 ++++++++++- src/Gui/Window.cpp | 1 + src/Gui/Window.h | 3 +- src/Instance.cpp | 1 + src/Instance.h | 5 ++- 6 files changed, 104 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Gui/RenderArea.cpp b/src/Gui/RenderArea.cpp index ec37f67..8bda549 100644 --- a/src/Gui/RenderArea.cpp +++ b/src/Gui/RenderArea.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace ZoomEdit { @@ -11,7 +12,7 @@ namespace Gui { GdkGLConfig *RenderArea::glconfig = NULL; RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr &xml) -: Gtk::DrawingArea(cobject), zoomLevel(0), scale(100), x(0), y(0) { +: Gtk::DrawingArea(cobject), zoomLevel(0), scale(100), xCenter(0), yCenter(0) { if(!glconfig) { glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DOUBLE)); if(!glconfig) glconfig = gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB); // Hmm, can't find double buffered config @@ -35,6 +36,9 @@ RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtrsignal_clicked().connect(sigc::bind(sigc::mem_fun(this, &RenderArea::zoom), -2, 0.5f, 0.5f)); + xml->get_widget("Hscrollbar", hScrollbar); + xml->get_widget("Vscrollbar", vScrollbar); + gtk_widget_set_gl_capability(GTK_WIDGET(cobject), glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); } @@ -71,7 +75,7 @@ bool RenderArea::onExposeEvent(GdkEventExpose *event) { glPushMatrix(); glScalef(scale, scale, 1); - glTranslatef(-x, -y, 0); + glTranslatef(-xCenter, -yCenter, 0); drawGrid(); @@ -103,7 +107,7 @@ void RenderArea::zoom(int zoom, float x, float y) { zoomLevel = std::max(std::min(zoomLevel + zoom, 50), -100); scale = 100*std::pow(1.1f, zoomLevel); - queue_draw(); + updateScrollbars(x, y); } void RenderArea::updateViewport() { @@ -120,17 +124,83 @@ void RenderArea::updateViewport() { gdkGLEnd(); + updateScrollbars(); +} + +void RenderArea::updateScrollbars(float x, float y) { + const gdouble imageWidth = getImageWidth(), imageHeight = getImageHeight(); + const gdouble minX = -imageWidth/2, maxX = imageWidth/2; + const gdouble minY = -imageHeight/2, maxY = imageHeight/2; + const gdouble width = getViewWidth(), height = getViewHeight(); + gdouble lower, upper, pageSize, value; + + get_window()->freeze_updates(); + + if(hScrollbar) { + lower = hScrollbar->get_adjustment()->get_lower(); + upper = hScrollbar->get_adjustment()->get_upper(); + pageSize = hScrollbar->get_adjustment()->get_page_size(); + + hScrollbar->get_adjustment()->set_lower(minX + width/2); + hScrollbar->get_adjustment()->set_upper(maxX + width/2); + hScrollbar->get_adjustment()->set_page_size(width); + + if(pageSize > (upper-lower) && width < imageWidth) + value = 0; + else + value = hScrollbar->get_value() + (x-0.5)*(pageSize-width); + + hScrollbar->set_value(std::max(std::min(value, maxX - width/2), minX + width/2)); + } + + if(vScrollbar) { + lower = vScrollbar->get_adjustment()->get_lower(); + upper = vScrollbar->get_adjustment()->get_upper(); + pageSize = vScrollbar->get_adjustment()->get_page_size(); + + vScrollbar->get_adjustment()->set_lower(minY + height/2); + vScrollbar->get_adjustment()->set_upper(maxY + height/2); + vScrollbar->get_adjustment()->set_page_size(height); + + if(pageSize > (upper-lower) && height < imageHeight) + value = 0; + else + value = vScrollbar->get_value() + (y-0.5)*(pageSize-height); + + vScrollbar->set_value(std::max(std::min(value, maxY - height/2), minY + height/2)); + } + + get_window()->thaw_updates(); + + updateScrolling(); +} + +void RenderArea::updateScrolling() { + if(hScrollbar) { + if(getImageWidth() < getViewWidth()) + xCenter = 0; + else + xCenter = hScrollbar->get_value(); + } + + if(vScrollbar) { + if(getImageHeight() < getViewHeight()) + yCenter = 0; + else + yCenter = vScrollbar->get_value(); + } + queue_draw(); } void RenderArea::drawGrid() { - float depth = std::log10(scale)-0.75f; + float depth = 1.25f + 0.04f*zoomLevel; float depth2 = std::floor(depth); float step = std::pow(0.1f, depth2); float f; int i; - float x1 = x-get_width()/(2*scale), y1 = y-get_height()/(2*scale); - float x2 = x+get_width()/(2*scale), y2 = y+get_height()/(2*scale); + float x1 = xCenter-getViewWidth()/2, y1 = yCenter-getViewHeight()/2; + float x2 = xCenter+getViewWidth()/2, y2 = yCenter+getViewHeight()/2; glLineWidth(1.0f); @@ -141,12 +211,12 @@ void RenderArea::drawGrid() { f = std::min(0.4f*(depth-depth2+i), 0.5f); glColor3f(f, f, f); - for(f = x1 - std::fmod(x1, step) - step; f <= x2; f+=step) { + for(f = x1 - std::fmod(x1, step); f <= x2; f+=step) { glVertex2f(f, y1); glVertex2f(f, y2); } - for(f = y1 - std::fmod(y1, step) - step; f <= y2; f+=step) { + for(f = y1 - std::fmod(y1, step); f <= y2; f+=step) { glVertex2f(x1, f); glVertex2f(x2, f); } diff --git a/src/Gui/RenderArea.h b/src/Gui/RenderArea.h index d0b4ad3..16c312e 100644 --- a/src/Gui/RenderArea.h +++ b/src/Gui/RenderArea.h @@ -2,6 +2,7 @@ #define ZOOMEDIT_GUI_RENDERAREA_H_ #include +#include #include #include @@ -15,7 +16,10 @@ class RenderArea : public Gtk::DrawingArea { private: static GdkGLConfig *glconfig; - float x, y; + Gtk::HScrollbar *hScrollbar; + Gtk::VScrollbar *vScrollbar; + + float xCenter, yCenter; int zoomLevel; float scale; @@ -28,9 +32,22 @@ class RenderArea : public Gtk::DrawingArea { void zoom(int zoom, float x = 0.5f, float y = 0.5f); void updateViewport(); + void updateScrollbars(float x = 0.5f, float y = 0.5f); + void updateScrolling(); void drawGrid(); + float getViewWidth() const { + return get_width()/scale; + } + + float getViewHeight() const { + return get_height()/scale; + } + + float getImageWidth() const {return 10;} + float getImageHeight() const {return 10;} + bool gdkGLBegin() { GtkWidget *widget = GTK_WIDGET(gobj()); diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp index 0ec933d..0109113 100644 --- a/src/Gui/Window.cpp +++ b/src/Gui/Window.cpp @@ -1,4 +1,5 @@ #include "Window.h" +#include "RenderArea.h" namespace ZoomEdit { namespace Gui { diff --git a/src/Gui/Window.h b/src/Gui/Window.h index 89e9f49..4cb3845 100644 --- a/src/Gui/Window.h +++ b/src/Gui/Window.h @@ -3,11 +3,12 @@ #include #include -#include "RenderArea.h" namespace ZoomEdit { namespace Gui { +class RenderArea; + class Window : public Gtk::Window { private: RenderArea *renderArea; diff --git a/src/Instance.cpp b/src/Instance.cpp index 6c658ba..f301bbf 100644 --- a/src/Instance.cpp +++ b/src/Instance.cpp @@ -1,5 +1,6 @@ #include #include "Instance.h" +#include "Gui/Window.h" namespace ZoomEdit { diff --git a/src/Instance.h b/src/Instance.h index 4517caf..de74dae 100644 --- a/src/Instance.h +++ b/src/Instance.h @@ -3,10 +3,13 @@ #include #include -#include "Gui/Window.h" namespace ZoomEdit { +namespace Gui { +class Window; +} + class Instance { public: virtual ~Instance(); -- cgit v1.2.3