diff options
Diffstat (limited to 'src/Gui/RenderArea.cpp')
-rw-r--r-- | src/Gui/RenderArea.cpp | 128 |
1 files changed, 118 insertions, 10 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(); } } |