zoomedit: Use tools for event handling and rendering

This commit is contained in:
neoraider 2007-12-24 00:04:02 +00:00
parent 9b5296b04e
commit 953a6ff48a
18 changed files with 196 additions and 162 deletions

View file

@ -49,7 +49,7 @@ gboolean Drawer::eventHandler(GtkWidget *widget, GdkEvent *event, Drawer *drawer
return TRUE;
case GDK_BUTTON_PRESS:
drawer->window->getEditManager().buttonPress(event->button.button);
drawer->window->getActiveTool()->getEventHandler()->buttonPress(event->button.button);
return TRUE;
case GDK_SCROLL:
@ -168,6 +168,9 @@ void Drawer::render() {
renderer.render(window->getLevel(), rect, scale);
if(window->getActiveTool()->getRenderer())
window->getActiveTool()->getRenderer()->render(window->getLevel(), rect, scale);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
@ -175,9 +178,7 @@ void Drawer::render() {
gdk_gl_drawable_gl_end(drawable);
}
Drawer::Drawer(Window *window, GdkGLConfig *glconfig)
: renderer(&window->getEditManager())
{
Drawer::Drawer(Window *window, GdkGLConfig *glconfig) : renderer(&window->getEditManager()) {
this->window = window;
zoomExp = 0;
scale = 100;

View file

@ -16,10 +16,10 @@ class Drawer {
GtkAdjustment *hAdjustment, *vAdjustment;
int zoomExp;
Renderer renderer;
Window *window;
Renderer renderer;
float scale;
float xCenter, yCenter;

View file

@ -2,7 +2,7 @@
#include "Window.h"
bool EditManager::lineOk(const Line& l) const {
bool EditManager::lineOk(const Room &newRoom, const Line &l) const {
Line l2;
for(size_t i = 0; i+2 < newRoom.size(); i++) {
@ -30,10 +30,8 @@ bool EditManager::lineOk(const Line& l) const {
EditManager::EditManager(Window *window) {
this->window = window;
selectedObject = NULL;
mode = VIEW;
hoveredObject = NULL;
selectedObject = NULL;
hasHoveredVertex = false;
}
@ -42,40 +40,18 @@ void EditManager::redraw() {
window->redraw();
}
void EditManager::addRoom() {
if(mode == VIEW) {
newRoom = Room();
mode = ADD;
bool EditManager::addRoom(const Room &newRoom) {
if(newRoom.size() > 2 && polygonOk(newRoom)) {
Room *room = new Room(newRoom);
room->setName(idManager.generate("room"));
selectedObject = &newRoom;
window->getLevel().push_back(SharedPtr<LevelObject>(room));
selectedObject = &*window->getLevel().back();
window->update();
return true;
}
}
void EditManager::finishRoom() {
if(mode == ADD) {
mode = VIEW;
if(newRoom.size() > 2 && polygonOk(newRoom)) {
newRoom.setName(idManager.generate("room"));
window->getLevel().push_back(SharedPtr<LevelObject>(new Room(newRoom)));
selectedObject = &*window->getLevel().back();
}
else {
selectedObject = NULL;
}
window->update();
}
}
void EditManager::addVertex(const Vertex &v) {
if(mode != ADD)
return;
newRoom.push_back(v);
window->update();
return false;
}
Vertex* EditManager::getHoveredVertex() {
@ -107,27 +83,7 @@ void EditManager::setHoveredVertex(Vertex *v) {
window->update();
}
void EditManager::buttonPress(unsigned int button) {
switch(button) {
case 1:
if(!hasHoveredVertex)
break;
switch(mode) {
case VIEW:
selectedObject = hoveredObject;
break;
case ADD:
if(vertexOk(hoveredVertex))
addVertex(hoveredVertex);
}
window->update();
}
}
bool EditManager::vertexOk(const Vertex& v) const {
bool EditManager::vertexOk(const Room &newRoom, const Vertex &v) const {
Line l;
for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) {
@ -140,7 +96,7 @@ bool EditManager::vertexOk(const Vertex& v) const {
l.setVertex1(newRoom.back());
l.setVertex2(v);
return lineOk(l);
return lineOk(newRoom, l);
}
bool EditManager::polygonOk(const Polygon& polygon) const {

View file

@ -10,57 +10,43 @@ class Window;
class EditManager {
public:
enum Mode {
VIEW, ADD
};
private:
Mode mode;
IdManager idManager;
Window *window;
Room newRoom;
LevelObject *selectedObject;
LevelObject *hoveredObject;
LevelObject *selectedObject;
Vertex hoveredVertex;
bool hasHoveredVertex;
bool lineOk(const Line& l) const;
bool lineOk(const Room &newRoom, const Line &l) const;
public:
EditManager(Window *window);
void redraw();
void addRoom();
void finishRoom();
LevelObject* getHoveredObject() {
return hoveredObject;
}
void addVertex(const Vertex &v);
Mode getMode() const {
return mode;
void setSelectedObject(LevelObject *object) {
selectedObject = object;
}
LevelObject* getSelectedObject() {
return selectedObject;
}
LevelObject* getHoveredObject() {
return hoveredObject;
}
bool addRoom(const Room &room);
Vertex* getHoveredVertex();
void setHoveredVertex(Vertex *v);
void buttonPress(unsigned int button);
bool vertexOk(const Vertex& v) const;
bool polygonOk(const Polygon& polygon) const;
bool vertexOk(const Room &newRoom, const Vertex &v) const;
bool polygonOk(const Polygon &polygon) const;
};
#endif /*EDITMANAGER_H_*/

11
EventHandler.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef EVENTHANDLER_H_
#define EVENTHANDLER_H_
class EventHandler {
public:
virtual ~EventHandler() {}
virtual bool buttonPress(unsigned int button) = 0;
};
#endif /*EVENTHANDLER_H_*/

View file

@ -126,7 +126,7 @@ void Renderer::renderRoom(const Room &room, bool selected, bool hovered, float s
glColor4f(1.0f, 1.0f, 1.0f, 0.9f);
glLineWidth(2.0f);
}
else if(hovered && editManager->getMode() == EditManager::VIEW) {
else if(hovered) {
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
glLineWidth(2.0f);
}
@ -143,7 +143,7 @@ void Renderer::renderPlayerStart(const PlayerStart &start, bool selected, bool h
glColor4f(1.0f, 1.0f, 1.0f, 0.9f);
glLineWidth(2.0f);
}
else if(hovered && editManager->getMode() == EditManager::VIEW) {
else if(hovered) {
glColor4f(0.0f, 0.7f, 0.7f, 0.7f);
glLineWidth(2.0f);
}
@ -170,31 +170,4 @@ void Renderer::render(const Level &level, const Rectangle &rect, float scale) {
renderObject(**object, (&**object == editManager->getSelectedObject()),
(&**object == editManager->getHoveredObject()), scale);
}
if(editManager->getMode() == EditManager::ADD) {
Room *activeRoom = (Room*)editManager->getSelectedObject();
if(editManager->polygonOk(*activeRoom))
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
else
glColor4f(1.0f, 0.3f, 0.3f, 0.2f);
fillPolygon(*activeRoom);
glLineWidth(2.0f);
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
drawPolygon(*activeRoom, false);
if(!activeRoom->empty() && editManager->getHoveredVertex()) {
if(!editManager->vertexOk(*editManager->getHoveredVertex()))
glColor4f(1.0f, 0.3f, 0.3f, 0.7f);
glBegin(GL_LINES);
glVertex2f(activeRoom->back().getX(), activeRoom->back().getY());
glVertex2f(editManager->getHoveredVertex()->getX(), editManager->getHoveredVertex()->getY());
glEnd();
}
}
}

View file

@ -14,6 +14,8 @@ class Renderer {
EditManager *editManager;
void drawGrid(const Rectangle &rect, float scale);
protected:
void fillPolygon(const Polygon &polygon);
void drawPolygon(const Polygon &polygon, bool close = true);
void drawCircle(const Vertex &m, float r, int n);
@ -29,7 +31,9 @@ class Renderer {
this->editManager = editManager;
}
void render(const Level &level, const Rectangle &rect, float scale);
virtual ~Renderer() {}
virtual void render(const Level &level, const Rectangle &rect, float scale);
};
#endif /*RENDERER_H_*/

View file

@ -3,10 +3,9 @@
SidebarManager::SidebarManager(Window *window)
: sidebarToolbox(window), sidebarView(&window->getEditManager()),
sidebarAdd(&window->getEditManager()), toolAddPolygon(&window->getEditManager())
: sidebarToolbox(window), toolAddPolygon(&window->getEditManager())
{
this->editor = &window->getEditManager();
this->window = window;
activeSidebar = NULL;
sidebar = gtk_vbox_new(FALSE, 0);
@ -16,7 +15,7 @@ SidebarManager::SidebarManager(Window *window)
gtk_box_pack_start(GTK_BOX(sidebar), gtk_hseparator_new(), FALSE, FALSE, 5);
toolLabel = gtk_label_new(sidebarToolbox.getActiveTool()->getName());
toolLabel = gtk_label_new(sidebarToolbox.getActiveTool().getName());
gtk_box_pack_start(GTK_BOX(sidebar), toolLabel, FALSE, FALSE, 0);
@ -40,13 +39,7 @@ SidebarManager::~SidebarManager() {
void SidebarManager::update() {
Sidebar *newSidebar = activeSidebar;
switch(editor->getMode()) {
case EditManager::VIEW:
newSidebar = &sidebarView;
break;
case EditManager::ADD:
newSidebar = &sidebarAdd;
}
newSidebar = window->getActiveTool()->getSidebar();
if(activeSidebar != newSidebar) {
if(activeSidebar)
@ -57,7 +50,7 @@ void SidebarManager::update() {
activeSidebar = newSidebar;
}
gtk_label_set_text(GTK_LABEL(toolLabel), sidebarToolbox.getActiveTool()->getName());
gtk_label_set_text(GTK_LABEL(toolLabel), sidebarToolbox.getActiveTool().getName());
sidebarToolbox.update();
activeSidebar->update();

View file

@ -20,12 +20,9 @@ class SidebarManager {
SidebarToolbox sidebarToolbox;
SidebarView sidebarView;
SidebarAdd sidebarAdd;
Sidebar *activeSidebar;
EditManager *editor;
Window *window;
ToolAddPolygon toolAddPolygon;
@ -37,10 +34,14 @@ class SidebarManager {
SidebarManager(Window *window);
virtual ~SidebarManager();
GtkWidget *getWidget() {
GtkWidget* getWidget() {
return sidebar;
}
Tool* getActiveTool() {
return &sidebarToolbox.getActiveTool();
}
void update();
};

View file

@ -47,8 +47,8 @@ class SidebarToolbox : Sidebar {
return widget;
}
Tool *getActiveTool() {
return activeTool;
Tool& getActiveTool() {
return *activeTool;
}
void addTool(Tool *tool);

View file

@ -1,29 +1,30 @@
#include "SidebarView.h"
#include "PlayerStart.h"
#include "ToolSelector.h"
void SidebarView::spinButtonChanged(GtkWidget *spinbutton, SidebarView *view) {
if(!view->editor->getSelectedObject())
if(!view->editManager->getSelectedObject())
return;
if(view->editor->getSelectedObject()->isOfType("Room")) {
if(view->editManager->getSelectedObject()->isOfType("Room")) {
if(spinbutton == view->spinButtonHeight)
((Room*)view->editor->getSelectedObject())->setHeight(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
((Room*)view->editManager->getSelectedObject())->setHeight(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
}
else if(view->editor->getSelectedObject()->isOfType("PlayerStart")) {
else if(view->editManager->getSelectedObject()->isOfType("PlayerStart")) {
if(spinbutton == view->spinButtonX)
((PlayerStart*)view->editor->getSelectedObject())->setX(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
((PlayerStart*)view->editManager->getSelectedObject())->setX(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
else if(spinbutton == view->spinButtonY)
((PlayerStart*)view->editor->getSelectedObject())->setY(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
((PlayerStart*)view->editManager->getSelectedObject())->setY(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
else if(spinbutton == view->spinButtonZ)
((PlayerStart*)view->editor->getSelectedObject())->setZ(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
((PlayerStart*)view->editManager->getSelectedObject())->setZ(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbutton)));
}
view->editor->redraw();
view->editManager->redraw();
}
SidebarView::SidebarView(EditManager *editor) {
this->editor = editor;
SidebarView::SidebarView(EditManager *editManager) {
this->editManager = editManager;
sidebar = gtk_vbox_new(FALSE, 0);
g_object_ref_sink(G_OBJECT(sidebar));
@ -154,9 +155,9 @@ void SidebarView::update() {
gtk_widget_hide(tableRoomData);
gtk_widget_hide(tablePlayerStart);
if(editor->getSelectedObject()) {
if(editor->getSelectedObject()->isOfType("Room")) {
Room *room = (Room*)editor->getSelectedObject();
if(editManager->getSelectedObject()) {
if(editManager->getSelectedObject()->isOfType("Room")) {
Room *room = (Room*)editManager->getSelectedObject();
gtk_label_set_markup(GTK_LABEL(labelType), "<b>Room info:</b>");
@ -177,8 +178,8 @@ void SidebarView::update() {
gtk_widget_show(tableRoomData);
}
else if(editor->getSelectedObject()->isOfType("PlayerStart")) {
PlayerStart *playerStart = (PlayerStart*)editor->getSelectedObject();
else if(editManager->getSelectedObject()->isOfType("PlayerStart")) {
PlayerStart *playerStart = (PlayerStart*)editManager->getSelectedObject();
gtk_label_set_markup(GTK_LABEL(labelType), "<b>Player start:</b>");

View file

@ -5,6 +5,8 @@
#include "EditManager.h"
class ToolSelector;
class SidebarView : public Sidebar {
private:
GtkWidget *sidebar;
@ -12,7 +14,7 @@ class SidebarView : public Sidebar {
GtkWidget *tableRoomData, *labelArea, *labelPerimeter, *spinButtonHeight;
GtkWidget *tablePlayerStart, *spinButtonX, *spinButtonY, *spinButtonZ;
EditManager *editor;
EditManager *editManager;
// prevent shallow copy
SidebarView(const SidebarView &w);
@ -21,7 +23,7 @@ class SidebarView : public Sidebar {
static void spinButtonChanged(GtkWidget *spinbutton, SidebarView *view);
public:
SidebarView(EditManager *editor);
SidebarView(EditManager *editManager);
virtual ~SidebarView();
GtkWidget* getWidget();

11
Tool.h
View file

@ -2,6 +2,9 @@
#define TOOL_H_
#include "Object.h"
#include "EventHandler.h"
#include "Sidebar.h"
#include "Renderer.h"
#include <gtk/gtk.h>
@ -12,12 +15,16 @@ class Tool : public Object {
virtual void activate() {};
virtual void deactivate() {};
virtual const char *getName() const {
virtual const char* getName() const {
return getType();
}
virtual GtkWidget *getImage() = 0;
virtual GtkWidget* getImage() = 0;
virtual bool isSensitive() = 0;
virtual EventHandler* getEventHandler() = 0;
virtual Sidebar* getSidebar() = 0;
virtual Renderer* getRenderer() {return NULL;}
};
#endif /*TOOL_H_*/

View file

@ -1,7 +1,8 @@
#include "ToolAddPolygon.h"
#include <GL/gl.h>
ToolAddPolygon::ToolAddPolygon(EditManager *editManager) {
ToolAddPolygon::ToolAddPolygon(EditManager *editManager) : Renderer(editManager), sidebar(editManager) {
this->editManager = editManager;
image = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON);
@ -13,9 +14,54 @@ ToolAddPolygon::~ToolAddPolygon() {
}
void ToolAddPolygon::activate() {
editManager->addRoom();
newRoom = Room();
editManager->setSelectedObject(NULL);
}
void ToolAddPolygon::deactivate() {
editManager->finishRoom();
editManager->addRoom(newRoom);
}
void ToolAddPolygon::render(const Level &level, const Rectangle &rect, float scale) {
if(editManager->polygonOk(newRoom))
glColor4f(0.0f, 0.7f, 1.0f, 0.2f);
else
glColor4f(1.0f, 0.3f, 0.3f, 0.2f);
fillPolygon(newRoom);
glLineWidth(2.0f);
glColor4f(0.0f, 0.7f, 1.0f, 0.7f);
drawPolygon(newRoom, false);
if(!newRoom.empty() && editManager->getHoveredVertex()) {
if(!editManager->vertexOk(newRoom, *editManager->getHoveredVertex()))
glColor4f(1.0f, 0.3f, 0.3f, 0.7f);
glBegin(GL_LINES);
glVertex2f(newRoom.back().getX(), newRoom.back().getY());
glVertex2f(editManager->getHoveredVertex()->getX(), editManager->getHoveredVertex()->getY());
glEnd();
}
}
bool ToolAddPolygon::buttonPress(unsigned int button) {
if(button != 1)
return false;
if(!editManager->getHoveredVertex())
return false;
if(!editManager->vertexOk(newRoom, *editManager->getHoveredVertex()))
return false;
newRoom.push_back(*editManager->getHoveredVertex());
editManager->redraw();
sidebar.update();
return true;
}

View file

@ -3,13 +3,19 @@
#include "Tool.h"
#include "EditManager.h"
#include "SidebarAdd.h"
class ToolAddPolygon : public Tool {
class ToolAddPolygon : public Tool, public EventHandler, public Renderer {
private:
GtkWidget *image;
EditManager *editManager;
SidebarAdd sidebar;
Room newRoom;
// prevent shallow copy
ToolAddPolygon(const ToolAddPolygon &t);
const ToolAddPolygon& operator=(const ToolAddPolygon &t);
@ -29,13 +35,29 @@ class ToolAddPolygon : public Tool {
return "Add polygonal room";
}
bool isSensitive() {
virtual bool isSensitive() {
return TRUE;
}
virtual GtkWidget *getImage() {
return image;
}
virtual EventHandler* getEventHandler() {
return this;
}
virtual Renderer *getRenderer() {
return this;
}
virtual void render(const Level &level, const Rectangle &rect, float scale);
virtual bool buttonPress(unsigned int button);
virtual Sidebar* getSidebar() {
return &sidebar;
}
};
#endif /*TOOLADDPOLYGON_H_*/

View file

@ -1,7 +1,7 @@
#include "ToolSelector.h"
ToolSelector::ToolSelector(EditManager *editManager) {
ToolSelector::ToolSelector(EditManager *editManager) : sidebar(editManager) {
this->editManager = editManager;
image = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON);
@ -11,3 +11,15 @@ ToolSelector::ToolSelector(EditManager *editManager) {
ToolSelector::~ToolSelector() {
g_object_unref(G_OBJECT(image));
}
bool ToolSelector::buttonPress(unsigned int button) {
if(button != 1)
return false;
editManager->setSelectedObject(editManager->getHoveredObject());
editManager->redraw();
sidebar.update();
return true;
}

View file

@ -3,13 +3,17 @@
#include "Tool.h"
#include "EditManager.h"
#include "SidebarView.h"
class ToolSelector : public Tool {
class ToolSelector : public Tool, public EventHandler {
private:
GtkWidget *image;
EditManager *editManager;
SidebarView sidebar;
// prevent shallow copy
ToolSelector(const ToolSelector &t);
const ToolSelector& operator=(const ToolSelector &t);
@ -26,13 +30,23 @@ class ToolSelector : public Tool {
return "Select";
}
bool isSensitive() {
virtual bool isSensitive() {
return TRUE;
}
virtual GtkWidget *getImage() {
return image;
}
virtual EventHandler *getEventHandler() {
return this;
}
virtual bool buttonPress(unsigned int button);
virtual Sidebar* getSidebar() {
return &sidebar;
}
};
#endif /*TOOLSELECTOR_H_*/

View file

@ -36,6 +36,7 @@ class Window {
const Window& operator=(const Window &w);
static gboolean deleteEvent(GtkWidget *widget, GdkEvent *event, Window *window);
public:
Window(GdkGLConfig *glconfig, WindowManager *manager);
virtual ~Window();
@ -48,6 +49,10 @@ class Window {
drawer.update();
}
Tool* getActiveTool() {
return sidebar.getActiveTool();
}
EditManager& getEditManager() {
return editor;
}