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-4.0 */
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, *vgrid, *hgrid;
95 struct voteinfo_bar *vib;
96 const int BUTTON_HEIGHT = 12;
97 int grid_row = 0;
98 int grid_col = 0;
99
100 vib = fc_calloc(1, sizeof(struct voteinfo_bar));
101
102 if (!split_bar) {
103 hgrid = gtk_grid_new();
104 gtk_grid_set_column_spacing(GTK_GRID(hgrid), 4);
105 g_object_set_data(G_OBJECT(hgrid), "voteinfo_bar", vib);
106 g_signal_connect(hgrid, "destroy", G_CALLBACK(voteinfo_bar_destroy), vib);
107 vib->box = hgrid;
108 vgrid = NULL; /* The compiler may require it. */
109 } else {
110 vgrid = gtk_grid_new();
111 gtk_grid_set_row_homogeneous(GTK_GRID(vgrid), TRUE);
112 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
113 GTK_ORIENTATION_VERTICAL);
114 gtk_grid_set_row_spacing(GTK_GRID(vgrid), 4);
115 g_object_set_data(G_OBJECT(vgrid), "voteinfo_bar", vib);
116 g_signal_connect(vgrid, "destroy", G_CALLBACK(voteinfo_bar_destroy), vib);
117 vib->box = vgrid;
118 hgrid = gtk_grid_new();
119 gtk_grid_set_column_spacing(GTK_GRID(hgrid), 4);
120 gtk_grid_attach(GTK_GRID(vgrid), hgrid, 0, grid_row++, 1, 1);
121 }
122
123 label = gtk_label_new("");
124 gtk_widget_set_hexpand(label, TRUE);
125 gtk_widget_set_halign(label, GTK_ALIGN_START);
126 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
127 gtk_widget_set_margin_start(label, 8);
128 gtk_widget_set_margin_end(label, 8);
129 gtk_widget_set_margin_top(label, 4);
130 gtk_widget_set_margin_bottom(label, 4);
131 gtk_label_set_max_width_chars(GTK_LABEL(label), 80);
132 gtk_grid_attach(GTK_GRID(hgrid), label, grid_col++, 0, 1, 1);
133 gtk_widget_set_name(label, "vote label");
134 vib->label = label;
135
136 if (split_bar) {
137 hgrid = gtk_grid_new();
138 grid_col = 0;
139 gtk_grid_set_column_spacing(GTK_GRID(hgrid), 4);
140 gtk_grid_attach(GTK_GRID(vgrid), hgrid, 0, grid_row++, 1, 1);
141 }
142
143 button = gtk_button_new();
144 gtk_widget_set_margin_end(button, 16);
145 g_signal_connect(button, "clicked",
146 G_CALLBACK(voteinfo_bar_next_callback), NULL);
147 gtk_button_set_icon_name(GTK_BUTTON(button), "media-seek-backward");
148 gtk_widget_set_size_request(button, -1, BUTTON_HEIGHT);
149 gtk_button_set_has_frame(GTK_BUTTON(button), FALSE);
150 gtk_widget_set_focus_on_click(button, FALSE);
151 gtk_grid_attach(GTK_GRID(hgrid), button, grid_col++, 0, 1, 1);
152 vib->next_button = button;
153
154 button = gtk_button_new_with_mnemonic(_("_YES"));
155 g_signal_connect(button, "clicked",
157 GINT_TO_POINTER(CVT_YES));
158 gtk_widget_set_focus_on_click(button, FALSE);
159 gtk_grid_attach(GTK_GRID(hgrid), button, grid_col++, 0, 1, 1);
160 gtk_widget_set_name(button, "vote yes button");
161 vib->yes_button = button;
162
163 label = gtk_label_new("0");
164 gtk_widget_set_halign(label, GTK_ALIGN_START);
165 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
166 gtk_grid_attach(GTK_GRID(hgrid), label, grid_col++, 0, 1, 1);
167 vib->yes_count_label = label;
168
169 button = gtk_button_new_with_mnemonic(_("_NO"));
170 g_signal_connect(button, "clicked",
172 GINT_TO_POINTER(CVT_NO));
173 gtk_widget_set_focus_on_click(button, FALSE);
174 gtk_grid_attach(GTK_GRID(hgrid), button, grid_col++, 0, 1, 1);
175 gtk_widget_set_name(button, "vote no button");
176 vib->no_button = button;
177
178 label = gtk_label_new("0");
179 gtk_widget_set_halign(label, GTK_ALIGN_START);
180 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
181 gtk_grid_attach(GTK_GRID(hgrid), label, grid_col++, 0, 1, 1);
182 vib->no_count_label = label;
183
184 button = gtk_button_new_with_mnemonic(_("_ABSTAIN"));
185 g_signal_connect(button, "clicked",
187 GINT_TO_POINTER(CVT_ABSTAIN));
188 gtk_widget_set_focus_on_click(button, FALSE);
189 gtk_grid_attach(GTK_GRID(hgrid), button, grid_col++, 0, 1, 1);
190 gtk_widget_set_name(button, "vote abstain button");
191 vib->abstain_button = button;
192
193 label = gtk_label_new("0");
194 gtk_widget_set_halign(label, GTK_ALIGN_START);
195 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
196 gtk_grid_attach(GTK_GRID(hgrid), label, grid_col++, 0, 1, 1);
198
199 label = gtk_label_new("/0");
200 gtk_widget_set_halign(label, GTK_ALIGN_START);
201 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
202 gtk_grid_attach(GTK_GRID(hgrid), label, grid_col++, 0, 1, 1);
204
205 return vib->box;
206}
207
208/**********************************************************************/
213{
214 int vote_count, index;
215 struct voteinfo_bar *vib = NULL;
216 struct voteinfo *vi = NULL;
217 char buf[1024], status[1024], ordstr[128], color[32];
218 bool running, need_scroll;
219 gchar *escaped_desc, *escaped_user;
220
221 if (get_client_page() == PAGE_START && NULL != pregame_votebar) {
222 vib = g_object_get_data(G_OBJECT(pregame_votebar), "voteinfo_bar");
223 } else if (get_client_page() == PAGE_GAME && NULL != ingame_votebar) {
224 vib = g_object_get_data(G_OBJECT(ingame_votebar), "voteinfo_bar");
225 }
226
227 if (vib == NULL) {
228 return;
229 }
230
232 gtk_widget_hide(vib->box);
233 return;
234 }
235
236 vote_count = voteinfo_queue_size();
237 vi = voteinfo_queue_get_current(&index);
238
239 if (vi != NULL && vi->resolved && vi->passed) {
240 /* TRANS: Describing a vote that passed. */
241 fc_snprintf(status, sizeof(status), _("[passed]"));
242 sz_strlcpy(color, "green");
243 } else if (vi != NULL && vi->resolved && !vi->passed) {
244 /* TRANS: Describing a vote that failed. */
245 fc_snprintf(status, sizeof(status), _("[failed]"));
246 sz_strlcpy(color, "red");
247 } else if (vi != NULL && vi->remove_time > 0) {
248 /* TRANS: Describing a vote that was removed. */
249 fc_snprintf(status, sizeof(status), _("[removed]"));
250 sz_strlcpy(color, "grey");
251 } else {
252 status[0] = '\0';
253 }
254
255 if (vote_count > 1) {
256 fc_snprintf(ordstr, sizeof(ordstr),
257 "<span weight=\"bold\">(%d/%d)</span> ",
258 index + 1, vote_count);
259 } else {
260 ordstr[0] = '\0';
261 }
262
263 if (status[0] != '\0') {
264 fc_snprintf(buf, sizeof(buf),
265 "<span weight=\"bold\" background=\"%s\">%s</span> ",
266 color, status);
267 sz_strlcpy(status, buf);
268 }
269
270 if (vi != NULL) {
271 escaped_desc = g_markup_escape_text(vi->desc, -1);
272 escaped_user = g_markup_escape_text(vi->user, -1);
273 /* TRANS: "Vote" as a process */
274 fc_snprintf(buf, sizeof(buf), _("%sVote %d by %s: %s%s"),
275 ordstr, vi->vote_no, escaped_user, status,
276 escaped_desc);
277 g_free(escaped_desc);
278 g_free(escaped_user);
279 } else {
280 buf[0] = '\0';
281 }
282 gtk_label_set_markup(GTK_LABEL(vib->label), buf);
283
284 if (vi != NULL) {
285 fc_snprintf(buf, sizeof(buf), "%d", vi->yes);
286 gtk_label_set_text(GTK_LABEL(vib->yes_count_label), buf);
287 fc_snprintf(buf, sizeof(buf), "%d", vi->no);
288 gtk_label_set_text(GTK_LABEL(vib->no_count_label), buf);
289 fc_snprintf(buf, sizeof(buf), "%d", vi->abstain);
290 gtk_label_set_text(GTK_LABEL(vib->abstain_count_label), buf);
291 fc_snprintf(buf, sizeof(buf), "/%d", vi->num_voters);
292 gtk_label_set_text(GTK_LABEL(vib->voter_count_label), buf);
293 } else {
294 gtk_label_set_text(GTK_LABEL(vib->yes_count_label), "-");
295 gtk_label_set_text(GTK_LABEL(vib->no_count_label), "-");
296 gtk_label_set_text(GTK_LABEL(vib->abstain_count_label), "-");
297 gtk_label_set_text(GTK_LABEL(vib->voter_count_label), "/-");
298 }
299
300 running = vi != NULL && !vi->resolved && vi->remove_time == 0;
301
302 gtk_widget_set_sensitive(vib->yes_button, running);
303 gtk_widget_set_sensitive(vib->no_button, running);
304 gtk_widget_set_sensitive(vib->abstain_button, running);
305
306 need_scroll = !gtk_widget_get_visible(vib->box)
308
309 gtk_widget_show(vib->box);
310
311 if (vote_count <= 1) {
312 gtk_widget_hide(vib->next_button);
313 }
314
315 if (need_scroll) {
316 /* Showing the votebar when it was hidden
317 * previously makes the chatline scroll up. */
319 }
320}
#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