Freeciv-3.1
Loading...
Searching...
No Matches
voteinfo_bar.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 2, or (at your option)
6 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 General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <gtk/gtk.h>
19
20/* utility */
21#include "fcintl.h"
22#include "mem.h"
23#include "support.h"
24
25/* client */
26#include "options.h"
27#include "voteinfo.h"
28
29/* client/gui-gtk-3.22 */
30#include "chatline.h"
31#include "pages.h"
32
33#include "voteinfo_bar.h"
34
35/* A set of widgets. */
36struct voteinfo_bar {
37 GtkWidget *box;
38 GtkWidget *next_button;
39 GtkWidget *label;
40 GtkWidget *yes_button;
41 GtkWidget *no_button;
42 GtkWidget *abstain_button;
43 GtkWidget *yes_count_label;
44 GtkWidget *no_count_label;
45 GtkWidget *abstain_count_label;
46 GtkWidget *voter_count_label;
47};
48
49GtkWidget *pregame_votebar = NULL; /* PAGE_START voteinfo bar. */
50GtkWidget *ingame_votebar = NULL; /* PAGE_GAME voteinfo bar. */
51
52/**********************************************************************/
55static void voteinfo_bar_do_vote_callback(GtkWidget *w, gpointer userdata)
56{
58 struct voteinfo *vi;
59
60 vote = GPOINTER_TO_INT(userdata);
62
63 if (vi == NULL) {
64 return;
65 }
66
68}
69
70/**********************************************************************/
73static void voteinfo_bar_next_callback(GtkWidget *w, gpointer userdata)
74{
77}
78
79/**********************************************************************/
82static void voteinfo_bar_destroy(GtkWidget *w, gpointer userdata)
83{
84 free((struct voteinfo_bar *) userdata);
85}
86
87/**********************************************************************/
92GtkWidget *voteinfo_bar_new(bool split_bar)
93{
94 GtkWidget *label, *button, *vbox, *hbox, *arrow;
95 struct voteinfo_bar *vib;
96 const int BUTTON_HEIGHT = 12;
97
98 vib = fc_calloc(1, sizeof(struct voteinfo_bar));
99
100 if (!split_bar) {
101 hbox = gtk_grid_new();
102 gtk_grid_set_column_spacing(GTK_GRID(hbox), 4);
103 g_object_set_data(G_OBJECT(hbox), "voteinfo_bar", vib);
104 g_signal_connect(hbox, "destroy", G_CALLBACK(voteinfo_bar_destroy), vib);
105 vib->box = hbox;
106 vbox = NULL; /* The compiler may require it. */
107 } else {
108 vbox = gtk_grid_new();
109 gtk_grid_set_row_homogeneous(GTK_GRID(vbox), TRUE);
110 gtk_orientable_set_orientation(GTK_ORIENTABLE(vbox),
111 GTK_ORIENTATION_VERTICAL);
112 gtk_grid_set_row_spacing(GTK_GRID(vbox), 4);
113 g_object_set_data(G_OBJECT(vbox), "voteinfo_bar", vib);
114 g_signal_connect(vbox, "destroy", G_CALLBACK(voteinfo_bar_destroy), vib);
115 vib->box = vbox;
116 hbox = gtk_grid_new();
117 gtk_grid_set_column_spacing(GTK_GRID(hbox), 4);
118 gtk_container_add(GTK_CONTAINER(vbox), hbox);
119 }
120
121 label = gtk_label_new("");
122 gtk_widget_set_hexpand(label, TRUE);
123 gtk_widget_set_halign(label, GTK_ALIGN_START);
124 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
125 gtk_widget_set_margin_start(label, 8);
126 gtk_widget_set_margin_end(label, 8);
127 gtk_widget_set_margin_top(label, 4);
128 gtk_widget_set_margin_bottom(label, 4);
129 gtk_label_set_max_width_chars(GTK_LABEL(label), 80);
130 gtk_container_add(GTK_CONTAINER(hbox), label);
131 gtk_widget_set_name(label, "vote label");
132 vib->label = label;
133
134 arrow = gtk_image_new_from_icon_name("media-seek-backward",
135 GTK_ICON_SIZE_SMALL_TOOLBAR);
136 gtk_widget_set_halign(arrow, GTK_ALIGN_CENTER);
137 gtk_widget_set_valign(arrow, GTK_ALIGN_START);
138
139 if (split_bar) {
140 hbox = gtk_grid_new();
141 gtk_grid_set_column_spacing(GTK_GRID(hbox), 4);
142 gtk_container_add(GTK_CONTAINER(vbox), hbox);
143 }
144
145 button = gtk_button_new();
146 gtk_widget_set_margin_end(button, 16);
147 g_signal_connect(button, "clicked",
148 G_CALLBACK(voteinfo_bar_next_callback), NULL);
149 gtk_button_set_image(GTK_BUTTON(button), arrow);
150 gtk_widget_set_size_request(button, -1, BUTTON_HEIGHT);
151 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
152 gtk_widget_set_focus_on_click(button, FALSE);
153 gtk_container_add(GTK_CONTAINER(hbox), button);
154 vib->next_button = button;
155
156 button = gtk_button_new_with_mnemonic(_("_YES"));
157 g_signal_connect(button, "clicked",
159 GINT_TO_POINTER(CVT_YES));
160 gtk_widget_set_focus_on_click(button, FALSE);
161 gtk_container_add(GTK_CONTAINER(hbox), button);
162 gtk_widget_set_name(button, "vote yes button");
163 vib->yes_button = button;
164
165 label = gtk_label_new("0");
166 gtk_widget_set_halign(label, GTK_ALIGN_START);
167 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
168 gtk_container_add(GTK_CONTAINER(hbox), label);
169 vib->yes_count_label = label;
170
171 button = gtk_button_new_with_mnemonic(_("_NO"));
172 g_signal_connect(button, "clicked",
174 GINT_TO_POINTER(CVT_NO));
175 gtk_widget_set_focus_on_click(button, FALSE);
176 gtk_container_add(GTK_CONTAINER(hbox), button);
177 gtk_widget_set_name(button, "vote no button");
178 vib->no_button = button;
179
180 label = gtk_label_new("0");
181 gtk_widget_set_halign(label, GTK_ALIGN_START);
182 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
183 gtk_container_add(GTK_CONTAINER(hbox), label);
184 vib->no_count_label = label;
185
186 button = gtk_button_new_with_mnemonic(_("_ABSTAIN"));
187 g_signal_connect(button, "clicked",
189 GINT_TO_POINTER(CVT_ABSTAIN));
190 gtk_widget_set_focus_on_click(button, FALSE);
191 gtk_container_add(GTK_CONTAINER(hbox), button);
192 gtk_widget_set_name(button, "vote abstain button");
193 vib->abstain_button = button;
194
195 label = gtk_label_new("0");
196 gtk_widget_set_halign(label, GTK_ALIGN_START);
197 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
198 gtk_container_add(GTK_CONTAINER(hbox), label);
200
201 label = gtk_label_new("/0");
202 gtk_widget_set_halign(label, GTK_ALIGN_START);
203 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
204 gtk_container_add(GTK_CONTAINER(hbox), label);
206
207 return vib->box;
208}
209
210/**********************************************************************/
215{
216 int vote_count, index;
217 struct voteinfo_bar *vib = NULL;
218 struct voteinfo *vi = NULL;
219 char buf[1024], status[1024], ordstr[128], color[32];
220 bool running, need_scroll;
221 gchar *escaped_desc, *escaped_user;
222
223 if (get_client_page() == PAGE_START && NULL != pregame_votebar) {
224 vib = g_object_get_data(G_OBJECT(pregame_votebar), "voteinfo_bar");
225 } else if (get_client_page() == PAGE_GAME && NULL != ingame_votebar) {
226 vib = g_object_get_data(G_OBJECT(ingame_votebar), "voteinfo_bar");
227 }
228
229 if (vib == NULL) {
230 return;
231 }
232
234 gtk_widget_hide(vib->box);
235 return;
236 }
237
238 vote_count = voteinfo_queue_size();
239 vi = voteinfo_queue_get_current(&index);
240
241 if (vi != NULL && vi->resolved && vi->passed) {
242 /* TRANS: Describing a vote that passed. */
243 fc_snprintf(status, sizeof(status), _("[passed]"));
244 sz_strlcpy(color, "green");
245 } else if (vi != NULL && vi->resolved && !vi->passed) {
246 /* TRANS: Describing a vote that failed. */
247 fc_snprintf(status, sizeof(status), _("[failed]"));
248 sz_strlcpy(color, "red");
249 } else if (vi != NULL && vi->remove_time > 0) {
250 /* TRANS: Describing a vote that was removed. */
251 fc_snprintf(status, sizeof(status), _("[removed]"));
252 sz_strlcpy(color, "grey");
253 } else {
254 status[0] = '\0';
255 }
256
257 if (vote_count > 1) {
258 fc_snprintf(ordstr, sizeof(ordstr),
259 "<span weight=\"bold\">(%d/%d)</span> ",
260 index + 1, vote_count);
261 } else {
262 ordstr[0] = '\0';
263 }
264
265 if (status[0] != '\0') {
266 fc_snprintf(buf, sizeof(buf),
267 "<span weight=\"bold\" background=\"%s\">%s</span> ",
268 color, status);
269 sz_strlcpy(status, buf);
270 }
271
272 if (vi != NULL) {
273 escaped_desc = g_markup_escape_text(vi->desc, -1);
274 escaped_user = g_markup_escape_text(vi->user, -1);
275 /* TRANS: "Vote" as a process */
276 fc_snprintf(buf, sizeof(buf), _("%sVote %d by %s: %s%s"),
277 ordstr, vi->vote_no, escaped_user, status,
278 escaped_desc);
279 g_free(escaped_desc);
280 g_free(escaped_user);
281 } else {
282 buf[0] = '\0';
283 }
284 gtk_label_set_markup(GTK_LABEL(vib->label), buf);
285
286 if (vi != NULL) {
287 fc_snprintf(buf, sizeof(buf), "%d", vi->yes);
288 gtk_label_set_text(GTK_LABEL(vib->yes_count_label), buf);
289 fc_snprintf(buf, sizeof(buf), "%d", vi->no);
290 gtk_label_set_text(GTK_LABEL(vib->no_count_label), buf);
291 fc_snprintf(buf, sizeof(buf), "%d", vi->abstain);
292 gtk_label_set_text(GTK_LABEL(vib->abstain_count_label), buf);
293 fc_snprintf(buf, sizeof(buf), "/%d", vi->num_voters);
294 gtk_label_set_text(GTK_LABEL(vib->voter_count_label), buf);
295 } else {
296 gtk_label_set_text(GTK_LABEL(vib->yes_count_label), "-");
297 gtk_label_set_text(GTK_LABEL(vib->no_count_label), "-");
298 gtk_label_set_text(GTK_LABEL(vib->abstain_count_label), "-");
299 gtk_label_set_text(GTK_LABEL(vib->voter_count_label), "/-");
300 }
301
302 running = vi != NULL && !vi->resolved && vi->remove_time == 0;
303
304 gtk_widget_set_sensitive(vib->yes_button, running);
305 gtk_widget_set_sensitive(vib->no_button, running);
306 gtk_widget_set_sensitive(vib->abstain_button, running);
307
308 need_scroll = !gtk_widget_get_visible(vib->box)
310
311 gtk_widget_show_all(vib->box);
312
313 if (vote_count <= 1) {
314 gtk_widget_hide(vib->next_button);
315 }
316
317 if (need_scroll) {
318 /* Showing the votebar when it was hidden
319 * previously makes the chatline scroll up. */
321 }
322}
#define _(String)
Definition fcintl.h:67
bool chatline_is_scrolled_to_bottom(void)
Definition chatline.c:959
void chatline_scroll_to_bottom(bool delayed)
Definition chatline.c:1006
void voteinfo_gui_update(void)
static void voteinfo_bar_do_vote_callback(GtkWidget *w, gpointer userdata)
GtkWidget * ingame_votebar
GtkWidget * voteinfo_bar_new(bool split_bar)
static void voteinfo_bar_next_callback(GtkWidget *w, gpointer userdata)
GtkWidget * pregame_votebar
static void voteinfo_bar_destroy(GtkWidget *w, gpointer userdata)
#define fc_calloc(n, esz)
Definition mem.h:38
enum client_pages get_client_page(void)
Definition colors.h:20
Definition voting.h:46
GtkWidget * abstain_button
GtkWidget * next_button
GtkWidget * voter_count_label
GtkWidget * abstain_count_label
GtkWidget * box
GtkWidget * label
GtkWidget * yes_button
GtkWidget * no_button
GtkWidget * yes_count_label
GtkWidget * no_count_label
int yes
Definition voteinfo.h:36
int num_voters
Definition voteinfo.h:39
bool passed
Definition voteinfo.h:41
char desc[512]
Definition voteinfo.h:33
int abstain
Definition voteinfo.h:38
bool resolved
Definition voteinfo.h:40
int vote_no
Definition voteinfo.h:31
int no
Definition voteinfo.h:37
time_t remove_time
Definition voteinfo.h:45
char user[MAX_LEN_NAME]
Definition voteinfo.h:32
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
#define sz_strlcpy(dest, src)
Definition support.h:167
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
void voteinfo_do_vote(int vote_no, enum client_vote_type vote)
Definition voteinfo.c:234
bool voteinfo_bar_can_be_shown(void)
Definition voteinfo.c:299
struct voteinfo * voteinfo_queue_get_current(int *pindex)
Definition voteinfo.c:201
void voteinfo_queue_next(void)
Definition voteinfo.c:272
int voteinfo_queue_size(void)
Definition voteinfo.c:291
client_vote_type
Definition voteinfo.h:22
@ CVT_YES
Definition voteinfo.h:24
@ CVT_NO
Definition voteinfo.h:25
@ CVT_ABSTAIN
Definition voteinfo.h:26