/********************************************************************** * * 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 "party_points.h" #include "game_overview.h" #include "party_points.graph.h" #include "ui.h" #include "translations.h" #include "cards.h" #include "icons.h" #include "bug_report.h" #include "../../party/party.h" #include "../../party/rule.h" #include "../../game/game_summary.h" #include "../../misc/setting.h" #include "../../utils/string.h" #include "widgets/stock_button.h" #include #include #include #include #include #include #include #include #include //#define OFFSET_ROUND 0 //#define OFFSET_GAMENO (OFFSET_ROUND + 1) //#define OFFSET_PLAYER (OFFSET_GAMENO + 1) #define OFFSET_PLAYER 1 #ifdef POSTPHONED #define OFFSET_GAMEPOINTS (OFFSET_PLAYER + this->ui->party().playerno()) #else #define OFFSET_GAMEPOINTS (OFFSET_PLAYER + ::party.playerno()) #endif #define OFFSET_GAMETYPE (OFFSET_GAMEPOINTS + 1) namespace UI_GTKMM_NS { /** ** ** Constructor for the model ** ** @param playerno number of players in the party ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.1 ** ** @todo the row can be deselected ** @todo extra window for the game summary ** **/ PartyPoints::PartyPointsModel::PartyPointsModel(unsigned const playerno) : Gtk::TreeModel::ColumnRecord(), empty(), round(), round_str(), round_color(), gameno(), gameno_str(), playerpoints(playerno), gamepoints(), gamepoints_str(), gametype() { this->add(this->empty); this->add(this->round); this->add(this->round_str); this->add(this->round_color); this->add(this->gameno); this->add(this->gameno_str); for (unsigned p = 0; p < playerno; p++) this->add(this->playerpoints[p]); this->add(this->gamepoints_str); this->add(this->gametype); return ; } // PartyPoints::PartyPointsModel::PartyPointsModel(unsigned const playerno) /** ** constructor ** ** @param parent the parent object ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.1 **/ PartyPoints::PartyPoints(Base* const parent) : Base(parent), StickyDialog("Party points", false), notebook(NULL), party_points_list(), party_points_treeview(NULL), round_rows(), game_rows(), party_points_sum_treeview(NULL), show_game_overview_button(NULL), add_up_points(NULL), collapse_rounds(NULL), expand_rounds(NULL), close_button(NULL), game_overview(NULL), graph(NULL), remaining_rounds_label(NULL), remaining_points_label(NULL) { this->ui->add_window(*this); this->signal_realize().connect(sigc::mem_fun(*this, &PartyPoints::init)); #ifndef OUTDATED // when 'GamePoints' doesn't need a pointer to Game any more this->realize(); #endif return ; } // PartyPoints::PartyPoints(Base* const parent) /** ** ** Destruktor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.5.4 ** **/ PartyPoints::~PartyPoints() { delete this->party_points_model; delete this->game_overview; delete this->graph; return ; } // PartyPoints::~PartyPoints() /** ** create all subelements ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.1 **/ void PartyPoints::init() { this->ui->translations->add(*this, ::translation("~party points")); this->set_icon(this->ui->icon); this->game_overview = new GameOverview(this); this->signal_show().connect(sigc::mem_fun(*this, &PartyPoints::show_game_overview_toggled)); { // notebook this->notebook = Gtk::manage(new Gtk::Notebook()); { // table Gtk::VBox* table_vbox = Gtk::manage(new Gtk::VBox(false)); table_vbox->set_border_width(1 ex); table_vbox->set_spacing(1 ex); { // the points table this->party_points_model = new PartyPointsModel(::party.playerno()); // of the sum treeview only the header is neeeded // (workaround since there exists no foot for a treeview) this->party_points_sum_treeview = Gtk::manage(new Gtk::TreeView(Gtk::TreeStore::create(*this->party_points_model))); this->party_points_list = Gtk::TreeStore::create(*this->party_points_model); this->party_points_treeview = Gtk::manage(new Gtk::TreeView(this->party_points_list)); this->party_points_treeview->get_selection()->set_mode(Gtk::SELECTION_SINGLE); this->party_points_treeview->append_column("", this->party_points_model->empty); this->party_points_sum_treeview->append_column("", this->party_points_model->empty); this->party_points_sum_treeview->get_column(0)->set_alignment(Gtk::ALIGN_RIGHT); for (unsigned p = 0; p < ::party.playerno(); p++) { this->party_points_treeview->append_column(::party.player(p).name(), this->party_points_model->playerpoints[p]); this->party_points_treeview->get_column_cell_renderer(p + OFFSET_PLAYER)->property_xalign() = 0.5; this->party_points_treeview->get_column(p + OFFSET_PLAYER)->set_alignment(Gtk::ALIGN_CENTER); this->party_points_sum_treeview->append_column("0", this->party_points_model->playerpoints[p]); this->party_points_sum_treeview->get_column(p + OFFSET_PLAYER)->set_resizable(false); this->party_points_sum_treeview->get_column(p + OFFSET_PLAYER)->set_alignment(Gtk::ALIGN_CENTER); } // for (p < ::party.playerno()) this->party_points_treeview->append_column("game points", this->party_points_model->gamepoints_str); this->party_points_treeview->get_column_cell_renderer(OFFSET_GAMEPOINTS)->property_xalign() = 0.5; this->party_points_sum_treeview->append_column("", this->party_points_model->gamepoints_str); this->party_points_sum_treeview->get_column(OFFSET_GAMEPOINTS)->set_alignment(Gtk::ALIGN_CENTER); this->party_points_treeview->append_column("game type", this->party_points_model->gametype); this->party_points_sum_treeview->append_column("", this->party_points_model->gametype); #ifdef LINUX this->party_points_treeview->set_rules_hint(true); #endif for (unsigned c = 0; c < this->party_points_treeview->get_columns().size(); ++c) { Gtk::TreeView::Column* column = this->party_points_treeview->get_column(c); column->property_width().signal_changed().connect(sigc::mem_fun(*this, &PartyPoints::update_player_columns_size)); //column->property_width().signal_changed().connect(sigc::mem_fun(*this, &PartyPoints::sum_columns_size_update)); #ifdef WINDOWS column->add_attribute(*column->get_first_cell_renderer(), "background", 3); #endif column->set_cell_data_func(*column->get_first_cell_renderer(), sigc::bind(sigc::mem_fun(*this, &PartyPoints::set_cell_color), c)); } } // the points table { // point list Gtk::VBox* table_box = Gtk::manage(new Gtk::VBox(false)); Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0, 1)); table_vbox->pack_start(*alignment); alignment->add(*table_box); { // the scrolled window Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow); scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled_window->add(*(this->party_points_treeview)); scrolled_window->set_hadjustment(this->party_points_treeview->property_hadjustment()); scrolled_window->set_vadjustment(this->party_points_treeview->property_vadjustment()); table_box->pack_start(*scrolled_window, true, true); } // the scrolled window table_box->pack_end(*this->party_points_sum_treeview, false, true); } // point list { // the buttons { // show game overview Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0, 0)); this->show_game_overview_button = Gtk::manage(new Gtk::CheckButton("show game overview")); this->ui->translations->add(*(this->show_game_overview_button), ::translation("show game overview")); alignment->add(*(this->show_game_overview_button)); table_vbox->pack_end(*alignment, Gtk::PACK_SHRINK); this->show_game_overview_button->signal_toggled().connect(sigc::mem_fun(*this, &PartyPoints::show_game_overview_toggled)); } // show game overview { // add up points Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0, 0)); this->add_up_points = Gtk::manage(new Gtk::CheckButton("add up points")); this->ui->translations->add(*this->add_up_points, ::translation("add up points")); alignment->add(*this->add_up_points); table_vbox->pack_end(*alignment, Gtk::PACK_SHRINK); this->add_up_points->signal_toggled().connect(sigc::mem_fun(*this, &PartyPoints::recalc_all)); } // add up points { // collapse rounds Gtk::HBox* vbox = Gtk::manage(new Gtk::HBox(true)); Gtk::RadioButton::Group group; table_vbox->pack_end(*vbox, Gtk::PACK_SHRINK); { Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0, 0)); vbox->add(*alignment); this->collapse_rounds = Gtk::manage(new Gtk::RadioButton(group, "collapse rounds")); this->ui->translations->add(*this->collapse_rounds, ::translation("collapse rounds")); alignment->add(*this->collapse_rounds); this->collapse_rounds->signal_toggled().connect(sigc::mem_fun(*this, &PartyPoints::collaps_setting_changed)); } { Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER, 0, 0)); vbox->add(*alignment); this->expand_rounds = Gtk::manage(new Gtk::RadioButton(group, "expand rounds")); this->ui->translations->add(*this->expand_rounds, ::translation("expand rounds")); alignment->add(*this->expand_rounds); this->expand_rounds->signal_toggled().connect(sigc::mem_fun(*this, &PartyPoints::collaps_setting_changed)); } } // collapse rounds } // the buttons Gtk::Label* label = Gtk::manage(new Gtk::Label("table")); this->ui->translations->add(*label, ::translation("table")); this->notebook->append_page(*table_vbox, *label); } // table { // graph this->graph = new Graph(this); Gtk::Label* label = Gtk::manage(new Gtk::Label("graph")); this->ui->translations->add(*label, ::translation("graph")); this->notebook->append_page(*this->graph, *label); } // graph this->get_vbox()->pack_start(*this->notebook, Gtk::PACK_EXPAND_WIDGET); } // notebook { // remaining rounds / points this->remaining_rounds_label = Gtk::manage(new Gtk::Label("remaining rounds")); this->ui->translations->add(*this->remaining_rounds_label, ::translation("remaining rounds: %urounds%", 0u)); this->remaining_points_label = Gtk::manage(new Gtk::Label("remaining points")); this->ui->translations->add(*this->remaining_points_label, ::translation("remaining points: %upoints%", 0u)); Gtk::Box* box = Gtk::manage(new Gtk::HBox(true)); box->pack_start(*this->remaining_rounds_label, Gtk::PACK_SHRINK, 1 em); box->pack_end(*this->remaining_points_label, Gtk::PACK_SHRINK, 1 em); this->get_vbox()->pack_start(*box, false, true); } // remaining rounds / points { // action area 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, &Gtk::Widget::hide)); } // action area this->show_all_children(); { // signals this->signal_hide().connect(sigc::bind(sigc::mem_fun(*this->show_game_overview_button, &Gtk::ToggleButton::set_active), false)); this->party_points_treeview->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PartyPoints::row_selection_changed)); this->signal_show().connect(sigc::mem_fun(*this, &PartyPoints::update_player_columns_size)); this->signal_show().connect(sigc::mem_fun(*this, &PartyPoints::language_update)); this->party_points_treeview->signal_row_collapsed().connect(sigc::mem_fun(*this, &PartyPoints::row_collapsed_or_expanded)); this->party_points_treeview->signal_row_expanded().connect(sigc::mem_fun(*this, &PartyPoints::row_collapsed_or_expanded)); } // signals this->update_player_columns_size(); this->language_update(); this->set_default_size(0, 3 * this->ui->cards->height()); this->show_game_overview_button->set_sensitive(false); if (::game_status > GAMESTATUS::PARTY_NEW) this->recreate_all(); return ; } // void PartyPoints::init() /** ** the party is opened ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.3 **/ void PartyPoints::party_open() { if (!this->is_realized()) return ; this->recreate_all(); if (this->ui->party().rule()(Rule::NUMBER_OF_ROUNDS_LIMITED)) this->remaining_rounds_label->show(); else this->remaining_rounds_label->hide(); if (this->ui->party().rule()(Rule::POINTS_LIMITED)) this->remaining_points_label->show(); else this->remaining_points_label->hide(); return ; } // void PartyPoints::party_open() /** ** a round of the party is started ** ** @param round number of the round ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 **/ void PartyPoints::party_start_round(unsigned const round) { if (!this->is_realized()) return ; if (round == 0) this->update_sum(); if (this->collapse_rounds->get_active()) if (round > 0) this->party_points_treeview->collapse_row(this->party_points_list->get_path(this->round_rows.back())); return ; } // void PartyPoints::party_start_round(unsigned const round) /** ** ** the party is finished ** ** @param - ** ** @return - ** ** @version 0.6.8 ** ** @author Diether Knof ** **/ void PartyPoints::party_finish() { if (!this->is_realized()) return ; if (!this->round_rows.empty()) this->party_points_treeview->collapse_row(this->party_points_list->get_path(this->round_rows.back())); return ; } // void PartyPoints::party_finish() /** ** ** the party is closed ** ** @param - ** ** @return - ** ** @version 0.6.6 ** ** @author Diether Knof ** **/ void PartyPoints::party_close() { if (!this->is_realized()) return ; this->party_points_list->clear(); this->round_rows.clear(); this->game_rows.clear(); this->graph->draw_all(); this->game_overview->set_gameno(UINT_MAX); return ; } // void PartyPoints::party_close() /** ** the game has started: ** redraw the graph (because of solo games) ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.4 **/ void PartyPoints::game_start() { if (!this->is_realized()) return ; this->graph->draw_all(); return ; } // void PartyPoints::game_start() /** ** ** the game has finished: ** add a new row with the current game ** ** @param - ** ** @return - ** ** @version 0.6.1 ** ** @author Diether Knof ** **/ void PartyPoints::game_finished() { if (!this->is_realized()) return ; this->add_game(::party.gameno()); this->party_points_treeview->scroll_to_row(Gtk::TreePath(this->game_rows.back())); return ; } // void PartyPoints::game_finished() /** ** ** the name of 'player' has changed ** ** @param player the player with the changed name ** ** @return - ** ** @version 0.6.4 ** ** @author Diether Knof ** **/ void PartyPoints::name_changed(Player const& player) { if (!this->is_realized()) return ; // ToDo: Here 'player.no()' means the number in the party, not in the game this->party_points_treeview->get_column(player.no() + OFFSET_PLAYER)->set_title(" " + player.name() + " "); this->game_overview->name_changed(player); this->party_points_treeview->columns_autosize(); return ; } // void PartyPoints::name_changed(Player const& player) /** ** recalculates the party points ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.3 **/ void PartyPoints::recalc_all() { if (!this->is_realized()) return ; if (::game_status <= GAMESTATUS::PARTY_NEW) return ; for (unsigned g = 0; g < this->game_rows.size(); g++) this->set_points(g); this->update_sum(); this->graph->draw_all(); return ; } // void PartyPoints::recalc_all() /** ** recreates the party points ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.9 ** ** @todo round limits **/ void PartyPoints::recreate_all() { if (!this->is_realized()) return ; if (!&this->ui->party()) return ; this->party_points_list->clear(); this->round_rows.clear(); this->game_rows.clear(); Party const& party = this->ui->party(); unsigned r = 0; // round startgame for (unsigned g = 0; g <= party.gameno(); ++g) { if ( (g == party.gameno()) && (::game_status != GAMESTATUS::GAME_FINISHED) ) break; if (g == party.round_startgame(r)) { this->party_start_round(r); r += 1; } this->add_game(g); } // for (g <= party.gameno()) this->update_sum(); this->graph->draw_all(); return ; } // void PartyPoints::recreate_all() /** ** ** add the row for the game 'gameno' ** ** @param gameno number of the game to be added ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** ** @todo color the row according to the gametype ** **/ void PartyPoints::add_game(unsigned const gameno) { if (!this->is_realized()) return ; //Gtk::TreeModel::Row row = *(this->party_points_list->append()); if (this->ui->party().starts_new_round(gameno)) { this->round_rows.push_back(*this->party_points_list->append()); this->game_rows.push_back(this->round_rows.back()); } else { this->game_rows.push_back(*this->party_points_list->append(this->round_rows.back().children())); if (this->round_rows.back()[this->party_points_model->gameno] + 1 == gameno) this->party_points_treeview->expand_row(this->party_points_list->get_path(this->round_rows.back()), true); } this->set_points(gameno); this->update_sum(); this->graph->draw_all(); return ; } // void PartyPoints::add_game(unsigned const gameno) /** ** update the values of 'round' ** ** @param gameno game number ** ** @return - ** ** @author Diether Knof ** ** @version 0.6.7 **/ void PartyPoints::set_points(unsigned const gameno) { if (!this->is_realized()) return ; DEBUG_ASSERTION((gameno < this->game_rows.size()), "PartyPoints::set_points(gameno)\n" " gameno = " << gameno << " >= " << this->game_rows.size() << " = number of rows"); Gtk::TreeModel::Row& row = this->game_rows[gameno]; Party const& party = this->ui->party(); ::GameSummary const& game_summary = party.game_summary(gameno); if ( party.starts_new_round(gameno) && row.children()) if (!this->party_points_treeview->row_expanded(this->party_points_list->get_path(row))) { this->update_round(row[this->party_points_model->round]); return ; } row[this->party_points_model->round] = party.round_of_game(gameno); if (party.round_of_game(gameno) % 2 == 0) row[this->party_points_model->round_color] = "#F8F8F8"; else row[this->party_points_model->round_color] = "#F0F0F0"; row[this->party_points_model->gameno] = gameno; row[this->party_points_model->gameno_str] = DK::Utils::String::to_string(gameno); row[this->party_points_model->gamepoints_str] = DK::Utils::String::to_string(game_summary.points()); #ifdef POSTPHONED if (game_summary.game_type() == GAMETYPE::NORMAL) ; //row[this->party_points_model->gametype] = NULL; else { Glib::RefPtr pixbuf = this->ui->icons->icon(g_ame_points.game_type()); int const height = 20; row[this->party_points_model->gametype] = pixbuf->scale_simple(pixbuf->get_width() * height / pixbuf->get_height(), height, Gdk::INTERP_TILES); } #else if (game_summary.game_type() == GAMETYPE::NORMAL) row[this->party_points_model->gametype] = ""; else row[this->party_points_model->gametype] = ::translation(game_summary.game_type()).translation(); #endif for (unsigned p = 0; p < party.playerno(); p++) { // ToDo: p is here the player in the party, not in the game #ifdef OUTDATED // 0.6.8 2005-01-03 if ( (game_summary.winnerteam() == TEAM::NOTEAM) || ( (game_summary.rule()(Rule::COUNTING) == COUNTING_NS::PLUS) && (game_summary.team(p) == game_summary.winnerteam()) ) || ( (game_summary.rule()(Rule::COUNTING) == COUNTING_NS::MINUS) && (game_summary.team(p) != game_summary.winnerteam()) ) || (game_summary.rule()(Rule::COUNTING) == COUNTING_NS::PLUSMINUS) ) { } #endif if (game_summary.player_get_points(p)) { if (this->add_up_points->get_active()) row[this->party_points_model->playerpoints[p]] = DK::Utils::String::to_string(party.pointsum_till_game(gameno, p)); else row[this->party_points_model->playerpoints[p]] = DK::Utils::String::to_string(party.game_summary(gameno).points(p)); } else { row[this->party_points_model->playerpoints[p]] = ""; } } // for (p < party.playerno()) return ; } // void PartyPoints::set_points(unsigned const gameno) /** ** ** a row has been collapsed/expanded ** ** @param iterator ** @param path ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** **/ void PartyPoints::row_collapsed_or_expanded(Gtk::TreeModel::iterator const& iterator, Gtk::TreeModel::Path const& path) { if (!this->is_realized()) return ; // ToDo: verify that it is a round-row Gtk::TreeModel::Row row = *this->party_points_treeview->get_model()->get_iter(path); if (this->party_points_treeview->row_expanded(path)) this->set_points(row[this->party_points_model->gameno]); else this->update_round(row[this->party_points_model->round]); return ; } // void PartyPoints::row_collapsed_or_expanded(Gtk::TreeModel::iterator const& iterator, Gtk::TreeModel::Path const& path) /** ** ** update the values of 'round' ** ** @param round round which is to be updated ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** **/ void PartyPoints::update_round(unsigned const round) { if (!this->is_realized()) return ; DEBUG_ASSERTION((this->round_rows.size() > round), "PartyPoints::update_round(round):\n" " round too great: round = " << round << " >= this->round_rows.size() = " << this->round_rows.size()); if (::game_status <= GAMESTATUS::PARTY_NEW) return ; Party const& party = this->ui->party(); Gtk::TreeModel::Row& row = this->round_rows[round]; row[this->party_points_model->gameno_str] = ""; row[this->party_points_model->gametype] = ""; if (this->add_up_points->get_active()) { for (unsigned p = 0; p < party.playerno(); ++p) row[this->party_points_model->playerpoints[p]] = DK::Utils::String::to_string(party.pointsum_till_round(round, p)); row[this->party_points_model->gamepoints_str] = DK::Utils::String::to_string(party.pointsum_till_round(round)); } else { for (unsigned p = 0; p < party.playerno(); ++p) row[this->party_points_model->playerpoints[p]] = DK::Utils::String::to_string(party.pointsum_in_round(round, p)); row[this->party_points_model->gamepoints_str] = DK::Utils::String::to_string(party.pointsum_in_round(round)); } return ; } // void PartyPoints::update_round(unsigned const round) /** ** ** update the sum ** ** @param - ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** **/ void PartyPoints::update_sum() { if (!this->is_realized()) return ; if (::game_status <= GAMESTATUS::PARTY_NEW) { for (unsigned p = 0; p < party.playerno(); ++p) this->party_points_sum_treeview->get_column(p + OFFSET_PLAYER)->set_title(""); this->party_points_sum_treeview->get_column(OFFSET_GAMEPOINTS)->set_title(""); this->party_points_sum_treeview->get_column(0)->set_title(""); return ; } // if (::game_status <= GAMESTATUS::PARTY_NEW) Party const& party = this->ui->party(); // udpate the sum for (unsigned p = 0; p < party.playerno(); ++p) this->party_points_sum_treeview->get_column(p + OFFSET_PLAYER)->set_title(DK::Utils::String::to_string(party.pointsum(p))); this->party_points_sum_treeview->get_column(OFFSET_GAMEPOINTS)->set_title(DK::Utils::String::to_string(party.pointsum())); this->party_points_sum_treeview->get_column(0)->set_title(" " + DK::Utils::String::to_string(party.gameno() + 1) + " "); this->sum_columns_size_update(); if (party.rule()(Rule::NUMBER_OF_ROUNDS_LIMITED)) this->ui->translations->change(*this->remaining_rounds_label, ::translation("remaining rounds: %urounds%", party.remaining_rounds()) ); if (party.rule()(Rule::POINTS_LIMITED)) this->ui->translations->change(*this->remaining_points_label, ::translation("remaining points: %upoints%", ( (party.points() > 0) ? static_cast(party.points()) : 0u) ) ); if ( party.rule()(Rule::NUMBER_OF_ROUNDS_LIMITED) || party.rule()(Rule::POINTS_LIMITED)) this->remaining_rounds_label->get_parent()->set_border_width(1 ex); else this->remaining_rounds_label->get_parent()->set_border_width(0); return ; } // void PartyPoints::update_sum() /** ** ** update the column size of the players ** ** @param - ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** ** @todo understand why this works ** **/ void PartyPoints::update_player_columns_size() { if (!this->is_visible()) return ; Party const& party = this->ui->party(); for (unsigned c = OFFSET_PLAYER; c < OFFSET_PLAYER + party.playerno(); ++c) { this->party_points_treeview->get_column(c)->set_min_width(-1); } // for (c) { int width = -1; for (unsigned c = OFFSET_PLAYER; c < OFFSET_PLAYER + party.playerno(); ++c) { width = std::max(width, this->party_points_treeview->get_column(c)->get_width()); } // for (c) for (unsigned c = OFFSET_PLAYER; c < OFFSET_PLAYER + party.playerno(); ++c) { if (this->party_points_treeview->get_column(c)->get_min_width() < width) this->party_points_treeview->get_column(c)->set_min_width(width); } // for (c) } this->sum_columns_size_update(); return ; } // void PartyPoints::update_player_columns_size() /** ** ** the row selection has changed: ** show the belonging game summary ** ** @param - ** ** @return - ** ** @version 0.6.1 ** ** @author Diether Knof ** **/ void PartyPoints::row_selection_changed() { Glib::RefPtr selection = this->party_points_treeview->get_selection(); this->show_game_overview_button->set_sensitive(selection->get_selected_rows().size() == 1); if (selection->get_selected()) { Gtk::TreeRow row = *(selection->get_selected()); unsigned const gameno = row[this->party_points_model->gameno]; this->game_overview->set_gameno(gameno); } else { // if !(selection->get_selected()) this->game_overview->set_gameno(UINT_MAX); this->game_overview->hide(); } // if !(selection->get_selected()) return ; } // void PartyPoints::row_selection_changed() /** ** ** update the column size of the sum treeview ** ** @param - ** ** @return - ** ** @version 0.6.1 ** ** @author Diether Knof ** **/ void PartyPoints::sum_columns_size_update() { if (!this->is_realized()) return ; for (unsigned c = 0; c < this->party_points_treeview->get_columns().size(); ++c) if (this->party_points_treeview->get_column(c)->get_visible()) { int const width = this->party_points_treeview->get_column(c)->get_width(); #ifdef WORKAROUND this->party_points_sum_treeview->get_column(c)->set_min_width(width); this->party_points_sum_treeview->get_column(c)->set_max_width(width); #else // does not work this->party_points_sum_treeview->get_column(c)->set_fixed_width(width); this->party_points_sum_treeview->get_column(c)->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); #endif } return ; } // void PartyPoints::sum_columns_size_update() /** ** ** clear the selection ** ** @param - ** ** @return - ** ** @version 0.6.3 ** ** @author Diether Knof ** **/ void PartyPoints::clear_selection() { if (!this->is_realized()) return ; this->party_points_treeview->get_selection()->unselect_all(); return ; } // void PartyPoints::clear_selection() /** ** ** toggle the showing of the 'game overview' window ** ** @param - ** ** @return - ** ** @version 0.6.3 ** ** @author Diether Knof ** **/ void PartyPoints::show_game_overview_toggled() { if (!this->is_realized()) return ; if (this->game_overview) { if (this->show_game_overview_button->get_active()) { this->row_selection_changed(); this->game_overview->present(); #ifdef WORKAROUND // 'game_overview' cannot get the gameno in the initialisation if (this->game_overview->gameno() == UINT_MAX) this->row_selection_changed(); #endif } else { this->game_overview->hide(); } } // if (this->game_overview) return ; } // void PartyPoints::show_game_overview_toggled() /** ** ** toggle the collappsing of the rounds ** ** @param - ** ** @return - ** ** @version 0.6.3 ** ** @author Diether Knof ** **/ void PartyPoints::collaps_setting_changed() { if (!this->is_realized()) return ; if (this->collapse_rounds->get_active()) this->party_points_treeview->collapse_all(); else this->party_points_treeview->expand_all(); return ; } // void PartyPoints::collaps_setting_changed() /** ** ** updates all language elements ** ** @param - ** ** @return - ** ** @version 0.6.1 ** ** @author Diether Knof ** **/ void PartyPoints::language_update() { if (!this->is_realized()) return ; if (::game_status <= GAMESTATUS::PARTY_NEW) return ; #ifdef OUTDATED this->party_points_treeview->get_column(OFFSET_ROUND)->set_title(::translation("round").translation()); this->party_points_treeview->get_column(OFFSET_GAMENO)->set_title(::translation("game").translation()); #endif this->party_points_treeview->get_column(OFFSET_GAMETYPE)->set_title(::translation("gametype").translation()); this->party_points_treeview->get_column(OFFSET_GAMEPOINTS)->set_title(::translation("game points").translation()); for (vector::iterator row = this->game_rows.begin(); row != this->game_rows.end(); ++row) { ::GameSummary const& game_summary = this->ui->party().game_summary((*row)[this->party_points_model->gameno]); if (game_summary.game_type() == GAMETYPE::NORMAL) (*row)[this->party_points_model->gametype] = ""; else (*row)[this->party_points_model->gametype] = ::translation(game_summary.game_type()).translation(); } // for (row \in this->game_rows) for (vector::iterator row = this->round_rows.begin(); row != this->round_rows.end(); ++row) { this->update_round((*row)[this->party_points_model->round]); } // for (rw \in this->round_rows) return ; } // void PartyPoints::language_update() /** ** ** changes the color of the cell at 'iterator' ** ** @param cell_renderer cell renderer to change ** @param iterator row ** @param column the column ** ** @return - ** ** @version 0.6.7 ** ** @author Diether Knof ** **/ void PartyPoints::set_cell_color(Gtk::CellRenderer* cell_renderer, Gtk::TreeModel::iterator const& iterator, unsigned const column) { if (!this->is_realized()) return ; Gtk::TreeModel::Row const row = *iterator; Gdk::Color color; unsigned round; if (this->party_points_list->iter_depth(iterator) == 0) round = row[this->party_points_model->round]; else { Gtk::TreePath path = this->party_points_list->get_path(iterator); path.up(); round = (*this->party_points_treeview->get_model()->get_iter(path) )[this->party_points_model->round]; } unsigned const gameno = row[this->party_points_model->gameno]; Party const& party = this->ui->party(); ::GameSummary const& game_summary = party.game_summary(gameno); #ifdef POSTPHONED if (this->party_points_treeview->row_expanded(*iterator)) #endif if ( (game_summary.soloplayer_no() != UINT_MAX) && ( (column == OFFSET_GAMETYPE) || (column == OFFSET_PLAYER + game_summary.soloplayer_no()) ) ) color = this->color(game_summary); dynamic_cast(cell_renderer)->property_foreground_gdk() = color; #ifdef POSTPHONED // the whole column is made italic // make the name of the startplayer bold if ( (column >= OFFSET_PLAYER) && (column < OFFSET_PLAYER + party.playerno()) && (game_summary.soloplayer_no() != UINT_MAX) && (column - OFFSET_PLAYER == game_summary.soloplayer_no())) { dynamic_cast(cell_renderer)->property_style() = Pango::STYLE_ITALIC; } // if (column of the soloplayer) #endif return ; } // void PartyPoints::set_cell_color(Gtk::CellRenderer* cell_renderer, Gtk::TreeModel::iterator const& iterator, unsigned const column) /** ** -> result ** ** @param game_summary game summary ** ** @return (background) color for the game summary ** ** @author Diether Knof ** ** @version 0.6.7 **/ Gdk::Color PartyPoints::color(::GameSummary const& game_summary) { Gdk::Color color; switch (game_summary.game_type()) { case GAMETYPE::NORMAL: color.set("black"); break; case GAMETYPE::THROWN_NINES: case GAMETYPE::THROWN_KINGS: case GAMETYPE::THROWN_NINES_AND_KINGS: case GAMETYPE::FOX_HIGHEST_TRUMP: color.set("#ffff00"); break; case GAMETYPE::POVERTY: color.set("#B8860B"); break; case GAMETYPE::GENSCHER: color.set("#7FFFD4"); break; case GAMETYPE::MARRIAGE: color.set("#1E90FF"); break; case GAMETYPE::MARRIAGE_SOLO: case GAMETYPE::MARRIAGE_SILENT: color.set("#00BFFF"); break; case GAMETYPE::SOLO_JACK: case GAMETYPE::SOLO_QUEEN: case GAMETYPE::SOLO_KING: case GAMETYPE::SOLO_QUEEN_JACK: case GAMETYPE::SOLO_KING_JACK: case GAMETYPE::SOLO_KING_QUEEN: case GAMETYPE::SOLO_KOEHLER: case GAMETYPE::SOLO_CLUB: case GAMETYPE::SOLO_SPADE: case GAMETYPE::SOLO_HEART: case GAMETYPE::SOLO_DIAMOND: case GAMETYPE::SOLO_MEATLESS: if (game_summary.is_duty_solo()) color.set("#FF0000"); else color.set("#ffaf00"); break; } // switch (game_type) return color; } // Gdk::Color PartyPoints::color(::GameSummary const& game_summary) /** ** a key has been pressed ** C-o: output of the points on 'stdout' ** ** @param key the key ** ** @return whether the key was managed ** ** @author Diether Knof ** ** @version 0.7.4 ** ** @todo print the party points **/ bool PartyPoints::on_key_press_event(GdkEventKey* key) { bool managed = false; if ((key->state & ~GDK_SHIFT_MASK) == GDK_CONTROL_MASK) { switch (key->keyval) { case GDK_o: // ouput of the party points // ToDo managed = true; break; } // switch (key->keyval) } // if (key->state == GDK_CONTROL_MASK) return (managed || this->StickyDialog::on_key_press_event(key) || this->ui->key_press(key)); } // bool PartyPoints::on_key_press_event(GdkEventKey* key) } // namespace UI_GTKMM_NS #endif // #ifdef USE_UI_GTKMM