From 36d892d1f0f0a919e70f81abddaeb568f1f7625c Mon Sep 17 00:00:00 2001 From: neoraider Date: Mon, 5 May 2008 19:26:05 +0000 Subject: zoomedit: * Use signals to inform RenderArea of view changes --- src/Gui/RenderArea.cpp | 56 ++++++++++++--------- src/Gui/RenderArea.h | 9 ++-- src/Gui/Window.cpp | 8 --- src/Gui/Window.h | 2 - src/Instance.cpp | 9 ++-- src/View/MapView.cpp | 133 +++++++++++++++++++++++++++---------------------- src/View/MapView.h | 29 ++++++----- src/View/TopView.cpp | 50 ++++++++++++++----- src/View/TopView.h | 24 ++++++--- src/View/View.h | 23 +++++---- 10 files changed, 198 insertions(+), 145 deletions(-) (limited to 'src') diff --git a/src/Gui/RenderArea.cpp b/src/Gui/RenderArea.cpp index b6686f5..41f76a6 100644 --- a/src/Gui/RenderArea.cpp +++ b/src/Gui/RenderArea.cpp @@ -52,35 +52,45 @@ RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtrsignalUpdate().connect(sigc::mem_fun(this, &RenderArea::queue_draw)); + + if(is_realized()) { + if(!gdkGLBegin()) + return; + + view->init(); + view->resize(get_width(), get_height()); + + gdkGLEnd(); + + queue_draw(); + } + } +} + void RenderArea::onRealize() { if(!gdkGLBegin()) return; - glClearColor(0, 0, 0, 0); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - glEnable(GL_LINE_SMOOTH); - glEnable(GL_POINT_SMOOTH); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + if(view) + view->init(); gdkGLEnd(); } -bool RenderArea::onConfigureEvent(GdkEventConfigure*) { +bool RenderArea::onConfigureEvent(GdkEventConfigure *event) { if(!gdkGLBegin()) return false; - 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); + if(view) + view->resize(event->width, event->height); gdkGLEnd(); @@ -94,7 +104,7 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) { return false; if(view) - view->render(this); + view->render(); gdkSwapBuffers(); gdkGLEnd(); @@ -106,10 +116,10 @@ bool RenderArea::onScrollEvent(GdkEventScroll *event) { if(view) { switch(event->direction) { case GDK_SCROLL_UP: - view->zoom(this, 1, event->x - get_width()/2, event->y - get_height()/2); + view->zoom(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); + view->zoom(-1, event->x - get_width()/2, event->y - get_height()/2); return true; default: return false; @@ -121,7 +131,7 @@ bool RenderArea::onScrollEvent(GdkEventScroll *event) { bool RenderArea::onButtonPressEvent(GdkEventButton *event) { if(view && event->button == 1) - view->click(this, event->x, event->y); + view->click(event->x, event->y); return true; } @@ -150,7 +160,7 @@ bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) { } if(view) - view->move(this, xHover - event->x, yHover - event->y, event->state); + view->move(xHover - event->x, yHover - event->y, event->state); xHover = event->x; yHover = event->y; diff --git a/src/Gui/RenderArea.h b/src/Gui/RenderArea.h index 6aa66df..d42a352 100644 --- a/src/Gui/RenderArea.h +++ b/src/Gui/RenderArea.h @@ -38,21 +38,20 @@ class RenderArea : public Gtk::DrawingArea { RenderArea(BaseObjectType *cobject, const Glib::RefPtr&); View::View* getView() const {return view;} - void setView(View::View *view0) { - view = view0; - queue_draw(); - } + void setView(View::View *view0); private: static GdkGLConfig *glconfig; View::View *view; + sigc::connection viewUpdate; + bool inWindow; gdouble xHover, yHover; void onRealize(); - bool onConfigureEvent(GdkEventConfigure*); + bool onConfigureEvent(GdkEventConfigure *event); bool onExposeEvent(GdkEventExpose*); bool onScrollEvent(GdkEventScroll *event); bool onButtonPressEvent(GdkEventButton *event); diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp index df20876..f33edf0 100644 --- a/src/Gui/Window.cpp +++ b/src/Gui/Window.cpp @@ -29,9 +29,6 @@ Window::Window(BaseObjectType *cobject, const Glib::RefPtr &x xml->get_widget_derived("RenderArea", renderArea); xml->get_widget_derived("MapArea", mapArea); - - if(renderArea) - renderArea->signal_expose_event().connect_notify(sigc::mem_fun(this, &Window::updateMap)); } Window::~Window() { @@ -42,10 +39,5 @@ Window::~Window() { delete mapArea; } -void Window::updateMap(GdkEventExpose*) { - if(mapArea) - mapArea->queue_draw(); -} - } } diff --git a/src/Gui/Window.h b/src/Gui/Window.h index 9b4f4ef..d2bd7aa 100644 --- a/src/Gui/Window.h +++ b/src/Gui/Window.h @@ -32,8 +32,6 @@ class Window : public Gtk::Window { private: RenderArea *renderArea, *mapArea; - void updateMap(GdkEventExpose*); - public: Window(BaseObjectType *cobject, const Glib::RefPtr &xml); virtual ~Window(); diff --git a/src/Instance.cpp b/src/Instance.cpp index 29a912b..a6346ad 100644 --- a/src/Instance.cpp +++ b/src/Instance.cpp @@ -66,15 +66,15 @@ Instance::Instance(const Glib::ustring &file) : window(0), levelXml(0), level(0) view = new View::TopView(); window->getRenderArea()->setView(view); - mapView = new View::MapView(window->getRenderArea()); + mapView = new View::MapView(view); window->getMapArea()->setView(mapView); 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)); + button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), 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)); + button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), -2, 0, 0)); if(file.empty()) createLevel(); @@ -136,13 +136,11 @@ void Instance::createLevel() { level = new Data::Level(root); view->setLevel(level); - mapView->setLevel(level); } bool Instance::loadLevel(const Glib::ustring &file) { if(level) { view->setLevel(0); - mapView->setLevel(0); delete level; level = 0; } @@ -162,7 +160,6 @@ bool Instance::loadLevel(const Glib::ustring &file) { level = new Data::Level(doc->get_root_node()); view->setLevel(level); - mapView->setLevel(level); return true; } diff --git a/src/View/MapView.cpp b/src/View/MapView.cpp index 5727c86..1d074bc 100644 --- a/src/View/MapView.cpp +++ b/src/View/MapView.cpp @@ -30,22 +30,51 @@ namespace ZoomEdit { namespace View { -void MapView::zoom(Gui::RenderArea*, int zoom, float, float) { - if(!mainArea) - return; +void MapView::setMainView(TopView *mainView0) { + mainView = mainView0; - TopView *mainView = dynamic_cast(mainArea->getView()); - if(!mainView) + if(mainViewUpdate) + mainViewUpdate.disconnect(); + + if(mainView) + mainViewUpdate = mainView->signalUpdate().connect(signalUpdate()); +} + +void MapView::init() { + glClearColor(0, 0, 0, 0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glEnable(GL_LINE_SMOOTH); + glEnable(GL_POINT_SMOOTH); +} + +void MapView::resize(float width, float height) { + if(width == viewWidth && height == viewHeight) return; - mainView->zoom(mainArea, zoom, 0, 0); + viewWidth = width; viewHeight = height; + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if(width != 0 && height != 0) + glScalef(2.0f/width, -2.0f/height, 1); + + signalUpdate().emit(); } -void MapView::move(Gui::RenderArea*, float x, float y, unsigned int state) { - if(!mainArea) +void MapView::zoom(int zoom, float, float) { + if(!mainView) return; - TopView *mainView = dynamic_cast(mainArea->getView()); + mainView->zoom(zoom, 0, 0); +} + +void MapView::move(float x, float y, unsigned int state) { if(!mainView) return; @@ -54,28 +83,20 @@ void MapView::move(Gui::RenderArea*, float x, float y, unsigned int state) { mainView->setXCenter(mainView->getXCenter() - x/scale); mainView->setYCenter(mainView->getYCenter() - y/scale); - - mainArea->queue_draw(); } -void MapView::click(Gui::RenderArea *renderArea, float x, float y) { - if(!mainArea) - return; - - TopView *mainView = dynamic_cast(mainArea->getView()); +void MapView::click(float x, float y) { if(!mainView) return; - mainView->setXCenter(xCenter + (x - renderArea->get_width()/2)/scale); - mainView->setYCenter(yCenter + (y - renderArea->get_height()/2)/scale); - - mainArea->queue_draw(); + mainView->setXCenter(xCenter + (x - viewWidth/2)/scale); + mainView->setYCenter(yCenter + (y - viewHeight/2)/scale); } -void MapView::render(Gui::RenderArea *renderArea) { +void MapView::render() { glClear(GL_COLOR_BUFFER_BIT); - if(!level) + if(!mainView || !mainView->getLevel()) return; float minX, maxX, minY, maxY; @@ -87,7 +108,7 @@ void MapView::render(Gui::RenderArea *renderArea) { if(width == 0 || height == 0) return; - scale = std::min(renderArea->get_width()/width, renderArea->get_height()/height)*0.75f; + scale = std::min(viewWidth/width, viewHeight/height)*0.75f; glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -95,44 +116,38 @@ void MapView::render(Gui::RenderArea *renderArea) { glScalef(scale, scale, 1); glTranslatef(-xCenter, -yCenter, 0); - const std::list &rooms = level->getRooms(); + const std::list &rooms = mainView->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) TopView::renderRoom(*room); - if(mainArea) { - TopView *mainView = dynamic_cast(mainArea->getView()); - - if(mainView) { - float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter(); - float mainScale = mainView->getScale(); - - float mainWidth = mainArea->get_width()/mainScale, mainHeight = mainArea->get_height()/mainScale; - - glColor4f(0.7f, 0.7f, 0.7f, 0.3f); - - glBegin(GL_POLYGON); - - glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); - glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); - glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); - glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); - - glEnd(); - - glColor4f(0.7f, 0.7f, 0.7f, 0.7f); - glLineWidth(1.0f); - - glBegin(GL_LINE_LOOP); - - glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); - glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); - glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); - glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); - - glEnd(); - } - } + float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter(); + float mainScale = mainView->getScale(); + + float mainWidth = mainView->getWidth()/mainScale, mainHeight = mainView->getHeight()/mainScale; + + glColor4f(0.7f, 0.7f, 0.7f, 0.3f); + + glBegin(GL_POLYGON); + + glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); + glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); + glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); + glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); + + glEnd(); + + glColor4f(0.7f, 0.7f, 0.7f, 0.7f); + glLineWidth(1.0f); + + glBegin(GL_LINE_LOOP); + + glVertex2f(mainXCenter-mainWidth/2, mainYCenter-mainHeight/2); + glVertex2f(mainXCenter+mainWidth/2, mainYCenter-mainHeight/2); + glVertex2f(mainXCenter+mainWidth/2, mainYCenter+mainHeight/2); + glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); + + glEnd(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); @@ -148,10 +163,10 @@ void MapView::getBounds(float *minX, float *maxX, float *minY, float *maxY) { if(maxY) *maxY = 0; - if(!level) + if(!mainView || !mainView->getLevel()) return; - const std::list &rooms = level->getRooms(); + const std::list &rooms = mainView->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { const std::list &triangles = (*room)->getFloorTriangles(); diff --git a/src/View/MapView.h b/src/View/MapView.h index 2fb0df4..e34cae5 100644 --- a/src/View/MapView.h +++ b/src/View/MapView.h @@ -21,6 +21,7 @@ #define ZOOMEDIT_VIEW_MAPVIEW_H_ #include "View.h" +#include namespace ZoomEdit { @@ -34,29 +35,33 @@ class TopView; class MapView : public View { private: - Data::Level *level; + sigc::connection mainViewUpdate; - Gui::RenderArea *mainArea; + float viewWidth, viewHeight; + + TopView *mainView; float scale, xCenter, yCenter; void getBounds(float *minX, float *maxX, float *minY, float *maxY); public: - MapView(Gui::RenderArea *mainArea0 = 0, Data::Level *level0 = 0) - : level(level0), mainArea(mainArea0), scale(1), xCenter(0), yCenter(0) {} + MapView(TopView *mainView0 = 0) + : mainView(0), scale(1), xCenter(0), yCenter(0) { + setMainView(mainView0); + } - Data::Level* getLevel() {return level;} - void setLevel(Data::Level *level0) {level = level0;} + TopView* getMainView() {return mainView;} + void setMainView(TopView *mainView0); - Gui::RenderArea* getMainArea() {return mainArea;} - void setMainArea(Gui::RenderArea *mainArea0) {mainArea = mainArea0;} + virtual void init(); + virtual void resize(float width, float height); - virtual void zoom(Gui::RenderArea*, int zoom, float, float); - virtual void move(Gui::RenderArea*, float x, float y, unsigned int state); - virtual void click(Gui::RenderArea *renderArea, float x, float y); + virtual void render(); - virtual void render(Gui::RenderArea *renderArea); + virtual void zoom(int zoom, float, float); + virtual void move(float x, float y, unsigned int state); + virtual void click(float x, float y); }; } diff --git a/src/View/TopView.cpp b/src/View/TopView.cpp index 29fc242..9ce6039 100644 --- a/src/View/TopView.cpp +++ b/src/View/TopView.cpp @@ -58,12 +58,12 @@ bool TopView::Edge::operator<(const Edge &e) const { return false; } -void TopView::drawGrid(Gui::RenderArea *renderArea) { +void TopView::drawGrid() { float depth = 1.25f + 0.04f*zoomLevel; float depth2 = std::floor(depth); float step = std::pow(0.1f, depth2); - float width = renderArea->get_width()/scale; - float height = renderArea->get_height()/scale; + float width = viewWidth/scale; + float height = viewHeight/scale; float x1 = xCenter - width/2; float x2 = xCenter + width/2; @@ -140,7 +140,34 @@ void TopView::renderRoom(Data::Room *room) { glEnd(); } -void TopView::zoom(Gui::RenderArea *renderArea, int zoom, float x, float y) { +void TopView::init() { + glClearColor(0, 0, 0, 0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glEnable(GL_LINE_SMOOTH); + glEnable(GL_POINT_SMOOTH); +} + +void TopView::resize(float width, float height) { + if(width == viewWidth && height == viewHeight) + return; + + viewWidth = width; viewHeight = height; + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if(width != 0 && height != 0) + glScalef(2.0f/width, -2.0f/height, 1); + + signalUpdate().emit(); +} + +void TopView::zoom(int zoom, float x, float y) { const float oldScale = scale; zoomLevel = std::max(std::min(zoomLevel + zoom, 50), -100); @@ -149,29 +176,29 @@ void TopView::zoom(Gui::RenderArea *renderArea, int zoom, float x, float y) { xCenter += x*(1/oldScale - 1/scale); yCenter += y*(1/oldScale - 1/scale); - renderArea->queue_draw(); + signalUpdate().emit(); } -void TopView::move(Gui::RenderArea *renderArea, float x, float y, unsigned int state) { +void TopView::move(float x, float y, unsigned int state) { if(!(state & GDK_BUTTON3_MASK)) return; xCenter += x/scale; yCenter += y/scale; - renderArea->queue_draw(); + signalUpdate().emit(); } -void TopView::render(Gui::RenderArea *renderArea) { +void TopView::render() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + glLoadIdentity(); glScalef(scale, scale, 1); glTranslatef(-xCenter, -yCenter, 0); - drawGrid(renderArea); + drawGrid(); if(!level) return; @@ -180,9 +207,6 @@ void TopView::render(Gui::RenderArea *renderArea) { for(std::list::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 1fa81ad..abbb77b 100644 --- a/src/View/TopView.h +++ b/src/View/TopView.h @@ -45,30 +45,38 @@ class TopView : public View { Data::Level *level; + float viewWidth, viewHeight; + float xCenter, yCenter; int zoomLevel; float scale; - void drawGrid(Gui::RenderArea *renderArea); + void drawGrid(); public: - TopView(Data::Level *level0 = 0) : level(level0), xCenter(0), yCenter(0), zoomLevel(0), scale(100) {} + TopView(Data::Level *level0 = 0) : level(level0), viewWidth(0), viewHeight(0), xCenter(0), yCenter(0), zoomLevel(0), scale(100) {} + + float getWidth() const {return viewWidth;} + float getHeight() const {return viewHeight;} float getXCenter() const {return xCenter;} - void setXCenter(float xCenter0) {xCenter = xCenter0;} + void setXCenter(float xCenter0) {xCenter = xCenter0; signalUpdate().emit();} float getYCenter() const {return yCenter;} - void setYCenter(float yCenter0) {yCenter = yCenter0;} + void setYCenter(float yCenter0) {yCenter = yCenter0; signalUpdate().emit();} float getScale() const {return scale;} Data::Level* getLevel() {return level;} - void setLevel(Data::Level *level0) {level = level0;} + void setLevel(Data::Level *level0) {level = level0; signalUpdate().emit();} + + virtual void init(); + virtual void resize(float width, float height); - virtual void zoom(Gui::RenderArea *renderArea, int zoom, float x, float y); - virtual void move(Gui::RenderArea *renderArea, float x, float y, unsigned int state); + virtual void render(); - virtual void render(Gui::RenderArea *renderArea); + virtual void zoom(int zoom, float x, float y); + virtual void move(float x, float y, unsigned int state); static void renderRoom(Data::Room *room); }; diff --git a/src/View/View.h b/src/View/View.h index 446a4f6..56e2542 100644 --- a/src/View/View.h +++ b/src/View/View.h @@ -20,23 +20,28 @@ #ifndef ZOOMEDIT_VIEW_VIEW_H_ #define ZOOMEDIT_VIEW_VIEW_H_ -namespace ZoomEdit { - -namespace Gui { -class RenderArea; -} +#include +namespace ZoomEdit { namespace View { class View { + private: + sigc::signal update; + public: virtual ~View() {} - virtual void render(Gui::RenderArea *renderArea) = 0; + virtual void init() = 0; + virtual void resize(float width, float height) = 0; + + virtual void render() = 0; + + virtual void zoom(int, float, float) {} + virtual void move(float, float, unsigned int) {} + virtual void click(float, float) {} - virtual void zoom(Gui::RenderArea*, int, float, float) {} - virtual void move(Gui::RenderArea*, float, float, unsigned int) {} - virtual void click(Gui::RenderArea*, float, float) {} + sigc::signal signalUpdate() const {return update;} }; } -- cgit v1.2.3