1 // Copyright (C) 2011, 2014, 2015, 2020 Ben Asselstine
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 // 02110-1301, USA.
17
18 #include <config.h>
19
20 #include <gtkmm.h>
21
22 #include "stack-army-button.h"
23 #include "stack.h"
24 #include "army.h"
25
26 #include "input-helpers.h"
27 #include "builder-cache.h"
28 #include "army-info-tip.h"
29 #include "ucompose.hpp"
30 #include "ImageCache.h"
31 #include "File.h"
32 #include "playerlist.h"
33 #include "player.h"
34 #include "shield.h"
35 #include "font-size.h"
36
create()37 StackArmyButton * StackArmyButton::create()
38 {
39 Glib::ustring file = "stack-army-button-large-screen.ui";
40 Glib::RefPtr<Gtk::Builder> xml = BuilderCache::get(file);
41
42 StackArmyButton *box;
43 xml->get_widget_derived("box", box);
44 box->d_stack = NULL;
45 box->d_army = NULL;
46 box->d_circle_colour_id = 0;
47 box->army_button->set_active(false);
48 return box;
49 }
50
StackArmyButton(BaseObjectType * baseObject,const Glib::RefPtr<Gtk::Builder> & xml)51 StackArmyButton::StackArmyButton(BaseObjectType* baseObject, const Glib::RefPtr<Gtk::Builder> &xml)
52 : Gtk::Box(baseObject)
53 {
54 army_info_tip = NULL;
55 xml->get_widget("army_button", army_button);
56 xml->get_widget("army_image", army_image);
57 xml->get_widget("army_label", army_label);
58 xml->get_widget("eventbox", eventbox);
59 eventbox->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
60 xml->get_widget("stack_button", stack_button);
61 xml->get_widget("stack_image", stack_image);
62 xml->get_widget("stack_button_container", stack_button_container);
63 memset (army_conn, 0, sizeof (army_conn));
64 }
65
~StackArmyButton()66 StackArmyButton::~StackArmyButton()
67 {
68 if (army_info_tip)
69 delete army_info_tip;
70 }
71
update_stack_button(bool selected)72 void StackArmyButton::update_stack_button(bool selected)
73 {
74 if (d_stack)
75 {
76 stack_image->clear();
77 if (selected)
78 stack_image->property_pixbuf() =
79 stack_button->render_icon_pixbuf(Gtk::Stock::YES, Gtk::ICON_SIZE_MENU);
80 else
81 stack_image->property_pixbuf() =
82 stack_button->render_icon_pixbuf(Gtk::Stock::NO, Gtk::ICON_SIZE_MENU);
83 stack_button->show();
84 }
85 else
86 stack_button->hide();
87 }
88
on_army_button_event(GdkEventButton * e)89 bool StackArmyButton::on_army_button_event(GdkEventButton *e)
90 {
91 MouseButtonEvent ev = to_input_event(e);
92 if (ev.button == MouseButtonEvent::RIGHT_BUTTON &&
93 ev.state == MouseButtonEvent::PRESSED)
94 {
95 if (army_info_tip)
96 delete army_info_tip;
97 army_info_tip = new ArmyInfoTip(army_button, d_army);
98 return true;
99 }
100 else if (ev.button == MouseButtonEvent::RIGHT_BUTTON &&
101 ev.state == MouseButtonEvent::RELEASED)
102 {
103 if (army_info_tip)
104 {
105 delete army_info_tip;
106 army_info_tip = NULL;
107 }
108 return true;
109 }
110
111 return false;
112 }
113
fill_buttons()114 void StackArmyButton::fill_buttons()
115 {
116 fill_army_button();
117 fill_stack_button();
118 }
119
fill_army_button()120 void StackArmyButton::fill_army_button()
121 {
122 Player *p = Playerlist::getActiveplayer();
123 ImageCache *gc = ImageCache::getInstance();
124 if (d_army)
125 {
126 bool greyed_out = false;
127 Stack *active_stack = p->getActivestack();
128 if (active_stack->getArmyById(d_army->getId()) == NULL)
129 greyed_out = true;
130 army_image->property_pixbuf() =
131 gc->getCircledArmyPic(p->getArmyset(), d_army->getTypeId(),
132 p, d_army->getMedalBonuses(), greyed_out,
133 !greyed_out ? p->getId() : d_circle_colour_id,
134 true,
135 FontSize::getInstance ()->get_height ())->to_pixbuf();
136
137 Pango::AttrList attrs;
138 Pango::Attribute scale = Pango::Attribute::create_attr_scale(1.2);
139 attrs.insert(scale);
140 army_label->set_attributes(attrs);
141 army_label->set_label(String::ucompose("%1", d_army->getMoves()));
142 }
143 else
144 {
145 army_image->property_pixbuf() =
146 gc->getCircledArmyPic(p->getArmyset(), 0, p, NULL, false,
147 Shield::NEUTRAL, false,
148 FontSize::getInstance ()->get_height ())->to_pixbuf();
149
150 stack_image->clear();
151 army_label->set_text(" ");
152 }
153 }
154
fill_stack_button()155 void StackArmyButton::fill_stack_button()
156 {
157 update_stack_button
158 (d_stack == Playerlist::getActiveplayer()->getActivestack());
159 }
160
clear_signals()161 void StackArmyButton::clear_signals()
162 {
163 //clear the old signals
164 stack_conn.disconnect();
165 for (unsigned int i = 0; i < 3; i++)
166 army_conn[i].disconnect();
167 }
168
setup_signals()169 void StackArmyButton::setup_signals()
170 {
171 clear_signals();
172 if (d_stack)
173 stack_conn = stack_button->signal_clicked().connect
174 (sigc::mem_fun(stack_clicked, &sigc::signal<void>::emit));
175 if (d_army)
176 {
177 army_conn[0] = army_button->signal_toggled().connect
178 (sigc::mem_fun(army_toggled, &sigc::signal<void>::emit));
179 army_conn[1] = army_button->signal_button_press_event().connect
180 (sigc::mem_fun(*this, &StackArmyButton::on_army_button_event), false);
181 army_conn[2] = army_button->signal_button_release_event().connect
182 (sigc::mem_fun(*this, &StackArmyButton::on_army_button_event), false);
183 }
184 }
185
reset()186 void StackArmyButton::reset()
187 {
188 clear_signals();
189 army_button->set_sensitive(true);
190 stack_button->set_sensitive(true);
191 draw(NULL, NULL, 0, false);
192 army_button->set_sensitive(false);
193 stack_button->set_sensitive(false);
194 }
195
draw(Stack * s,Army * a,guint32 circle_colour_id,bool toggled)196 void StackArmyButton::draw(Stack *s, Army *a, guint32 circle_colour_id, bool toggled)
197 {
198 d_stack = s;
199 d_army = a;
200 d_circle_colour_id = circle_colour_id;
201 army_button->set_sensitive(true);
202 stack_button->set_sensitive(true);
203 if (army_button->get_active() != toggled)
204 army_button->set_active(toggled);
205 fill_buttons();
206 setup_signals();
207 }
208