Skip to content

Commit 0a5c551

Browse files
committed
Refactor the code into components
- Define UrnComponent interface and title component - Implement the timer and splits as components - Add previous, best sum, PB and WR components - Clean up the code and fix warnings
1 parent 08b5277 commit 0a5c551

13 files changed

+1120
-661
lines changed

GNUmakefile

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
BIN := urn-gtk
2-
OBJS := urn.o urn-gtk.o bind.o
3-
LIBS := gtk+-3.0 x11 jansson
4-
CFLAGS := `pkg-config --cflags $(LIBS)`
5-
LDLIBS := `pkg-config --libs $(LIBS)`
6-
BIN_DIR := /usr/local/bin
7-
APP := urn.desktop
8-
APP_DIR := /usr/share/applications
9-
ICON := urn
10-
ICON_DIR := /usr/share/icons/hicolor
11-
SCHEMAS_DIR := /usr/share/glib-2.0/schemas
1+
BIN = urn-gtk
2+
OBJS = urn.o urn-gtk.o bind.o $(COMPONENTS)
3+
COMPONENTS = $(addprefix components/, \
4+
urn-component.o title.o splits.o timer.o \
5+
prev-segment.o best-sum.o pb.o wr.o)
6+
7+
LIBS = gtk+-3.0 x11 jansson
8+
CFLAGS += `pkg-config --cflags $(LIBS)`
9+
LDLIBS += `pkg-config --libs $(LIBS)`
10+
11+
BIN_DIR = /usr/local/bin
12+
APP = urn.desktop
13+
APP_DIR = /usr/share/applications
14+
ICON = urn
15+
ICON_DIR = /usr/share/icons/hicolor
16+
SCHEMAS_DIR = /usr/share/glib-2.0/schemas
1217

1318
$(BIN): $(OBJS)
1419

components/best-sum.c

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "urn-component.h"
2+
3+
typedef struct _UrnBestSum {
4+
UrnComponent base;
5+
GtkWidget *container;
6+
GtkWidget *sum_of_bests;
7+
} UrnBestSum;
8+
extern UrnComponentOps urn_best_sum_operations;
9+
10+
#define SUM_OF_BEST_SEGMENTS "Sum of best segments"
11+
12+
UrnComponent *urn_component_best_sum_new() {
13+
UrnBestSum *self;
14+
GtkWidget *label;
15+
16+
self = malloc(sizeof(UrnBestSum));
17+
if (!self) return NULL;
18+
self->base.ops = &urn_best_sum_operations;
19+
20+
self->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
21+
add_class(self->container, "footer"); /* hack */
22+
gtk_widget_show(self->container);
23+
24+
label = gtk_label_new(SUM_OF_BEST_SEGMENTS);
25+
add_class(label, "sum-of-bests-label");
26+
gtk_widget_set_halign(label, GTK_ALIGN_START);
27+
gtk_widget_set_hexpand(label, TRUE);
28+
gtk_container_add(GTK_CONTAINER(self->container), label);
29+
gtk_widget_show(label);
30+
31+
self->sum_of_bests = gtk_label_new(NULL);
32+
add_class(self->sum_of_bests, "sum-of-bests");
33+
gtk_widget_set_halign(self->sum_of_bests, GTK_ALIGN_END);
34+
gtk_container_add(GTK_CONTAINER(self->container), self->sum_of_bests);
35+
gtk_widget_show(self->sum_of_bests);
36+
37+
return (UrnComponent *)self;
38+
}
39+
40+
static void best_sum_delete(UrnComponent *self) {
41+
free(self);
42+
}
43+
44+
static GtkWidget *best_sum_widget(UrnComponent *self) {
45+
return ((UrnBestSum *)self)->container;
46+
}
47+
48+
static void best_sum_show_game(UrnComponent *self_,
49+
urn_game *game, urn_timer *timer) {
50+
UrnBestSum *self = (UrnBestSum *)self_;
51+
char str[256];
52+
if (game->split_count && timer->sum_of_bests) {
53+
urn_time_string(str, timer->sum_of_bests);
54+
gtk_label_set_text(GTK_LABEL(self->sum_of_bests), str);
55+
}
56+
}
57+
58+
static void best_sum_clear_game(UrnComponent *self_) {
59+
UrnBestSum *self = (UrnBestSum *)self_;
60+
gtk_label_set_text(GTK_LABEL(self->sum_of_bests), "");
61+
}
62+
63+
static void best_sum_draw(UrnComponent *self_, urn_game *game,
64+
urn_timer *timer) {
65+
UrnBestSum *self = (UrnBestSum *)self_;
66+
char str[256];
67+
remove_class(self->sum_of_bests, "time");
68+
gtk_label_set_text(GTK_LABEL(self->sum_of_bests), "-");
69+
if (timer->sum_of_bests) {
70+
add_class(self->sum_of_bests, "time");
71+
urn_time_string(str, timer->sum_of_bests);
72+
gtk_label_set_text(GTK_LABEL(self->sum_of_bests), str);
73+
}
74+
}
75+
76+
UrnComponentOps urn_best_sum_operations = {
77+
.delete = best_sum_delete,
78+
.widget = best_sum_widget,
79+
.show_game = best_sum_show_game,
80+
.clear_game = best_sum_clear_game,
81+
.draw = best_sum_draw
82+
};

