zoomedit:

* Moved much stuff from RenderArea to TopView to make MapView possible
* Created MapView class
This commit is contained in:
neoraider 2008-04-20 00:08:05 +00:00
parent c771232b74
commit 12ebbe18e1
9 changed files with 200 additions and 97 deletions

View file

@ -22,8 +22,6 @@
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#include <cmath> #include <cmath>
#include <gtkmm/toolbutton.h>
#include <gtkmm/adjustment.h>
#include <GL/gl.h> #include <GL/gl.h>
namespace ZoomEdit { namespace ZoomEdit {
@ -31,9 +29,8 @@ namespace Gui {
GdkGLConfig *RenderArea::glconfig = 0; GdkGLConfig *RenderArea::glconfig = 0;
RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml> &xml) RenderArea::RenderArea(BaseObjectType *cobject, const Glib::RefPtr<Gnome::Glade::Xml>&)
: Gtk::DrawingArea(cobject), view(0), xCenter(0), yCenter(0), viewWidth(0), viewHeight(0), zoomLevel(0), : Gtk::DrawingArea(cobject), view(0), inWindow(false) {
scale(100), inWindow(false) {
if(!glconfig) { if(!glconfig) {
glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)(GDK_GL_MODE_RGB | GDK_GL_MODE_DOUBLE)); 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 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_leave_notify_event().connect(sigc::mem_fun(this, &RenderArea::onLeaveNotifyEvent));
signal_motion_notify_event().connect(sigc::mem_fun(this, &RenderArea::onMotionNotifyEvent)); 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); gtk_widget_set_gl_capability(GTK_WIDGET(cobject), glconfig, 0, TRUE, GDK_GL_RGBA_TYPE);
} }
@ -93,9 +83,6 @@ bool RenderArea::onConfigureEvent(GdkEventConfigure*) {
gdkGLEnd(); gdkGLEnd();
viewWidth = get_width()/scale;
viewHeight = get_height()/scale;
queue_draw(); queue_draw();
return true; return true;
@ -105,20 +92,9 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) {
if(!gdkGLBegin()) if(!gdkGLBegin())
return false; return false;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glScalef(scale, scale, 1);
glTranslatef(-xCenter, -yCenter, 0);
if(view) if(view)
view->render(this); view->render(this);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
gdkSwapBuffers(); gdkSwapBuffers();
gdkGLEnd(); gdkGLEnd();
@ -126,22 +102,26 @@ bool RenderArea::onExposeEvent(GdkEventExpose*) {
} }
bool RenderArea::onScrollEvent(GdkEventScroll *event) { bool RenderArea::onScrollEvent(GdkEventScroll *event) {
if(view) {
switch(event->direction) { switch(event->direction) {
case GDK_SCROLL_UP: case GDK_SCROLL_UP:
zoom(1, event->x/get_width(), event->y/get_height()); view->zoom(this, 1, event->x - get_width()/2, event->y - get_height()/2);
return true; return true;
case GDK_SCROLL_DOWN: case GDK_SCROLL_DOWN:
zoom(-1, event->x/get_width(), event->y/get_height()); view->zoom(this, -1, event->x - get_width()/2, event->y - get_height()/2);
return true; return true;
default: default:
return false; return false;
} }
}
return false;
} }
bool RenderArea::onEnterNotifyEvent(GdkEventCrossing *event) { bool RenderArea::onEnterNotifyEvent(GdkEventCrossing *event) {
inWindow = true; inWindow = true;
xHover = event->x/scale - getViewWidth()/2 + xCenter; xHover = event->x;
yHover = event->y/scale - getViewHeight()/2 + yCenter; yHover = event->y;
return true; return true;
} }
@ -153,35 +133,22 @@ bool RenderArea::onLeaveNotifyEvent(GdkEventCrossing*) {
} }
bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) { bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) {
if(!inWindow) {
xHover = event->x;
yHover = event->y;
inWindow = true; inWindow = true;
if(event->state & GDK_BUTTON3_MASK) { return true;
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(event->state & GDK_BUTTON3_MASK && view)
view->move(this, xHover - event->x, yHover - event->y);
xHover = event->x;
yHover = event->y;
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);
viewWidth = newWidth;
viewHeight = newHeight;
queue_draw();
}
} }
} }

View file

