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 <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,35 +133,22 @@ bool RenderArea::onLeaveNotifyEvent(GdkEventCrossing*) {
}
bool RenderArea::onMotionNotifyEvent(GdkEventMotion *event) {
inWindow = true;
if(!inWindow) {
xHover = event->x;
yHover = event->y;
inWindow = true;
return 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(event->state & GDK_BUTTON3_MASK && view)
view->move(this, xHover - event->x, yHover - event->y);
xHover = event->x;
yHover = event->y;
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 {
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());

View file

@ -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

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) {
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();
}
}

View file

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

View file

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

View file

@ -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>