zoomedit:

* Use signals to inform RenderArea of view changes
This commit is contained in:
neoraider 2008-05-05 19:26:05 +00:00
parent 1d6f52984d
commit 36d892d1f0
10 changed files with 198 additions and 145 deletions

View file

@ -52,35 +52,45 @@ RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade:
gtk_widget_set_gl_capability(GTK_WIDGET(cobject), glconfig, 0, TRUE, GDK_GL_RGBA_TYPE); gtk_widget_set_gl_capability(GTK_WIDGET(cobject), glconfig, 0, TRUE, GDK_GL_RGBA_TYPE);
} }
void RenderArea::setView(View::View *view0) {
view = view0;
if(viewUpdate)
viewUpdate.disconnect();
if(view) {
viewUpdate = view->signalUpdate().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() { void RenderArea::onRealize() {
if(!gdkGLBegin()) if(!gdkGLBegin())
return; return;
glClearColor(0, 0, 0, 0); if(view)
view->init();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gdkGLEnd(); gdkGLEnd();
} }
bool RenderArea::onConfigureEvent(GdkEventConfigure*) { bool RenderArea::onConfigureEvent(GdkEventConfigure *event) {
if(!gdkGLBegin()) if(!gdkGLBegin())
return false; return false;
glViewport(0, 0, get_width(), get_height()); if(view)
view->resize(event->width, event->height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(get_width() != 0 && get_height() != 0)
glScalef(2.0f/get_width(), -2.0f/get_height(), 1);
gdkGLEnd(); gdkGLEnd();
@ -94,7 +104,7 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) {
return false; return false;
if(view) if(view)
view->render(this); view->render();
gdkSwapBuffers(); gdkSwapBuffers();
gdkGLEnd(); gdkGLEnd();
@ -106,10 +116,10 @@ bool RenderArea::onScrollEvent(GdkEventScroll *event) {
if(view) { if(view) {
switch(event->direction) { switch(event->direction) {
case GDK_SCROLL_UP: 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; return true;
case GDK_SCROLL_DOWN: 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; return true;
default: default:
return false; return false;
@ -121,7 +131,7 @@ bool RenderArea::onScrollEvent(GdkEventScroll *event) {
bool RenderArea::onButtonPressEvent(GdkEventButton *event) { bool RenderArea::onButtonPressEvent(GdkEventButton *event) {
if(view && event->button == 1) if(view && event->button == 1)
view->click(this, event->x, event->y); view->click(event->x, event->y);
return true; return true;
} }
@ -150,7 +160,7 @@ bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) {
} }
if(view) 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; xHover = event->x;
yHover = event->y; yHover = event->y;

View file

@ -38,21 +38,20 @@ class RenderArea : public Gtk::DrawingArea {
RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml>&); RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml>&);
View::View* getView() const {return view;} View::View* getView() const {return view;}
void setView(View::View *view0) { void setView(View::View *view0);
view = view0;
queue_draw();
}
private: private:
static GdkGLConfig *glconfig; static GdkGLConfig *glconfig;
View::View *view; View::View *view;
sigc::connection viewUpdate;
bool inWindow; bool inWindow;
gdouble xHover, yHover; gdouble xHover, yHover;
void onRealize(); void onRealize();
bool onConfigureEvent(GdkEventConfigure*); bool onConfigureEvent(GdkEventConfigure *event);
bool onExposeEvent(GdkEventExpose*); bool onExposeEvent(GdkEventExpose*);
bool onScrollEvent(GdkEventScroll *event); bool onScrollEvent(GdkEventScroll *event);
bool onButtonPressEvent(GdkEventButton *event); bool onButtonPressEvent(GdkEventButton *event);

View file

@ -29,9 +29,6 @@ Window::Window(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &x
xml->get_widget_derived("RenderArea", renderArea); xml->get_widget_derived("RenderArea", renderArea);
xml->get_widget_derived("MapArea", mapArea); xml->get_widget_derived("MapArea", mapArea);
if(renderArea)
renderArea->signal_expose_event().connect_notify(sigc::mem_fun(this, &Window::updateMap));
} }
Window::~Window() { Window::~Window() {
@ -42,10 +39,5 @@ Window::~Window() {
delete mapArea; delete mapArea;
} }
void Window::updateMap(GdkEventExpose*) {
if(mapArea)
mapArea->queue_draw();
}
} }
} }

View file

@ -32,8 +32,6 @@ class Window : public Gtk::Window {
private: private:
RenderArea *renderArea, *mapArea; RenderArea *renderArea, *mapArea;
void updateMap(GdkEventExpose*);
public: public:
Window(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml); Window(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml);
virtual ~Window(); virtual ~Window();

View file

@ -66,15 +66,15 @@ Instance::Instance(const Glib::ustring &file) : window(0), levelXml(0), level(0)
view = new View::TopView(); view = new View::TopView();
window->getRenderArea()->setView(view); window->getRenderArea()->setView(view);
mapView = new View::MapView(window->getRenderArea()); mapView = new View::MapView(view);
window->getMapArea()->setView(mapView); window->getMapArea()->setView(mapView);
Gtk::ToolButton *button; Gtk::ToolButton *button;
xml->get_widget("ToolButtonZoomIn", 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); 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()) if(file.empty())
createLevel(); createLevel();
@ -136,13 +136,11 @@ void Instance::createLevel() {
level = new Data::Level(root); level = new Data::Level(root);
view->setLevel(level); view->setLevel(level);
mapView->setLevel(level);
} }
bool Instance::loadLevel(const Glib::ustring &file) { bool Instance::loadLevel(const Glib::ustring &file) {
if(level) { if(level) {
view->setLevel(0); view->setLevel(0);
mapView->setLevel(0);
delete level; delete level;
level = 0; level = 0;
} }
@ -162,7 +160,6 @@ bool Instance::loadLevel(const Glib::ustring &file) {
level = new Data::Level(doc->get_root_node()); level = new Data::Level(doc->get_root_node());
view->setLevel(level); view->setLevel(level);
mapView->setLevel(level);
return true; return true;
} }

View file

@ -30,22 +30,51 @@
namespace ZoomEdit { namespace ZoomEdit {
namespace View { namespace View {
void MapView::zoom(Gui::RenderArea*, int zoom, float, float) { void MapView::setMainView(TopView *mainView0) {
if(!mainArea) mainView = mainView0;
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; return;
TopView *mainView = dynamic_cast<TopView*>(mainArea->getView()); 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::zoom(int zoom, float, float) {
if(!mainView) if(!mainView)
return; return;
mainView->zoom(mainArea, zoom, 0, 0); mainView->zoom(zoom, 0, 0);
} }
void MapView::move(Gui::RenderArea*, float x, float y, unsigned int state) { void MapView::move(float x, float y, unsigned int state) {
if(!mainArea)
return;
TopView *mainView = dynamic_cast<TopView*>(mainArea->getView());
if(!mainView) if(!mainView)
return; return;
@ -54,28 +83,20 @@ void MapView::move(Gui::RenderArea*, float x, float y, unsigned int state) {
mainView->setXCenter(mainView->getXCenter() - x/scale); mainView->setXCenter(mainView->getXCenter() - x/scale);
mainView->setYCenter(mainView->getYCenter() - y/scale); mainView->setYCenter(mainView->getYCenter() - y/scale);
mainArea->queue_draw();
} }
void MapView::click(Gui::RenderArea *renderArea, float x, float y) { void MapView::click(float x, float y) {
if(!mainArea)
return;
TopView *mainView = dynamic_cast<TopView*>(mainArea->getView());
if(!mainView) if(!mainView)
return; return;
mainView->setXCenter(xCenter + (x - renderArea->get_width()/2)/scale); mainView->setXCenter(xCenter + (x - viewWidth/2)/scale);
mainView->setYCenter(yCenter + (y - renderArea->get_height()/2)/scale); mainView->setYCenter(yCenter + (y - viewHeight/2)/scale);
mainArea->queue_draw();
} }
void MapView::render(Gui::RenderArea *renderArea) { void MapView::render() {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
if(!level) if(!mainView || !mainView->getLevel())
return; return;
float minX, maxX, minY, maxY; float minX, maxX, minY, maxY;
@ -87,7 +108,7 @@ void MapView::render(Gui::RenderArea *renderArea) {
if(width == 0 || height == 0) if(width == 0 || height == 0)
return; 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); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
@ -95,19 +116,15 @@ void MapView::render(Gui::RenderArea *renderArea) {
glScalef(scale, scale, 1); glScalef(scale, scale, 1);
glTranslatef(-xCenter, -yCenter, 0); glTranslatef(-xCenter, -yCenter, 0);
const std::list<Data::Room*> &rooms = level->getRooms(); const std::list<Data::Room*> &rooms = mainView->getLevel()->getRooms();
for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room) for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room)
TopView::renderRoom(*room); TopView::renderRoom(*room);
if(mainArea) {
TopView *mainView = dynamic_cast<TopView*>(mainArea->getView());
if(mainView) {
float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter(); float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter();
float mainScale = mainView->getScale(); float mainScale = mainView->getScale();
float mainWidth = mainArea->get_width()/mainScale, mainHeight = mainArea->get_height()/mainScale; float mainWidth = mainView->getWidth()/mainScale, mainHeight = mainView->getHeight()/mainScale;
glColor4f(0.7f, 0.7f, 0.7f, 0.3f); glColor4f(0.7f, 0.7f, 0.7f, 0.3f);
@ -131,8 +148,6 @@ void MapView::render(Gui::RenderArea *renderArea) {
glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2); glVertex2f(mainXCenter-mainWidth/2, mainYCenter+mainHeight/2);
glEnd(); glEnd();
}
}
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPopMatrix(); glPopMatrix();
@ -148,10 +163,10 @@ void MapView::getBounds(float *minX, float *maxX, float *minY, float *maxY) {
if(maxY) if(maxY)
*maxY = 0; *maxY = 0;
if(!level) if(!mainView || !mainView->getLevel())
return; return;
const std::list<Data::Room*> &rooms = level->getRooms(); const std::list<Data::Room*> &rooms = mainView->getLevel()->getRooms();
for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room) {
const std::list<Data::Triangle*> &triangles = (*room)->getFloorTriangles(); const std::list<Data::Triangle*> &triangles = (*room)->getFloorTriangles();

View file

@ -21,6 +21,7 @@
#define ZOOMEDIT_VIEW_MAPVIEW_H_ #define ZOOMEDIT_VIEW_MAPVIEW_H_
#include "View.h" #include "View.h"
#include <sigc++/connection.h>
namespace ZoomEdit { namespace ZoomEdit {
@ -34,29 +35,33 @@ class TopView;
class MapView : public View { class MapView : public View {
private: private:
Data::Level *level; sigc::connection mainViewUpdate;
Gui::RenderArea *mainArea; float viewWidth, viewHeight;
TopView *mainView;
float scale, xCenter, yCenter; float scale, xCenter, yCenter;
void getBounds(float *minX, float *maxX, float *minY, float *maxY); void getBounds(float *minX, float *maxX, float *minY, float *maxY);
public: public:
MapView(Gui::RenderArea *mainArea0 = 0, Data::Level *level0 = 0) MapView(TopView *mainView0 = 0)
: level(level0), mainArea(mainArea0), scale(1), xCenter(0), yCenter(0) {} : mainView(0), scale(1), xCenter(0), yCenter(0) {
setMainView(mainView0);
}
Data::Level* getLevel() {return level;} TopView* getMainView() {return mainView;}
void setLevel(Data::Level *level0) {level = level0;} void setMainView(TopView *mainView0);
Gui::RenderArea* getMainArea() {return mainArea;} virtual void init();
void setMainArea(Gui::RenderArea *mainArea0) {mainArea = mainArea0;} virtual void resize(float width, float height);
virtual void zoom(Gui::RenderArea*, int zoom, float, float); virtual void render();
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(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);
}; };
} }

View file

@ -58,12 +58,12 @@ bool TopView::Edge::operator<(const Edge &e) const {
return false; return false;
} }
void TopView::drawGrid(Gui::RenderArea *renderArea) { void TopView::drawGrid() {
float depth = 1.25f + 0.04f*zoomLevel; float depth = 1.25f + 0.04f*zoomLevel;
float depth2 = std::floor(depth); float depth2 = std::floor(depth);
float step = std::pow(0.1f, depth2); float step = std::pow(0.1f, depth2);
float width = renderArea->get_width()/scale; float width = viewWidth/scale;
float height = renderArea->get_height()/scale; float height = viewHeight/scale;
float x1 = xCenter - width/2; float x1 = xCenter - width/2;
float x2 = xCenter + width/2; float x2 = xCenter + width/2;
@ -140,7 +140,34 @@ void TopView::renderRoom(Data::Room *room) {
glEnd(); 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; const float oldScale = scale;
zoomLevel = std::max(std::min(zoomLevel + zoom, 50), -100); 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); xCenter += x*(1/oldScale - 1/scale);
yCenter += y*(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)) if(!(state & GDK_BUTTON3_MASK))
return; return;
xCenter += x/scale; xCenter += x/scale;
yCenter += y/scale; yCenter += y/scale;
renderArea->queue_draw(); signalUpdate().emit();
} }
void TopView::render(Gui::RenderArea *renderArea) { void TopView::render() {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glLoadIdentity();
glScalef(scale, scale, 1); glScalef(scale, scale, 1);
glTranslatef(-xCenter, -yCenter, 0); glTranslatef(-xCenter, -yCenter, 0);
drawGrid(renderArea); drawGrid();
if(!level) if(!level)
return; return;
@ -180,9 +207,6 @@ void TopView::render(Gui::RenderArea *renderArea) {
for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room) for(std::list<Data::Room*>::const_iterator room = rooms.begin(); room != rooms.end(); ++room)
renderRoom(*room); renderRoom(*room);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
} }
} }

View file

@ -45,30 +45,38 @@ class TopView : public View {
Data::Level *level; Data::Level *level;
float viewWidth, viewHeight;
float xCenter, yCenter; float xCenter, yCenter;
int zoomLevel; int zoomLevel;
float scale; float scale;
void drawGrid(Gui::RenderArea *renderArea); void drawGrid();
public: 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;} float getXCenter() const {return xCenter;}
void setXCenter(float xCenter0) {xCenter = xCenter0;} void setXCenter(float xCenter0) {xCenter = xCenter0; signalUpdate().emit();}
float getYCenter() const {return yCenter;} float getYCenter() const {return yCenter;}
void setYCenter(float yCenter0) {yCenter = yCenter0;} void setYCenter(float yCenter0) {yCenter = yCenter0; signalUpdate().emit();}
float getScale() const {return scale;} float getScale() const {return scale;}
Data::Level* getLevel() {return level;} Data::Level* getLevel() {return level;}
void setLevel(Data::Level *level0) {level = level0;} void setLevel(Data::Level *level0) {level = level0; signalUpdate().emit();}
virtual void zoom(Gui::RenderArea *renderArea, int zoom, float x, float y); virtual void init();
virtual void move(Gui::RenderArea *renderArea, float x, float y, unsigned int state); virtual void resize(float width, float height);
virtual void render(Gui::RenderArea *renderArea); virtual void render();
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); static void renderRoom(Data::Room *room);
}; };

View file

@ -20,23 +20,28 @@
#ifndef ZOOMEDIT_VIEW_VIEW_H_ #ifndef ZOOMEDIT_VIEW_VIEW_H_
#define ZOOMEDIT_VIEW_VIEW_H_ #define ZOOMEDIT_VIEW_VIEW_H_
#include <sigc++/signal.h>
namespace ZoomEdit { namespace ZoomEdit {
namespace Gui {
class RenderArea;
}
namespace View { namespace View {
class View { class View {
private:
sigc::signal<void> update;
public: public:
virtual ~View() {} virtual ~View() {}
virtual void render(Gui::RenderArea *renderArea) = 0; virtual void init() = 0;
virtual void resize(float width, float height) = 0;
virtual void zoom(Gui::RenderArea*, int, float, float) {} virtual void render() = 0;
virtual void move(Gui::RenderArea*, float, float, unsigned int) {}
virtual void click(Gui::RenderArea*, float, float) {} virtual void zoom(int, float, float) {}
virtual void move(float, float, unsigned int) {}
virtual void click(float, float) {}
sigc::signal<void> signalUpdate() const {return update;}
}; };
} }