@ -35,7 +35,7 @@ namespace Gui {
class RenderArea : public Gtk::DrawingArea { class RenderArea : public Gtk::DrawingArea {
public: 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;} View::View* getView() const {return view;}
void setView(View::View *view0) { void setView(View::View *view0) {
@ -43,32 +43,13 @@ class RenderArea : public Gtk::DrawingArea {
queue_draw(); 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: private:
static GdkGLConfig *glconfig; static GdkGLConfig *glconfig;
View::View *view; View::View *view;
float xCenter, yCenter;
float viewWidth, viewHeight;
int zoomLevel;
float scale;
bool inWindow; bool inWindow;
float xHover, yHover; gdouble xHover, yHover;
void onRealize(); void onRealize();
bool onConfigureEvent(GdkEventConfigure*); bool onConfigureEvent(GdkEventConfigure*);
@ -78,8 +59,6 @@ class RenderArea : public Gtk::DrawingArea {
bool onLeaveNotifyEvent(GdkEventCrossing*); bool onLeaveNotifyEvent(GdkEventCrossing*);
bool onMotionNotifyEvent(GdkEventMotion *event); bool onMotionNotifyEvent(GdkEventMotion *event);
void zoom(int zoom, float x = 0.5f, float y = 0.5f);
bool gdkGLBegin() { bool gdkGLBegin() {
GtkWidget *widget = GTK_WIDGET(gobj()); GtkWidget *widget = GTK_WIDGET(gobj());

View file

@ -21,6 +21,7 @@
#include <iostream> #include <iostream>
#include <libxml++/validators/dtdvalidator.h> #include <libxml++/validators/dtdvalidator.h>
#include <libxml/tree.h> #include <libxml/tree.h>
#include <gtkmm/toolbutton.h>
#include <Gui/Window.h> #include <Gui/Window.h>
#include <Gui/RenderArea.h> #include <Gui/RenderArea.h>
#include <Data/Level.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(); view = new View::TopView();
window->getRenderArea()->setView(view); 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()) if(file.empty())
createLevel(); createLevel();
else else

30
src/View/MapView.cpp Normal file
View file

@ -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) {
}
}
}

49
src/View/MapView.h Normal file
View file

@ -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_*/

View file

@ -59,18 +59,16 @@ bool TopView::Edge::operator<(const Edge &e) const {
} }
void TopView::drawGrid(Gui::RenderArea *renderArea) { 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 depth2 = std::floor(depth);
float step = std::pow(0.1f, depth2); float step = std::pow(0.1f, depth2);
float x1, x2; float width = renderArea->get_width()/scale;
float y1, y2; float height = renderArea->get_height()/scale;
float width = renderArea->getViewWidth();
float height = renderArea->getViewHeight();
x1 = x2 = renderArea->getXCenter(); float x1 = xCenter - width/2;
y1 = y2 = renderArea->getYCenter(); float x2 = xCenter + width/2;
x1 -= width/2; x2 += width/2; float y1 = yCenter - height/2;
y1 -= height/2; y2 += height/2; float y2 = yCenter + height/2;
glLineWidth(1.0f); glLineWidth(1.0f);
@ -142,7 +140,34 @@ void TopView::renderRoom(Data::Room *room) {
glEnd(); 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) { 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); drawGrid(renderArea);
if(!level) 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) 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,15 +45,29 @@ class TopView : public View {
Data::Level *level; 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 drawGrid(Gui::RenderArea *renderArea);
void renderRoom(Data::Room *room); void renderRoom(Data::Room *room);
public: 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;} Data::Level* getLevel() {return level;}
void setLevel(Data::Level *level0) {level = level0;} 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); virtual void render(Gui::RenderArea *renderArea);
}; };

View file

@ -33,6 +33,9 @@ class View {
virtual ~View() {} virtual ~View() {}
virtual void render(Gui::RenderArea *renderArea) = 0; virtual void render(Gui::RenderArea *renderArea) = 0;
virtual void zoom(Gui::RenderArea*, int, float, float) {}
virtual void move(Gui::RenderArea*, float, float) {}
}; };
} }

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> <!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> <glade-interface>
<widget class="GtkWindow" id="WindowMain"> <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> <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="visible">True</property>
<property name="can_focus">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="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> <child>
<widget class="GtkDrawingArea" id="RenderArea"> <widget class="GtkDrawingArea" id="RenderArea">
<property name="visible">True</property> <property name="visible">True</property>
@ -211,7 +212,31 @@
</packing> </packing>
</child> </child>
<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> </child>
</widget> </widget>
<packing> <packing>