/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 . * */ #define FORBIDDEN_SYMBOL_ALLOW_ALL #include "common/debug.h" #include "qdengine/qdengine.h" #include "qdengine/qd_fwd.h" #include "qdengine/parser/qdscr_parser.h" #include "qdengine/parser/xml_tag.h" #include "qdengine/qdcore/qd_game_dispatcher.h" #include "qdengine/qdcore/qd_interface_button.h" namespace QDEngine { qdInterfaceButton::qdInterfaceButton() : _cur_state(-1) { } qdInterfaceButton::qdInterfaceButton(const qdInterfaceButton &bt) : qdInterfaceElement(bt), #ifndef _QD_INTERFACE_BUTTON_PTR_CONTAINER _states(bt._states), #endif _cur_state(-1) { #ifdef _QD_INTERFACE_BUTTON_PTR_CONTAINER for (int i = 0; i < bt.num_states(); i++) _states.push_back(new qdInterfaceElementState(*bt.get_state(i))); #endif for (int i = 0; i < num_states(); i++) { get_state(i)->set_owner(this); get_state(i)->register_resources(); } } qdInterfaceButton::~qdInterfaceButton() { _states.clear(); } qdInterfaceButton &qdInterfaceButton::operator = (const qdInterfaceButton &bt) { if (this == &bt) return *this; *static_cast(this) = bt; #ifdef _QD_INTERFACE_BUTTON_PTR_CONTAINER for (state_container_t::iterator it = _states.begin(); it != _states.end(); ++it) delete *it; _states.clear(); for (int i = 0; i < bt.num_states(); i++) _states.push_back(new qdInterfaceElementState(*bt.get_state(i))); #else _states.clear(); _states = bt._states; #endif for (int i = 0; i < num_states(); i++) { get_state(i)->set_owner(this); get_state(i)->register_resources(); } _cur_state = -1; return *this; } bool qdInterfaceButton::activate_state(int state_num) { if (state_num >= _states.size()) state_num = _states.size() - 1; if (!_states.size() || _cur_state == state_num) return false; if (state_num < 0) state_num = 0; _cur_state = state_num; if (state_num >= 0 && state_num < _states.size()) return set_state(get_state(state_num)); return true; } bool qdInterfaceButton::activate_state(const char *state_name) { for (int i = 0; i < num_states(); i++) { qdInterfaceElementState *p = get_state(i); if (!strcmp(p->name(), state_name)) return activate_state(i); } return false; } bool qdInterfaceButton::set_option_value(int value) { if (value < 0) value = 0; if (value >= _states.size()) value = _states.size() - 1; activate_state(value); return true; } bool qdInterfaceButton::add_state(const qdInterfaceElementState &st) { #ifdef _QD_INTERFACE_BUTTON_PTR_CONTAINER _states.push_back(new qdInterfaceElementState(st)); #else _states.push_back(st); #endif get_state(_states.size() - 1)->set_owner(this); get_state(_states.size() - 1)->register_resources(); return true; } bool qdInterfaceButton::insert_state(int insert_before, const qdInterfaceElementState &st) { assert(insert_before >= 0 && insert_before < _states.size()); #ifdef _QD_INTERFACE_BUTTON_PTR_CONTAINER _states.insert(_states.begin() + insert_before, new qdInterfaceElementState(st)); #else _states.insert(_states.begin() + insert_before, st); #endif get_state(insert_before)->set_owner(this); get_state(insert_before)->register_resources(); return true; } bool qdInterfaceButton::erase_state(int state_num) { assert(state_num >= 0 && state_num < _states.size()); #ifdef _QD_INTERFACE_BUTTON_PTR_CONTAINER // delete *(_states.begin() + state_num); #endif _states.erase(_states.begin() + state_num); if (_cur_state == state_num) activate_state(--_cur_state); return true; } bool qdInterfaceButton::mouse_handler(int x, int y, mouseDispatcher::mouseEvent ev) { if (_cur_state == -1) return false; return get_state(_cur_state)->mouse_handler(x, y, ev); } bool qdInterfaceButton::keyboard_handler(Common::KeyCode vkey) { return false; } bool qdInterfaceButton::init(bool is_game_active) { set_lock(false); if (!is_game_active) { for (int i = 0; i < num_states(); i++) { if (get_state(i)->need_active_game()) { set_lock(true); break; } } } for (int i = 0; i < num_states(); i++) { qdInterfaceElementState *p = get_state(i); p->set_state_mode(qdInterfaceElementState::DEFAULT_MODE); } if (_cur_state != -1) return set_state(get_state(_cur_state)); return true; } bool qdInterfaceButton::save_script_body(Common::WriteStream &fh, int indent) const { for (int i = 0; i < num_states(); i++) { get_state(i)->save_script(fh, indent + 1); } return true; } bool qdInterfaceButton::load_script_body(const xml::tag *p) { int num_states = 0; for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) { switch (it->ID()) { case QDSCR_INTERFACE_ELEMENT_STATE: num_states++; break; } } if (num_states) { _states.reserve(num_states); _cur_state = 0; } for (xml::tag::subtag_iterator it = p->subtags_begin(); it != p->subtags_end(); ++it) { switch (it->ID()) { case QDSCR_INTERFACE_ELEMENT_STATE: { qdInterfaceElementState st; st.load_script(&*it); add_state(st); } break; } } return true; } bool qdInterfaceButton::quant(float dt) { debugC(9, kDebugQuant, "qdInterfaceButton::quant()"); qdInterfaceElement::quant(dt); if (find_event(qdInterfaceEvent::EVENT_CLEAR_MOUSE)) { if (qdGameDispatcher * dp = qdGameDispatcher::get_dispatcher()) { debugC(3, kDebugQuant, "qdInterfaceButton::quant()"); if (dp->is_on_mouse(NULL)) activate_state(1); else activate_state(0); } } if (_cur_state != -1) { get_state(_cur_state)->quant(dt); } return true; } bool qdInterfaceButton::hit_test(int x, int y) const { if (_cur_state != -1) { if (get_state(_cur_state)->has_contour(get_state(_cur_state)->state_mode())) return get_state(_cur_state)->hit_test(x - r().x, y - r().y, get_state(_cur_state)->state_mode()); } return qdInterfaceElement::hit_test(x, y); } bool qdInterfaceButton::change_state(bool direction) { if (num_states()) { if (_cur_state != -1) { _cur_state += (direction) ? 1 : -1; if (_cur_state < 0) _cur_state = num_states() - 1; if (_cur_state >= num_states()) _cur_state = 0; } else _cur_state = 0; return activate_state(_cur_state); } return false; } const qdInterfaceEvent *qdInterfaceButton::find_event(qdInterfaceEvent::event_t type) const { for (int i = 0; i < num_states(); i++) { const qdInterfaceElementState *p = get_state(i); if (const qdInterfaceEvent * ev = p->find_event(type)) return ev; } return NULL; } bool qdInterfaceButton::has_event(qdInterfaceEvent::event_t type, const char *ev_data) const { for (int i = 0; i < num_states(); i++) { const qdInterfaceElementState *p = get_state(i); if (p->has_event(type, ev_data)) return true; } return false; } } // namespace QDEngine