components/pb.c

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include "urn-component.h"
2+
3+
typedef struct _UrnPb {
4+
UrnComponent base;
5+
GtkWidget *container;
6+
GtkWidget *personal_best;
7+
} UrnPb;
8+
extern UrnComponentOps urn_pb_operations;
9+
10+
#define PERSONAL_BEST "Personal best"
11+
12+
UrnComponent *urn_component_pb_new() {
13+
UrnPb *self;
14+
GtkWidget *label;
15+
16+
self = malloc(sizeof(UrnPb));
17+
if (!self) return NULL;
18+
self->base.ops = &urn_pb_operations;
19+
20+
self->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
21+
add_class(self->container, "footer"); /* hack */
22+
gtk_widget_show(self->container);
23+
24+
label = gtk_label_new(PERSONAL_BEST);
25+
add_class(label, "personal-best-label");
26+
gtk_widget_set_halign(label, GTK_ALIGN_START);
27+
gtk_widget_set_hexpand(label, TRUE);
28+
gtk_container_add(GTK_CONTAINER(self->container), label);
29+
gtk_widget_show(label);
30+
31+
self->personal_best = gtk_label_new(NULL);
32+
add_class(self->personal_best, "personal-best");
33+
gtk_widget_set_halign(self->personal_best, GTK_ALIGN_END);
34+
gtk_container_add(GTK_CONTAINER(self->container), self->personal_best);
35+
gtk_widget_show(self->personal_best);
36+
37+
return (UrnComponent *)self;
38+
}
39+
40+
static void pb_delete(UrnComponent *self) {
41+
free(self);
42+
}
43+
44+
static GtkWidget *pb_widget(UrnComponent *self) {
45+
return ((UrnPb *)self)->container;
46+
}
47+
48+
static void pb_show_game(UrnComponent *self_,
49+
urn_game *game, urn_timer *timer) {
50+
UrnPb *self = (UrnPb *)self_;
51+
char str[256];
52+
if (game->split_count && game->split_times[game->split_count - 1]) {
53+
if (game->split_times[game->split_count - 1]) {
54+
urn_time_string(
55+
str, game->split_times[game->split_count - 1]);
56+
gtk_label_set_text(GTK_LABEL(self->personal_best), str);
57+
}
58+
}
59+
60+
}
61+
62+
static void pb_clear_game(UrnComponent *self_) {
63+
UrnPb *self = (UrnPb *)self_;
64+
gtk_label_set_text(GTK_LABEL(self->personal_best), "");
65+
}
66+
67+
static void pb_draw(UrnComponent *self_, urn_game *game,
68+
urn_timer *timer) {
69+
UrnPb *self = (UrnPb *)self_;
70+
char str[256];
71+
remove_class(self->personal_best, "time");
72+
gtk_label_set_text(GTK_LABEL(self->personal_best), "-");
73+
if (timer->curr_split == game->split_count
74+
&& timer->split_times[game->split_count - 1]
75+
&& (!game->split_times[game->split_count - 1]
76+
|| (timer->split_times[game->split_count - 1]
77+
< game->split_times[game->split_count - 1]))) {
78+
add_class(self->personal_best, "time");
79+
urn_time_string(
80+
str, timer->split_times[game->split_count - 1]);
81+
gtk_label_set_text(GTK_LABEL(self->personal_best), str);
82+
} else if (game->split_times[game->split_count - 1]) {
83+
add_class(self->personal_best, "time");
84+
urn_time_string(
85+
str, game->split_times[game->split_count - 1]);
86+
gtk_label_set_text(GTK_LABEL(self->personal_best), str);
87+
}
88+
}
89+
90+
UrnComponentOps urn_pb_operations = {
91+
.delete = pb_delete,
92+
.widget = pb_widget,
93+
.show_game = pb_show_game,
94+
.clear_game = pb_clear_game,
95+
.draw = pb_draw
96+
};

