summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Gui/RenderArea.cpp128
-rw-r--r--src/Gui/RenderArea.h31
2 files changed, 147 insertions, 12 deletions
diff --git a/src/Gui/RenderArea.cpp b/src/Gui/RenderArea.cpp
index c19c0a5..ec37f67 100644
--- a/src/Gui/RenderArea.cpp
+++ b/src/Gui/RenderArea.cpp
@@ -1,6 +1,8 @@
#include "RenderArea.h"
#include <iostream>
#include <cstdlib>
+#include <cmath>
+#include <gtkmm/toolbutton.h>
#include <GL/gl.h>
namespace ZoomEdit {
@@ -9,7 +11,7 @@ namespace Gui {
GdkGLConfig *RenderArea::glconfig = NULL;
RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml)
-: Gtk::DrawingArea(cobject) {
+: Gtk::DrawingArea(cobject), zoomLevel(0), scale(100), x(0), y(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
@@ -20,19 +22,24 @@ RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade:
}
signal_realize().connect(sigc::mem_fun(this, &RenderArea::onRealize));
+ signal_configure_event().connect(sigc::mem_fun(this, &RenderArea::onConfigureEvent));
+ signal_expose_event().connect(sigc::mem_fun(this, &RenderArea::onExposeEvent));
+ signal_scroll_event().connect(sigc::mem_fun(this, &RenderArea::onScrollEvent));
+
+ Gtk::ToolButton *button;
+ xml->get_widget("ToolButtonZoomIn", button);
+ if(button)
+ button->signal_clicked().connect(sigc::bind(sigc::mem_fun(this, &RenderArea::zoom), 2, 0.5f, 0.5f));
+
+ xml->get_widget("ToolButtonZoomOut", button);
+ if(button)
+ button->signal_clicked().connect(sigc::bind(sigc::mem_fun(this, &RenderArea::zoom), -2, 0.5f, 0.5f));
gtk_widget_set_gl_capability(GTK_WIDGET(cobject), glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
}
-RenderArea::~RenderArea() {
-}
-
void RenderArea::onRealize() {
- GtkWidget *widget = GTK_WIDGET(gobj());
- GdkGLContext *context = gtk_widget_get_gl_context(widget);
- GdkGLDrawable *drawable = gtk_widget_get_gl_drawable(widget);
-
- if(!gdk_gl_drawable_gl_begin(drawable, context))
+ if(!gdkGLBegin())
return;
glClearColor(0, 0, 0, 0);
@@ -46,7 +53,108 @@ void RenderArea::onRealize() {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- gdk_gl_drawable_gl_end(drawable);
+ gdkGLEnd();
+}
+
+bool RenderArea::onConfigureEvent(GdkEventConfigure *event) {
+ updateViewport();
+ return true;
+}
+
+bool RenderArea::onExposeEvent(GdkEventExpose *event) {
+ if(!gdkGLBegin())
+ return false;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ glScalef(scale, scale, 1);
+ glTranslatef(-x, -y, 0);
+
+
+ drawGrid();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+
+ gdkSwapBuffers();
+ gdkGLEnd();
+
+ return true;
+}
+
+bool RenderArea::onScrollEvent(GdkEventScroll *event) {
+ switch(event->direction) {
+ case GDK_SCROLL_UP:
+ zoom(1, event->x/get_width(), event->y/get_height());
+ return true;
+ case GDK_SCROLL_DOWN:
+ zoom(-1, event->x/get_width(), event->y/get_height());
+ return true;
+ default:
+ return false;
+ }
+}
+
+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();
+}
+
+void RenderArea::updateViewport() {
+ if(!gdkGLBegin())
+ return;
+
+ glViewport(0, 0, get_width(), get_height());
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ if(get_width() != 0 && get_height() != 0)
+ glScalef(2.0f/get_width(), -2.0f/get_height(), 1);
+
+ gdkGLEnd();
+
+ queue_draw();
+}
+
+void RenderArea::drawGrid() {
+ float depth = std::log10(scale)-0.75f;
+ 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);
+
+
+ glLineWidth(1.0f);
+
+ glBegin(GL_LINES);
+
+ for(i = 0; 0.4f*(depth-depth2+i-1) < 0.5f; i++) {
+ 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) {
+ glVertex2f(f, y1);
+ glVertex2f(f, y2);
+ }
+
+ for(f = y1 - std::fmod(y1, step) - step; f <= y2; f+=step) {
+ glVertex2f(x1, f);
+ glVertex2f(x2, f);
+ }
+
+ step *= 10;
+ }
+
+ glEnd();
}
}
diff --git a/src/Gui/RenderArea.h b/src/Gui/RenderArea.h
index 6695e09..d0b4ad3 100644
--- a/src/Gui/RenderArea.h
+++ b/src/Gui/RenderArea.h
@@ -11,12 +11,39 @@ namespace Gui {
class RenderArea : public Gtk::DrawingArea {
public:
RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml);
- virtual ~RenderArea();
-
+
private:
static GdkGLConfig *glconfig;
+ float x, y;
+
+ int zoomLevel;
+ float scale;
+
void onRealize();
+ bool onConfigureEvent(GdkEventConfigure *event);
+ bool onExposeEvent(GdkEventExpose *event);
+ bool onScrollEvent(GdkEventScroll *event);
+
+ void zoom(int zoom, float x = 0.5f, float y = 0.5f);
+
+ void updateViewport();
+
+ void drawGrid();
+
+ bool gdkGLBegin() {
+ GtkWidget *widget = GTK_WIDGET(gobj());
+
+ return gdk_gl_drawable_gl_begin(gtk_widget_get_gl_drawable(widget), gtk_widget_get_gl_context(widget));
+ }
+
+ void gdkSwapBuffers() {
+ gdk_gl_drawable_swap_buffers(gtk_widget_get_gl_drawable(GTK_WIDGET(gobj())));
+ }
+
+ void gdkGLEnd() {
+ gdk_gl_drawable_gl_end(gtk_widget_get_gl_drawable(GTK_WIDGET(gobj())));
+ }
};
}