diff options
-rw-r--r-- | src/Gui/RenderArea.cpp | 89 | ||||
-rw-r--r-- | src/Gui/RenderArea.h | 25 | ||||
-rw-r--r-- | src/Instance.cpp | 8 | ||||
-rw-r--r-- | src/View/MapView.cpp | 30 | ||||
-rw-r--r-- | src/View/MapView.h | 49 | ||||
-rw-r--r-- | src/View/TopView.cpp | 46 | ||||
-rw-r--r-- | src/View/TopView.h | 16 | ||||
-rw-r--r-- | src/View/View.h | 3 | ||||
-rw-r--r-- | zoomedit.glade | 29 |
9 files changed, 199 insertions, 96 deletions
diff --git a/src/Gui/RenderArea.cpp b/src/Gui/RenderArea.cpp index 1904aa8..0cec471 100644 --- a/src/Gui/RenderArea.cpp +++ b/src/Gui/RenderArea.cpp @@ -22,8 +22,6 @@ #include <iostream> #include <cstdlib> #include <cmath> -#include <gtkmm/toolbutton.h> -#include <gtkmm/adjustment.h> #include <GL/gl.h> namespace ZoomEdit { @@ -31,9 +29,8 @@ namespace Gui { GdkGLConfig *RenderArea::glconfig = 0; -RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml) -: Gtk::DrawingArea(cobject), view(0), xCenter(0), yCenter(0), viewWidth(0), viewHeight(0), zoomLevel(0), -scale(100), inWindow(false) { +RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml>&) +: Gtk::DrawingArea(cobject), view(0), inWindow(false) { 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 @@ -51,13 +48,6 @@ scale(100), inWindow(false) { signal_leave_notify_event().connect(sigc::mem_fun(this, &RenderArea::onLeaveNotifyEvent)); signal_motion_notify_event().connect(sigc::mem_fun(this, &RenderArea::onMotionNotifyEvent)); - Gtk::ToolButton *button; - xml->get_widget("ToolButtonZoomIn", button); - button->signal_clicked().connect(sigc::bind(sigc::mem_fun(this, &RenderArea::zoom), 2, 0.5f, 0.5f)); - - xml->get_widget("ToolButtonZoomOut", 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, 0, TRUE, GDK_GL_RGBA_TYPE); } @@ -93,9 +83,6 @@ bool RenderArea::onConfigureEvent(GdkEventConfigure*) { gdkGLEnd(); - viewWidth = get_width()/scale; - viewHeight = get_height()/scale; - queue_draw(); return true; @@ -105,20 +92,9 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) { if(!gdkGLBegin()) return false; - glClear(GL_COLOR_BUFFER_BIT); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - glScalef(scale, scale, 1); - glTranslatef(-xCenter, -yCenter, 0); - if(view) view->render(this); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gdkSwapBuffers(); gdkGLEnd(); @@ -126,22 +102,26 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) { } 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; + if(view) { + switch(event->direction) { + case GDK_SCROLL_UP: + view->zoom(this, 1, event->x - get_width()/2, event->y - get_height()/2); + return true; + case GDK_SCROLL_DOWN: + view->zoom(this, -1, event->x - get_width()/2, event->y - get_height()/2); + return true; + default: + return false; + } } + + return false; } bool RenderArea::onEnterNotifyEvent(GdkEventCrossing *event) { inWindow = true; - xHover = event->x/scale - getViewWidth()/2 + xCenter; - yHover = event->y/scale - getViewHeight()/2 + yCenter; + xHover = event->x; + yHover = event->y; return true; } @@ -153,34 +133,21 @@ bool RenderArea::onLeaveNotifyEvent(GdkEventCrossing*) { } bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) { - inWindow = true; - - if(event->state & GDK_BUTTON3_MASK) { - xCenter = xHover - event->x/scale + getViewWidth()/2; - yCenter = yHover - event->y/scale + getViewHeight()/2; - queue_draw(); - } - else { - xHover = event->x/scale - getViewWidth()/2 + xCenter; - yHover = event->y/scale - getViewHeight()/2 + yCenter; + if(!inWindow) { + xHover = event->x; + yHover = event->y; + inWindow = true; + + return true; } - return true; -} - -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); - - const float newWidth = get_width()/scale, newHeight = get_height()/scale; - - xCenter += (x-0.5f)*(viewWidth-newWidth); - yCenter += (y-0.5f)*(viewHeight-newHeight); + if(event->state & GDK_BUTTON3_MASK && view) + view->move(this, xHover - event->x, yHover - event->y); - viewWidth = newWidth; - viewHeight = newHeight; + xHover = event->x; + yHover = event->y; - queue_draw(); + return true; } } diff --git a/src/Gui/RenderArea.h b/src/Gui/RenderArea.h index c8b6d6e..08cb841 100644 --- a/src/Gui/RenderArea.h +++ b/src/Gui/RenderArea.h @@ -35,7 +35,7 @@ namespace Gui { class RenderArea : public Gtk::DrawingArea { public: - RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml); + RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml>&); View::View* getView() const {return view;} void setView(View::View *view0) { @@ -43,32 +43,13 @@ class RenderArea : public Gtk::DrawingArea { queue_draw(); } - float getViewWidth() const { - return viewWidth; - } - - float getViewHeight() const { - return viewHeight; - } - - float getScale() const {return scale;} - - float getXCenter() const {return xCenter;} - float getYCenter() const {return yCenter;} - private: static GdkGLConfig *glconfig; View::View *view; - float xCenter, yCenter; - float viewWidth, viewHeight; - - int zoomLevel; - float scale; - bool inWindow; - float xHover, yHover; + gdouble xHover, yHover; void onRealize(); bool onConfigureEvent(GdkEventConfigure*); @@ -78,8 +59,6 @@ class RenderArea : public Gtk::DrawingArea { bool onLeaveNotifyEvent(GdkEventCrossing*); bool onMotionNotifyEvent(GdkEventMotion *event); - void zoom(int zoom, float x = 0.5f, float y = 0.5f); - bool gdkGLBegin() { GtkWidget *widget = GTK_WIDGET(gobj()); diff --git a/src/Instance.cpp b/src/Instance.cpp index b54fb32..0f53dab 100644 --- a/src/Instance.cpp +++ b/src/Instance.cpp @@ -21,6 +21,7 @@ #include <iostream> #include <libxml++/validators/dtdvalidator.h> #include <libxml/tree.h> +#include <gtkmm/toolbutton.h> #include <Gui/Window.h> #include <Gui/RenderArea.h> #include <Data/Level.h> @@ -64,6 +65,13 @@ Instance::Instance(const Glib::ustring &file) : window(0), levelXml(0), level(0) view = new View::TopView(); window->getRenderArea()->setView(view); + Gtk::ToolButton *button; + xml->get_widget("ToolButtonZoomIn", button); + button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), window->getRenderArea(), 2, 0, 0)); + + xml->get_widget("ToolButtonZoomOut", button); + button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), window->getRenderArea(), -2, 0, 0)); + if(file.empty()) createLevel(); else diff --git a/src/View/MapView.cpp b/src/View/MapView.cpp new file mode 100644 index 0000000..263383f --- /dev/null +++ b/src/View/MapView.cpp @@ -0,0 +1,30 @@ +/* + * MapView.cpp + * + * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "MapView.h" + +namespace ZoomEdit { +namespace View { + +void MapView::render(Gui::RenderArea *renderArea) { + +} + +} +} diff --git a/src/View/MapView.h b/src/View/MapView.h new file mode 100644 index 0000000..525eb97 --- /dev/null +++ b/src/View/MapView.h @@ -0,0 +1,49 @@ +/* + * MapView.h + * + * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ZOOMEDIT_VIEW_MAPVIEW_H_ +#define ZOOMEDIT_VIEW_MAPVIEW_H_ + +#include "View.h" + +namespace ZoomEdit { + +namespace Data { +class Level; +} + +namespace View { + +class MapView : public View { + private: + Data::Level *level; + + public: + MapView(Data::Level *level0 = 0) : level(level0) {} + + Data::Level* getLevel() {return level;} + void setLevel(Data::Level *level0) {level = level0;} + + virtual void render(Gui::RenderArea *renderArea); +}; + +} +} + +#endif /*ZOOMEDIT_VIEW_MAPVIEW_H_*/ diff --git a/src/View/TopView.cpp b/src/View/TopView.cpp index 8ca047f..da26242 100644 --- a/src/View/TopView.cpp +++ b/src/View/TopView.cpp @@ -59,18 +59,16 @@ bool TopView::Edge::operator<(const Edge &e) const { } void TopView::drawGrid(Gui::RenderArea *renderArea) { - float depth = std::log10(renderArea->getScale())-0.75f; + float depth = 1.25f + 0.04f*zoomLevel; float depth2 = std::floor(depth); float step = std::pow(0.1f, depth2); - float x1, x2; - float y1, y2; - float width = renderArea->getViewWidth(); - float height = renderArea->getViewHeight(); + float width = renderArea->get_width()/scale; + float height = renderArea->get_height()/scale; - x1 = x2 = renderArea->getXCenter(); - y1 = y2 = renderArea->getYCenter(); - x1 -= width/2; x2 += width/2; - y1 -= height/2; y2 += height/2; + float x1 = xCenter - width/2; + float x2 = xCenter + width/2; + float y1 = yCenter - height/2; + float y2 = yCenter + height/2; glLineWidth(1.0f); @@ -142,7 +140,34 @@ void TopView::renderRoom(Data::Room *room) { glEnd(); } +void TopView::zoom(Gui::RenderArea *renderArea, int zoom, float x, float y) { + const float oldScale = scale; + + zoomLevel = std::max(std::min(zoomLevel + zoom, 50), -100); + scale = 100*std::pow(1.1f, zoomLevel); + + xCenter += x*(1/oldScale - 1/scale); + yCenter += y*(1/oldScale - 1/scale); + + renderArea->queue_draw(); +} + +void TopView::move(Gui::RenderArea *renderArea, float x, float y) { + xCenter += x/scale; + yCenter += y/scale; + + renderArea->queue_draw(); +} + void TopView::render(Gui::RenderArea *renderArea) { + glClear(GL_COLOR_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glScalef(scale, scale, 1); + glTranslatef(-xCenter, -yCenter, 0); + drawGrid(renderArea); if(!level) @@ -152,6 +177,9 @@ void TopView::render(Gui::RenderArea *renderArea) { for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room) renderRoom(*room); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } } diff --git a/src/View/TopView.h b/src/View/TopView.h index 914b1e5..ad2862c 100644 --- a/src/View/TopView.h +++ b/src/View/TopView.h @@ -45,15 +45,29 @@ class TopView : public View { Data::Level *level; + float xCenter, yCenter; + + int zoomLevel; + float scale; + + float getXCenter() const {return xCenter;} + float getYCenter() const {return yCenter;} + + float getScale() const {return scale;} + void drawGrid(Gui::RenderArea *renderArea); void renderRoom(Data::Room *room); public: - TopView(Data::Level *level0 = 0) : level(level0) {} + TopView(Data::Level *level0 = 0) : level(level0), xCenter(0), yCenter(0), zoomLevel(0), scale(100) {} Data::Level* getLevel() {return level;} void setLevel(Data::Level *level0) {level = level0;} + virtual void zoom(Gui::RenderArea *renderArea, int zoom, float x, float y); + + virtual void move(Gui::RenderArea *renderArea, float x, float y); + virtual void render(Gui::RenderArea *renderArea); }; diff --git a/src/View/View.h b/src/View/View.h index ad0a6cd..6a0eaf8 100644 --- a/src/View/View.h +++ b/src/View/View.h @@ -33,6 +33,9 @@ class View { virtual ~View() {} virtual void render(Gui::RenderArea *renderArea) = 0; + + virtual void zoom(Gui::RenderArea*, int, float, float) {} + virtual void move(Gui::RenderArea*, float, float) {} }; } diff --git a/zoomedit.glade b/zoomedit.glade index ffb5ecd..341299e 100644 --- a/zoomedit.glade +++ b/zoomedit.glade @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.0 on Thu Apr 17 10:41:01 2008 --> +<!--Generated with glade3 3.4.0 on Fri Apr 18 10:38:23 2008 --> <glade-interface> <widget class="GtkWindow" id="WindowMain"> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> @@ -200,6 +200,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="position">480</property> <child> <widget class="GtkDrawingArea" id="RenderArea"> <property name="visible">True</property> @@ -211,7 +212,31 @@ </packing> </child> <child> - <placeholder/> + <widget class="GtkVBox" id="vboxpane"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <child> + <widget class="GtkAspectFrame" id="aspectframemap"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="label_xalign">0</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="yalign">0</property> + <property name="ratio">1.3300000429153442</property> + <property name="obey_child">False</property> + <child> + <widget class="GtkDrawingArea" id="MapArea"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="resize">True</property> + <property name="shrink">True</property> + </packing> </child> </widget> <packing> |