From b4adc20ef08257124a01499436f2b8b447adcb33 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 9 Jan 2010 03:18:25 +0100 Subject: Use room list --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 1 + src/Gui/Renderer/RoomListRenderer.cpp | 66 ++++++++++++++++++++++++++++++ src/Gui/Renderer/RoomListRenderer.h | 53 ++++++++++++++++++++++++ src/Gui/Window.cpp | 14 +++++++ src/Gui/Window.h | 38 +++++++++++++++-- src/Instance.cpp | 77 ++++++++++++++++++++++++++--------- src/Instance.h | 20 ++++++++- src/View/MapView.cpp | 13 +++--- src/View/TopView.cpp | 14 ++++--- src/View/TopView.h | 17 ++++---- 11 files changed, 269 insertions(+), 46 deletions(-) create mode 100644 src/Gui/Renderer/RoomListRenderer.cpp create mode 100644 src/Gui/Renderer/RoomListRenderer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5081b8f..6a91fc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ ENDIF (NOT OPENGL_FOUND) find_package(PkgConfig) pkg_check_modules(XMLPP REQUIRED libxml++-2.6>=2.24) -pkg_check_modules(GTKMM REQUIRED glibmm-2.4>=2.16 gtkmm-2.4>=2.16) +pkg_check_modules(GTKMM REQUIRED glibmm-2.4>=2.16 gtkmm-2.4>=2.18) pkg_check_modules(GTKGLEXT REQUIRED gtkglext-1.0) #include_directories(${Boost_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLPNG_INCLUDE_DIR} ${XMLPP_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GTKGLEXT_INCLUDE_DIRS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cdf2748..4339ca8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(zoomedit Gui/AspectFrame.h Gui/RenderArea.cpp Gui/RenderArea.h Gui/Window.cpp Gui/Window.h + Gui/Renderer/RoomListRenderer.cpp Gui/Renderer/RoomListRenderer.h Math/Triangle2D.cpp Math/Triangle2D.h diff --git a/src/Gui/Renderer/RoomListRenderer.cpp b/src/Gui/Renderer/RoomListRenderer.cpp new file mode 100644 index 0000000..83b0402 --- /dev/null +++ b/src/Gui/Renderer/RoomListRenderer.cpp @@ -0,0 +1,66 @@ +/* + * RoomListRenderer.cpp + * + * Copyright (C) 2010 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#include "RoomListRenderer.h" +#include + +#include + +namespace ZoomEdit { +namespace Gui { +namespace Renderer { + +void RoomListRenderer::get_size_vfunc(Gtk::Widget &/*widget*/, const Gdk::Rectangle * /*cell_area*/, + int * /*x_offset*/, int * /*y_offset*/, int * /*width*/, int *height) const { + int xpad, ypad; + get_padding(xpad, ypad); + + *height = 60 + ypad*2; +} + +void RoomListRenderer::render_vfunc(const Glib::RefPtr &window, Gtk::Widget &widget, + const Gdk::Rectangle &/*background_area*/, const Gdk::Rectangle &cell_area, + const Gdk::Rectangle &/*expose_area*/, Gtk::CellRendererState /*flags*/) { + + Data::Room *room = reinterpret_cast(value.get_value()); + + int xpad, ypad; + get_padding(xpad, ypad); + + int x = xpad + cell_area.get_x(); + int y = ypad + cell_area.get_y(); + + int width = cell_area.get_width() - 2*xpad; + int height = cell_area.get_height() - 2*ypad; + + Glib::RefPtr gc = Gdk::GC::create(window); + gc->set_rgb_fg_color(Gdk::Color("000000")); + + Glib::RefPtr layout = Pango::Layout::create(widget.get_pango_context()); + + layout->set_width(width); + layout->set_height(height); + layout->set_markup("" + room->getId() + ""); + + window->draw_layout(gc, x, y, layout); +} + +} +} +} diff --git a/src/Gui/Renderer/RoomListRenderer.h b/src/Gui/Renderer/RoomListRenderer.h new file mode 100644 index 0000000..ee2ac9f --- /dev/null +++ b/src/Gui/Renderer/RoomListRenderer.h @@ -0,0 +1,53 @@ +/* + * RoomListRenderer.h + * + * Copyright (C) 2010 Matthias Schiffer + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with this program. If not, see . + */ + +#ifndef ZOOMEDIT_GUI_RENDERER_ROOMLISTRENDERER_H_ +#define ZOOMEDIT_GUI_RENDERER_ROOMLISTRENDERER_H_ + +#include + +namespace ZoomEdit { +namespace Gui { +namespace Renderer { + +class RoomListRenderer : public virtual Glib::ObjectBase, public Gtk::CellRenderer { + public: + RoomListRenderer() : Glib::ObjectBase(typeid(RoomListRenderer)), value(*this, "value") {} + + Glib::PropertyProxy property_value() { + return value.get_proxy(); + } + + protected: + virtual void get_size_vfunc(Gtk::Widget &widget, const Gdk::Rectangle *cell_area, + int *x_offset, int *y_offset, int *width, int *height) const; + + virtual void render_vfunc(const Glib::RefPtr &window, Gtk::Widget &widget, + const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, + const Gdk::Rectangle &expose_area, Gtk::CellRendererState flags); + + private: + Glib::Property value; +}; + +} +} +} + +#endif /* ZOOMEDIT_GUI_RENDERER_ROOMLISTRENDERER_H_ */ diff --git a/src/Gui/Window.cpp b/src/Gui/Window.cpp index dcc8f45..9e3722c 100644 --- a/src/Gui/Window.cpp +++ b/src/Gui/Window.cpp @@ -26,6 +26,8 @@ namespace ZoomEdit { namespace Gui { +const Window::RoomListColumnRecord Window::ROOM_LIST_COLUMN_RECORD; + Window::Window(BaseObjectType *cobject, const Glib::RefPtr &builder) : Gtk::Window(cobject) { @@ -37,6 +39,18 @@ Window::Window(BaseObjectType *cobject, const Glib::RefPtr &builde builder->get_widget_derived("RenderArea", renderArea); builder->get_widget_derived("MapArea", mapArea); builder->get_widget_derived("AspectFrameMap", aspectFrameMap); + + roomListStore = Gtk::ListStore::create(ROOM_LIST_COLUMN_RECORD); + + builder->get_widget("RoomList", roomList); + + roomList->set_model(roomListStore); + int colCount = roomList->append_column("Room", roomListRenderer); + Gtk::TreeViewColumn *roomColumn = roomList->get_column(colCount-1); + + if(roomColumn) { + roomColumn->add_attribute(roomListRenderer.property_value(), ROOM_LIST_COLUMN_RECORD.room); + } } Window::~Window() { diff --git a/src/Gui/Window.h b/src/Gui/Window.h index 97ebcda..ce0b1e2 100644 --- a/src/Gui/Window.h +++ b/src/Gui/Window.h @@ -21,25 +21,55 @@ #define ZOOMEDIT_GUI_WINDOW_H_ #include +#include +#include #include +#include "Renderer/RoomListRenderer.h" + namespace ZoomEdit { + +namespace Data { +class Room; +} + namespace Gui { class AspectFrame; class RenderArea; class Window : public Gtk::Window { - private: - RenderArea *renderArea, *mapArea; - AspectFrame *aspectFrameMap; - public: Window(BaseObjectType *cobject, const Glib::RefPtr &builder); virtual ~Window(); RenderArea* getRenderArea() const {return renderArea;} RenderArea* getMapArea() const {return mapArea;} + + Glib::RefPtr getRoomListStore() {return roomListStore;} + Gtk::TreeView* getRoomList() {return roomList;} + + class RoomListColumnRecord : public Gtk::TreeModel::ColumnRecord { + public: + friend class Window; + + Gtk::TreeModelColumn room; + + private: + RoomListColumnRecord() { + add(room); + } + }; + + static const RoomListColumnRecord ROOM_LIST_COLUMN_RECORD; + + private: + RenderArea *renderArea, *mapArea; + AspectFrame *aspectFrameMap; + Gtk::TreeView *roomList; + + Glib::RefPtr roomListStore; + Renderer::RoomListRenderer roomListRenderer; }; } diff --git a/src/Instance.cpp b/src/Instance.cpp index ce0d239..3eee22f 100644 --- a/src/Instance.cpp +++ b/src/Instance.cpp @@ -18,21 +18,24 @@ */ #include "Instance.h" -#include -#include -#include -#include + #include #include #include +#include #include #include +#include +#include +#include +#include + namespace ZoomEdit { guint Instance::instances = 0; -Instance::Instance(const Glib::ustring &file) : window(0), levelXml(0), level(0), view(0) { +Instance::Instance(const Glib::ustring &file) : window(0), view(0), levelXml(0), level(0), selectedRoom(0) { instances++; try { @@ -50,13 +53,16 @@ Instance::Instance(const Glib::ustring &file) : window(0), levelXml(0), level(0) } window->signal_hide().connect(sigc::mem_fun(this, &Instance::destroy)); + window->getRoomList()->get_selection()->signal_changed().connect(sigc::mem_fun(this, &Instance::onRoomListSelect)); - view = new View::TopView(); + view = new View::TopView(this); window->getRenderArea()->setView(view); mapView = new View::MapView(view); window->getMapArea()->setView(mapView); + view->signalUpdate().connect(sigc::mem_fun(this, &Instance::onUpdate)); + Gtk::ToolButton *button; builder->get_widget("ToolButtonZoomIn", button); button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), 2, 0, 0)); @@ -93,14 +99,54 @@ Instance::~Instance() { Gtk::Main::quit(); } -void Instance::createLevel() { +void Instance::setSelectedRoom(Data::Room *newSelectedRoom) { + if(selectedRoom == newSelectedRoom) + return; + + selectedRoom = newSelectedRoom; + view->signalUpdate().emit(); +} + +void Instance::onUpdate() { + window->getRoomListStore()->clear(); + + const std::list rooms = level->getRooms(); + + for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { + Gtk::ListStore::iterator row = window->getRoomListStore()->append(); + row->set_value(Gui::Window::ROOM_LIST_COLUMN_RECORD.room, static_cast(*room)); + + if(*room == selectedRoom) { + window->getRoomList()->get_selection()->select(row); + } + } +} + +void Instance::onRoomListSelect() { + Gtk::ListStore::iterator row = window->getRoomList()->get_selection()->get_selected(); + if(!window->getRoomListStore()->iter_is_valid(row)) + return; + + setSelectedRoom(static_cast(row->get_value(Gui::Window::ROOM_LIST_COLUMN_RECORD.room))); +} + +void Instance::deleteLevel() { if(level) { - view->setLevel(0); delete level; + level = 0; + view->signalUpdate().emit(); } - + if(levelXml) delete levelXml; +} + +void Instance::setLevel() { + view->signalUpdate().emit(); +} + +void Instance::createLevel() { + deleteLevel(); levelXml = new xmlpp::DomParser; xmlpp::Document *doc = levelXml->get_document(); @@ -125,18 +171,11 @@ void Instance::createLevel() { level = new Data::Level(root); - view->setLevel(level); + setLevel(); } bool Instance::loadLevel(const Glib::ustring &file) { - if(level) { - view->setLevel(0); - delete level; - level = 0; - } - - if(levelXml) - delete levelXml; + deleteLevel(); levelXml = new xmlpp::DomParser(file); xmlpp::Document *doc = levelXml->get_document(); @@ -149,7 +188,7 @@ bool Instance::loadLevel(const Glib::ustring &file) { level = new Data::Level(doc->get_root_node()); - view->setLevel(level); + setLevel(); return true; } diff --git a/src/Instance.h b/src/Instance.h index 090e2f1..de6249e 100644 --- a/src/Instance.h +++ b/src/Instance.h @@ -21,7 +21,9 @@ #define ZOOMEDIT_INSTANCE_H_ #include +#include #include + #include namespace ZoomEdit { @@ -32,6 +34,7 @@ class Window; namespace Data { class Level; +class Room; } namespace View { @@ -47,6 +50,11 @@ class Instance { bool loadLevel(const Glib::ustring &file); bool saveLevel(const Glib::ustring &file); + Data::Level* getLevel() {return level;} + + Data::Room* getSelectedRoom() {return selectedRoom;} + void setSelectedRoom(Data::Room *newSelectedRoom); + static bool create(const Glib::ustring &file = Glib::ustring()); private: @@ -55,16 +63,24 @@ class Instance { Glib::RefPtr builder; Gui::Window *window; - xmlpp::DomParser *levelXml; - Data::Level *level; View::TopView *view; View::MapView *mapView; + xmlpp::DomParser *levelXml; + Data::Level *level; + Data::Room *selectedRoom; + Instance(const Glib::ustring &file); void destroy(); + void onUpdate(); + void onRoomListSelect(); + + void deleteLevel(); + void setLevel(); + // Prevent shallow copy Instance(const Instance &o); Instance& operator=(const Instance &o); diff --git a/src/View/MapView.cpp b/src/View/MapView.cpp index 224cd37..2569a3c 100644 --- a/src/View/MapView.cpp +++ b/src/View/MapView.cpp @@ -19,10 +19,13 @@ #include "MapView.h" #include "TopView.h" + +#include #include #include #include #include + #include #include #include @@ -96,7 +99,7 @@ void MapView::click(float x, float y, unsigned int button) { void MapView::render() { glClear(GL_COLOR_BUFFER_BIT); - if(!mainView || !mainView->getLevel()) + if(!mainView || !mainView->getInstance()->getLevel()) return; float minX, maxX, minY, maxY; @@ -116,10 +119,10 @@ void MapView::render() { glScalef(scale, scale, 1); glTranslatef(-xCenter, -yCenter, 0); - const std::list &rooms = mainView->getLevel()->getRooms(); + const std::list &rooms = mainView->getInstance()->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) - TopView::renderRoom(*room); + TopView::renderRoom(*room, (*room == mainView->getInstance()->getSelectedRoom())); float mainXCenter = mainView->getXCenter(), mainYCenter = mainView->getYCenter(); float mainScale = mainView->getScale(); @@ -163,10 +166,10 @@ void MapView::getBounds(float *minX, float *maxX, float *minY, float *maxY) { if(maxY) *maxY = 0; - if(!mainView || !mainView->getLevel()) + if(!mainView || !mainView->getInstance()->getLevel()) return; - const std::list &rooms = mainView->getLevel()->getRooms(); + const std::list &rooms = mainView->getInstance()->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { const std::list &triangles = (*room)->getTriangles(); diff --git a/src/View/TopView.cpp b/src/View/TopView.cpp index 12bbe4a..7e649cc 100644 --- a/src/View/TopView.cpp +++ b/src/View/TopView.cpp @@ -18,11 +18,14 @@ */ #include "TopView.h" + +#include #include #include #include #include #include + #include #include #include @@ -218,13 +221,13 @@ void TopView::render() { drawGrid(); - if(!level) + if(!instance->getLevel()) return; - const std::list &rooms = level->getRooms(); + const std::list &rooms = instance->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) - renderRoom(*room, *room == selectedRoom); + renderRoom(*room, *room == instance->getSelectedRoom()); } void TopView::click(float x, float y, unsigned int button) { @@ -233,9 +236,9 @@ void TopView::click(float x, float y, unsigned int button) { vmml::vec2f v(xCenter + x/scale, yCenter + y/scale); - selectedRoom = 0; + Data::Room *selectedRoom = 0; - const std::list& rooms = level->getRooms(); + const std::list &rooms = instance->getLevel()->getRooms(); for(std::list::const_iterator room = rooms.begin(); room != rooms.end(); ++room) { const std::list& triangles = (*room)->getTriangles(); @@ -255,6 +258,7 @@ void TopView::click(float x, float y, unsigned int button) { break; } + instance->setSelectedRoom(selectedRoom); signalUpdate().emit(); } diff --git a/src/View/TopView.h b/src/View/TopView.h index c164f31..085d244 100644 --- a/src/View/TopView.h +++ b/src/View/TopView.h @@ -27,6 +27,8 @@ namespace ZoomEdit { +class Instance; + namespace Data { class Level; class Room; @@ -45,7 +47,7 @@ class TopView : public View { bool operator<(const Edge &e) const; }; - Data::Level *level; + Instance *instance; float viewWidth, viewHeight; @@ -54,14 +56,14 @@ class TopView : public View { int zoomLevel; float scale; - Data::Room *selectedRoom; - void drawGrid(); public: - TopView(Data::Level *level0 = 0) - : level(level0), viewWidth(0), viewHeight(0), xCenter(0), yCenter(0), zoomLevel(0), scale(100), selectedRoom(0) {} + TopView(Instance *instance0) + : instance(instance0), viewWidth(0), viewHeight(0), xCenter(0), yCenter(0), zoomLevel(0), scale(100) {} + Instance* getInstance() {return instance;} + float getWidth() const {return viewWidth;} float getHeight() const {return viewHeight;} @@ -72,11 +74,6 @@ class TopView : public View { float getScale() const {return scale;} - Data::Room* getSelectedRoom() {return selectedRoom;} - - Data::Level* getLevel() {return level;} - void setLevel(Data::Level *level0) {level = level0; signalUpdate().emit();} - virtual void init(); virtual void resize(float width, float height); -- cgit v1.2.3