1 /**********************************************************************
2 *
3 * FreeDoko a Doppelkopf-Game
4 *
5 * Copyright (C) 2001 – 2018 by Diether Knof and Borg Enders
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 * You can find this license in the file 'gpl.txt'.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 *
23 * Contact:
24 * Diether Knof dknof@posteo.de
25 *
26 *********************************************************************/
27
28 #include "constants.h"
29
30 #ifdef USE_UI_GTKMM
31
32 #include "cards_order.h"
33
34 #include "../ui.h"
35 #include "../cards.h"
36
37 #include <gtkmm/radiobutton.h>
38 #include <gtkmm/grid.h>
39 #include <gtkmm/box.h>
40 #include <gtkmm/arrow.h>
41 #include <gtkmm/image.h>
42
43 namespace UI_GTKMM_NS {
44 using Direction = ::Preferences::CardsOrder::Direction;
45
46 /** constructor
47 **/
CardsOrder(Preferences & preferences)48 Preferences::CardsOrder::CardsOrder(Preferences& preferences) :
49 Base(&preferences),
50 preferences_(preferences)
51 {
52 this->init();
53 }
54
55 /** destructor
56 **/
57 Preferences::CardsOrder::~CardsOrder()
58 = default;
59
60 /** use the cards order as a widget
61 **/
operator Gtk::Widget&()62 Preferences::CardsOrder::operator Gtk::Widget&()
63 {
64 return *this->container;
65 }
66
67 /** creates all subelements for the cardsorder
68 **/
69 void
init()70 Preferences::CardsOrder::init()
71 {
72 auto const& cards_order = ::preferences(::Preferences::Type::cards_order);
73 this->container = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 1 EX));
74 { // sorted/unsorted
75 auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
76 vbox->set_halign(Gtk::ALIGN_CENTER);
77
78 Gtk::RadioButton::Group group;
79
80 this->sorted_button
81 = Gtk::manage(new Gtk::RadioButton(group, _("Button::sorted")));
82 vbox->add(*(this->sorted_button));
83
84 this->unsorted_button
85 = Gtk::manage(new Gtk::RadioButton(group, _("Button::unsorted")));
86 vbox->add(*(this->unsorted_button));
87
88 if (cards_order.mixed())
89 this->unsorted_button->set_active();
90 else
91 this->sorted_button->set_active();
92
93 this->sorted_button->signal_toggled().connect(sigc::mem_fun(*this, &CardsOrder::set_sorted));
94 this->unsorted_button->signal_toggled().connect(sigc::mem_fun(*this, &CardsOrder::set_sorted));
95 this->container->add(*vbox);
96 } // sorted/unsorted
97
98 { // the cards
99 this->cards_container = Gtk::manage(new Gtk::Grid());
100 auto grid = this->cards_container;
101 this->container->add(*grid);
102 grid->set_row_spacing(1 EX);
103 grid->set_column_spacing(1 EM);
104
105 for (unsigned p = 0; p < Card::number_of_tcolors; ++p) {
106 { // left/right button
107 auto hbox = Gtk::manage(new Gtk::Box());
108 hbox->set_homogeneous();
109 grid->attach(*hbox, p, 0, 1, 1);
110
111 auto left_button = Gtk::manage(new Gtk::Button());
112 left_button->add(*Gtk::manage(new Gtk::Arrow(Gtk::ARROW_LEFT,
113 Gtk::SHADOW_OUT)));
114 hbox->add(*left_button);
115 left_button->signal_clicked().connect(sigc::bind<unsigned const>(sigc::mem_fun(*this, &CardsOrder::pos_to_left), p));
116
117 auto right_button = Gtk::manage(new Gtk::Button());
118 right_button->add(*Gtk::manage(new Gtk::Arrow(Gtk::ARROW_RIGHT,
119 Gtk::SHADOW_OUT)));
120 hbox->add(*right_button);
121 right_button->signal_clicked().connect(sigc::bind<unsigned const>(sigc::mem_fun(*this, &CardsOrder::pos_to_right), p));
122 } // left/right button
123 { // the image
124 if (cards_order.tcolor(p) == Card::trump) {
125 this->sorting_tcolor_image.push_back(this->ui->cards->new_managed_image(Card::club_queen));
126 } else {
127 this->sorting_tcolor_image.push_back(this->ui->cards->new_managed_image(Card(cards_order.tcolor(p), Card::ace)));
128 }
129 grid->attach(*this->sorting_tcolor_image.back(), p, 1, 1, 1);
130 } // the image
131 { // up/down buttons
132 auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
133 grid->attach(*vbox, p, 2, 1, 1);
134
135 Gtk::RadioButton::Group group;
136 this->sorting_up_button.push_back(Gtk::manage(new Gtk::RadioButton(group, _(Direction::up))));
137 vbox->add(*(this->sorting_up_button.back()));
138
139 this->sorting_down_button.push_back(Gtk::manage(new Gtk::RadioButton(group, _(Direction::down))));
140 vbox->add(*(this->sorting_down_button.back()));
141
142 // events
143 this->sorting_up_button.back()->set_active(cards_order.direction(p) == Direction::up);
144 this->sorting_down_button.back()->set_active(cards_order.direction(p) == Direction::down);
145 this->sorting_up_button.back()->signal_toggled().connect(sigc::bind<unsigned const>(sigc::mem_fun(*this, &CardsOrder::set_direction), p));
146 this->sorting_down_button.back()->signal_toggled().connect(sigc::bind<unsigned const>(sigc::mem_fun(*this, &CardsOrder::set_direction), p));
147 } // up/down buttons
148 } // for (c < Card::number_of_tcolors)
149 } // the cards
150 }
151
152 /** update the cards order
153 **/
154 void
update()155 Preferences::CardsOrder::update()
156 {
157 auto& cards_order = ::preferences(::Preferences::Type::cards_order);
158 if (cards_order.mixed()) {
159 this->unsorted_button->set_active();
160 this->cards_container->set_sensitive(false);
161 } else {
162 this->sorted_button->set_active();
163 this->cards_container->set_sensitive(true);
164
165 for (unsigned p = 0; p < Card::number_of_tcolors; ++p) {
166 if (cards_order.tcolor(p) == Card::trump)
167 this->ui->cards->change_managed(this->sorting_tcolor_image[p],
168 Card::club_queen);
169 else
170 this->ui->cards->change_managed(this->sorting_tcolor_image[p],
171 Card(cards_order.tcolor(p), Card::ace));
172
173 if (cards_order.direction(p)
174 == Direction::up)
175 this->sorting_up_button[p]->set_active();
176 else
177 this->sorting_down_button[p]->set_active();
178
179 } // for (n < Card::number_of_tcolors)
180 } // if !(::preferences(::Preferences::Type::cards_order).mixed())
181 }
182
183 /** event: set the sorting direction
184 **
185 ** @param pos the position which is changed
186 **/
187 void
set_direction(unsigned const pos)188 Preferences::CardsOrder::set_direction(unsigned const pos)
189 {
190 auto& cards_order = ::preferences(::Preferences::Type::cards_order);
191 cards_order.sorted_set(true);
192 if (this->sorting_up_button[pos]->get_active())
193 cards_order.direction_set(pos, Direction::up);
194 else
195 cards_order.direction_set(pos, Direction::down);
196 }
197
198 /** event: shift the type at 'pos' one position to the left
199 **
200 ** @param pos the position which is shifted
201 **/
202 void
pos_to_left(unsigned const pos)203 Preferences::CardsOrder::pos_to_left(unsigned const pos)
204 {
205 auto& cards_order = ::preferences(::Preferences::Type::cards_order);
206 cards_order.sorted_set(true);
207 cards_order.pos_to_left(pos);
208 }
209
210 /** event: shift the type at 'pos' one position to the right
211 **
212 ** @param pos the position which is shifted
213 **/
214 void
pos_to_right(unsigned const pos)215 Preferences::CardsOrder::pos_to_right(unsigned const pos)
216 {
217 auto& cards_order = ::preferences(::Preferences::Type::cards_order);
218 cards_order.sorted_set(true);
219 cards_order.pos_to_right(pos);
220 }
221
222 /** event: set the sorted state
223 **/
224 void
set_sorted()225 Preferences::CardsOrder::set_sorted()
226 {
227 auto& cards_order = ::preferences(::Preferences::Type::cards_order);
228 cards_order.sorted_set(this->sorted_button->get_active());
229 }
230
231 } // namespace UI_GTKMM_NS
232
233 #endif // #ifdef USE_UI_GTKMM
234