/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001-2007 by Diether Knof and Borg Enders * * 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 2 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 can find this license in the file 'gpl.txt'. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@gmx.de * Borg Enders borg@borgsoft.de * *********************************************************************/ #include "constants.h" #ifdef USE_UI_GTKMM #include "gameinfo_dialog.h" #include "gameinfo.h" #include "gameinfo.announcement.h" #include "table.h" #include "ui.h" #include "translations.h" #include "main_window.h" #include "../../party/party.h" #include "../../game/game.h" #include "../../player/human/human.h" #include "widgets/stock_button.h" #include #include #include #ifdef USE_NETWORK #include "../../network/server.h" #endif namespace UI_GTKMM_NS { /** ** constructor ** ** @param table the table ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ GameInfoDialog::GameInfoDialog(Table* const table) : Base(table), Gtk::StickyDialog("GameInfoDialog", *table->ui->main_window, false), close_button(NULL), announcement_reply_button(NULL), timeout_connection(), infos() { this->ui->add_window(*this); this->signal_realize().connect(sigc::mem_fun(*this, &GameInfoDialog::init)); return ; } // GameInfoDialog::GameInfoDialog(Table* table) /** ** destruktor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ GameInfoDialog::~GameInfoDialog() { this->clear(); return ; } // GameInfoDialog::~GameInfoDialog() /** ** init the dialog ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.1 **/ void GameInfoDialog::init() { this->ui->translations->add(*this, ::translation("game information")); this->set_icon(this->ui->icon); this->set_skip_taskbar_hint(); { // action area { // announcement reply button this->announcement_reply_button = Gtk::manage(new Gtk::StockButton(Gtk::Stock::CLOSE, "announcement reply")); this->ui->translations->add(*this->announcement_reply_button, ::translation("")); this->add_action_widget(*this->announcement_reply_button, Gtk::RESPONSE_CLOSE); this->announcement_reply_button->grab_default(); this->announcement_reply_button->signal_clicked().connect(sigc::mem_fun(*this, &GameInfoDialog::announcement_reply)); this->announcement_reply_button->signal_clicked().connect(sigc::mem_fun(*this, &GameInfoDialog::close)); // the button is only shown when the reply is valid, see add_info(). this->announcement_reply_button->show_all_children(); } // announcement reply button { // close button this->close_button = Gtk::manage(new Gtk::StockButton(Gtk::Stock::CLOSE, "close")); this->ui->translations->add(*this->close_button, ::translation("close")); this->add_action_widget(*this->close_button, Gtk::RESPONSE_CLOSE); this->close_button->grab_default(); this->close_button->signal_clicked().connect(sigc::mem_fun(*this, &GameInfoDialog::close)); this->close_button->show_all(); } // close button } // action area { // move to the top left corner of the table int x, y; this->table().get_window()->get_origin(x, y); this->move(x, y); } // move to the top left corner of the table return ; } // void GameInfoDialog::init() /** ** add the information and manage it ** ** @param info game information to add ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::add_info(Information* const info) { this->infos.push_back(info); if (this->infos.empty()) { this->ui->translations->change(*this, info->title); } else { this->get_vbox()->add(*Gtk::manage(new Gtk::HSeparator())); this->ui->translations->change(*this, ::translation("game information")); } this->get_vbox()->add(*info); info->show(); { // check for announcement reply Game const& game = this->ui->game(); if ( (game.humanno() == 1) && (!this->announcement_reply_button->is_visible()) && (dynamic_cast(info)) ) { Information::Announcement const& announcement_info = static_cast(*info); if ( (game.team(*announcement_info.player) != game.team(*game.human_player())) && !ANNOUNCEMENT::is_reply(announcement_info.announcement) && game.announcement_valid(ANNOUNCEMENT::to_reply(announcement_info.announcement), *game.human_player()) ) { this->ui->translations->change(*this->announcement_reply_button, ::translation(ANNOUNCEMENT::to_reply(announcement_info.announcement))); this->announcement_reply_button->show(); } // if (reply valid } // if (is announcement) } // check for announcement reply return ; } // void GameInfoDialog::add_info(Information* info) /** ** clear the window ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::clear() { for (vector::iterator info = this->infos.begin(); info != this->infos.end(); info++) { this->get_vbox()->remove(**info); delete *info; } this->infos.clear(); if (this->announcement_reply_button) this->announcement_reply_button->hide(); return ; } // void GameinfDialog::clear() /** ** -> result ** ** @param - ** ** @return the table ** ** @author Diether Knof ** ** @version 0.6.8 **/ Table& GameInfoDialog::table() { return *dynamic_cast(this->parent); } // Table& GameinfDialog::table() /** ** show the information and manage it ** ** @param info information to show ** @param close_automatically whether to close the window automatically ** @param close_delay the time (in tenth of seconds) to wait ** before closing the window ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 ** ** @todo manage multiple delays **/ void GameInfoDialog::show(Information* const info, bool const close_automatically, unsigned const close_delay) { if (!this->is_realized()) this->realize(); this->add_info(info); this->present(); #ifdef WORKAROUND // @todo manage multiple delays if (this->timeout_connection) this->timeout_connection.disconnect(); if (close_automatically) this->timeout_connection = Glib::signal_timeout().connect(sigc::slot0(sigc::mem_fun(*this, &GameInfoDialog::on_timeout)), close_delay); #endif #ifdef POSTPHONED #ifdef USE_NETWORK if (::server->empty()) { #endif // @todo if not in network modus wait till the player actively closes the window while ( (::game_status == GAMESTATUS::GAME_FULL_TRICK) && !this->ui->thrower) ::ui->wait(); this->close() #ifdef USE_NETWORK } // if (::server->empty()) #endif #endif return ; } // void GameInfoDialog::show(Information* info, bool close_automatically, unsigned close_delay) /** ** show the information and close it on a click ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.1 **/ void GameInfoDialog::show(Information* const info) { this->show(info, false, 0); return ; } // void GameInfoDialog::show(Information* info) /** ** hide the window ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::close() { if (this->timeout_connection) this->timeout_connection.disconnect(); this->hide(); this->clear(); return ; } // void GameInfoDialog::close() /** ** update the announcement reply sensitivity ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::update_announcement_reply() { if (!this->announcement_reply_button) return ; Game const& game = this->ui->game(); if ( this->announcement_reply_button->is_visible() && !game.announcement_valid(ANNOUNCEMENT::to_reply(game.announcement_of_team(opposite(game.team(*game.human_player())))), *game.human_player()) ) { this->announcement_reply_button->hide(); } // if (reply invalid) return ; } // void GameInfoDialog::update_announcement_reply() /** ** the name of 'player' has changed ** ** @param player player whose name has changed ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::name_changed(Player const& player) { for (vector::iterator info = this->infos.begin(); info != this->infos.begin(); info++) (*info)->name_changed(player); } // void GameInfoDialog::name_changed(Player player) /** ** the timeout event: ** close the window and exit the main loop ** ** @param - ** ** @return false (to stop the timeout event) ** ** @author Diether Knof ** ** @version 0.6.1 **/ bool GameInfoDialog::on_timeout() { this->close(); return false; } // bool GameInfoDialog::on_timeout() /** ** reply to the last announcement ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void GameInfoDialog::announcement_reply() { Game& game = ::party.game(); DEBUG_ASSERTION((game.humanno() == 1), "GameInfoDialog::announcement_reply()\n" " game has '" << game.humanno() << "' humans, must be '1'"); Announcement const announcement = ANNOUNCEMENT::to_reply(game.announcement_of_team(opposite(game.team(*game.human_player())))); game.make_announcement(announcement, *game.human_player()); return ; } // void GameInfoDialog::announcement_reply() } // namespace UI_GTKMM_NS #endif // #ifdef USE_UI_GTKMM