summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Gui/RenderArea.cpp86
-rw-r--r--src/Gui/RenderArea.h19
-rw-r--r--src/Gui/Window.cpp1
-rw-r--r--src/Gui/Window.h3
-rw-r--r--src/Instance.cpp1
-rw-r--r--src/Instance.h5
6 files changed, 104 insertions, 11 deletions
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 <cstdlib>
#include <cmath>
#include <gtkmm/toolbutton.h>
+#include <gtkmm/adjustment.h>
#include <GL/gl.h>
namespace ZoomEdit {
@@ -11,7 +12,7 @@ namespace Gui {
GdkGLConfig *RenderArea::glconfig = NULL;
RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &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::RefPtr<Gnome::Glade:
if(button)
button->signal_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 <gtkmm/drawingarea.h>
+#include <gtkmm/scrollbar.h>
#include <libglademm/xml.h>
#include <gtk/gtkgl.h>
@@ -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 <gtkmm/window.h>
#include <libglademm/xml.h>
-#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 <iostream>
#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 <gtkmm/main.h>
#include <libglademm/xml.h>
-#include "Gui/Window.h"
namespace ZoomEdit {
+namespace Gui {
+class Window;
+}
+
class Instance {
public:
virtual ~Instance();