/* * Instance.cpp * * Copyright (C) 2008 Matthias Schiffer * * 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 . */ #include "Instance.h" #include #include #include #include #include #include #include #include #include #include namespace ZoomEdit { guint Instance::instances = 0; Instance::Instance(const Glib::ustring &file) : window(0), view(0), levelXml(0), level(0), selectedRoom(0) { instances++; try { builder = Gtk::Builder::create_from_file("zoomedit.ui"); } catch(const Glib::Exception& ex) { std::cerr << ex.what() << std::endl; return; } builder->get_widget_derived("WindowMain", window); if(!window) { builder.clear(); return; } 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(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)); builder->get_widget("ToolButtonZoomOut", button); button->signal_clicked().connect(sigc::bind(sigc::mem_fun(view, &View::TopView::zoom), -2, 0, 0)); if(file.empty()) createLevel(); else loadLevel(file); window->show(); } Instance::~Instance() { if(window) delete window; if(mapView) delete mapView; if(view) delete view; if(level) delete level; if(levelXml) delete levelXml; instances--; if(!instances) Gtk::Main::quit(); } 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) { 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(); xmlSetDocCompressMode(doc->cobj(), 9); xmlpp::Element *root = doc->create_root_node("level"); xmlpp::Element *info = root->add_child("info"); info->add_child("name"); info->add_child("desc"); xmlpp::Element *start = info->add_child("start"); start->set_attribute("x", "0"); start->set_attribute("y", "0"); start->set_attribute("z", "0"); xmlpp::Element *rooms = root->add_child("rooms"); rooms->add_child("floor"); root->add_child("gates"); root->add_child("textures"); level = new Data::Level(root); setLevel(); } bool Instance::loadLevel(const Glib::ustring &file) { deleteLevel(); levelXml = new xmlpp::DomParser(file); xmlpp::Document *doc = levelXml->get_document(); if(!doc || !doc->get_root_node()) return false; if(!xmlpp::DtdValidator("level.dtd").validate(doc)) return false; level = new Data::Level(doc->get_root_node()); setLevel(); return true; } bool Instance::saveLevel(const Glib::ustring &file) { if(!level | !levelXml->get_document()) return false; levelXml->get_document()->write_to_file(file); return true; } bool Instance::create(const Glib::ustring &file) { Instance *instance = new Instance(file); if(!instance->level) { delete instance; return false; } return true; } void Instance::destroy() { delete this; } }