components/prev-segment.c

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#include "urn-component.h"
2+
3+
typedef struct _UrnPrevSegment {
4+
UrnComponent base;
5+
GtkWidget *container;
6+
GtkWidget *previous_segment_label;
7+
GtkWidget *previous_segment;
8+
} UrnPrevSegment;
9+
extern UrnComponentOps urn_prev_segment_operations;
10+
11+
#define PREVIOUS_SEGMENT "Previous segment"
12+
#define LIVE_SEGMENT "Live segment"
13+
14+
UrnComponent *urn_component_prev_segment_new() {
15+
UrnPrevSegment *self;
16+
17+
self = malloc(sizeof(UrnPrevSegment));
18+
if (!self) return NULL;
19+
self->base.ops = &urn_prev_segment_operations;
20+
21+
self->container = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
22+
add_class(self->container, "footer");
23+
gtk_widget_show(self->container);
24+
25+
self->previous_segment_label = gtk_label_new(PREVIOUS_SEGMENT);
26+
add_class(self->previous_segment_label, "prev-segment-label");
27+
gtk_widget_set_halign(self->previous_segment_label,
28+
GTK_ALIGN_START);
29+
gtk_widget_set_hexpand(self->previous_segment_label, TRUE);
30+
gtk_container_add(GTK_CONTAINER(self->container),
31+
self->previous_segment_label);
32+
gtk_widget_show(self->previous_segment_label);
33+
34+
self->previous_segment = gtk_label_new(NULL);
35+
add_class(self->previous_segment, "prev-segment");
36+
gtk_widget_set_halign(self->previous_segment, GTK_ALIGN_END);
37+
gtk_container_add(GTK_CONTAINER(self->container), self->previous_segment);
38+
gtk_widget_show(self->previous_segment);
39+
40+
return (UrnComponent *)self;
41+
}
42+
43+
static void prev_segment_delete(UrnComponent *self) {
44+
free(self);
45+
}
46+
47+
static GtkWidget *prev_segment_widget(UrnComponent *self) {
48+
return ((UrnPrevSegment *)self)->container;
49+
}
50+
51+
static void prev_segment_show_game(UrnComponent *self_,
52+
urn_game *game, urn_timer *timer) {
53+
UrnPrevSegment *self = (UrnPrevSegment *)self_;
54+
remove_class(self->previous_segment, "behind");
55+
remove_class(self->previous_segment, "losing");
56+
remove_class(self->previous_segment, "best-segment");
57+
}
58+
59+
static void prev_segment_clear_game(UrnComponent *self_) {
60+
UrnPrevSegment *self = (UrnPrevSegment *)self_;
61+
gtk_label_set_text(GTK_LABEL(self->previous_segment_label),
62+
PREVIOUS_SEGMENT);
63+
gtk_label_set_text(GTK_LABEL(self->previous_segment), "");
64+
}
65+
66+
static void prev_segment_draw(UrnComponent *self_, urn_game *game,
67+
urn_timer *timer) {
68+
UrnPrevSegment *self = (UrnPrevSegment *)self_;
69+
const char *label;
70+
char str[256];
71+
int prev, curr = timer->curr_split;
72+
if (curr == game->split_count)
73+
--curr;
74+
75+
remove_class(self->previous_segment, "best-segment");
76+
remove_class(self->previous_segment, "behind");
77+
remove_class(self->previous_segment, "losing");
78+
remove_class(self->previous_segment, "delta");
79+
gtk_label_set_text(GTK_LABEL(self->previous_segment), "-");
80+
81+
label = PREVIOUS_SEGMENT;
82+
if (timer->segment_deltas[curr] > 0) {
83+
// Live segment
84+
label = LIVE_SEGMENT;
85+
remove_class(self->previous_segment, "best-segment");
86+
add_class(self->previous_segment, "behind");
87+
add_class(self->previous_segment, "losing");
88+
add_class(self->previous_segment, "delta");
89+
urn_delta_string(str, timer->segment_deltas[curr]);
90+
gtk_label_set_text(GTK_LABEL(self->previous_segment), str);
91+
} else if (curr) {
92+
prev = timer->curr_split - 1;
93+
// Previous segment
94+
if (timer->curr_split) {
95+
prev = timer->curr_split - 1;
96+
if (timer->segment_deltas[prev]) {
97+
if (timer->split_info[prev]
98+
& URN_INFO_BEST_SEGMENT) {
99+
add_class(self->previous_segment, "best-segment");
100+
} else if (timer->segment_deltas[prev] > 0) {
101+
add_class(self->previous_segment, "behind");
102+
add_class(self->previous_segment, "losing");
103+
}
104+
add_class(self->previous_segment, "delta");
105+
urn_delta_string(str, timer->segment_deltas[prev]);
106+
gtk_label_set_text(GTK_LABEL(self->previous_segment), str);
107+
}
108+
}
109+
}
110+
gtk_label_set_text(GTK_LABEL(self->previous_segment_label), label);
111+
}
112+
113+
UrnComponentOps urn_prev_segment_operations = {
114+
.delete = prev_segment_delete,
115+
.widget = prev_segment_widget,
116+
.show_game = prev_segment_show_game,
117+
.clear_game = prev_segment_clear_game,
118+
.draw = prev_segment_draw
119+
};

0 commit comments

Comments
 (0)