1 #include <hikari/group.h>
2
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <hikari/memory.h>
8 #include <hikari/view.h>
9
10 void
hikari_group_init(struct hikari_group * group,const char * name)11 hikari_group_init(struct hikari_group *group, const char *name)
12 {
13 int length = strlen(name) + 1;
14
15 group->name = hikari_malloc(length);
16 strcpy(group->name, name);
17
18 wl_list_init(&group->views);
19 wl_list_init(&group->visible_views);
20
21 wl_list_insert(&hikari_server.groups, &group->server_groups);
22 }
23
24 void
hikari_group_fini(struct hikari_group * group)25 hikari_group_fini(struct hikari_group *group)
26 {
27 hikari_free(group->name);
28 wl_list_remove(&group->server_groups);
29 }
30
31 #define GROUP_VIEW(name, link) \
32 struct hikari_view *hikari_group_##name##_view(struct hikari_group *group) \
33 { \
34 if (!wl_list_empty(&group->visible_views)) { \
35 struct wl_list *link = group->visible_views.link; \
36 struct hikari_view *view = \
37 wl_container_of(link, view, visible_group_views); \
38 return view; \
39 } \
40 \
41 return NULL; \
42 }
43
GROUP_VIEW(first,next)44 GROUP_VIEW(first, next)
45 GROUP_VIEW(last, prev)
46 #undef GROUP_VIEW
47
48 void
49 hikari_group_raise(struct hikari_group *group, struct hikari_view *top)
50 {
51 assert(group != NULL);
52 assert(top != NULL);
53
54 struct hikari_view *view, *view_temp, *first = NULL;
55 wl_list_for_each_reverse_safe (
56 view, view_temp, &group->visible_views, visible_group_views) {
57 assert(!hikari_view_is_hidden(view));
58
59 if (view == first) {
60 break;
61 } else if (first == NULL) {
62 first = view;
63 }
64
65 if (view != top) {
66 hikari_view_raise(view);
67 }
68 }
69
70 hikari_view_raise(top);
71 }
72
73 void
hikari_group_lower(struct hikari_group * group,struct hikari_view * top)74 hikari_group_lower(struct hikari_group *group, struct hikari_view *top)
75 {
76 hikari_view_lower(top);
77
78 struct hikari_view *view, *view_temp, *first = NULL;
79 wl_list_for_each_safe (
80 view, view_temp, &group->visible_views, visible_group_views) {
81 assert(!hikari_view_is_hidden(view));
82
83 if (view == first) {
84 break;
85 } else if (first == NULL) {
86 first = view;
87 }
88
89 if (view != top) {
90 hikari_view_lower(view);
91 }
92 }
93 }
94
95 void
hikari_group_damage(struct hikari_group * group)96 hikari_group_damage(struct hikari_group *group)
97 {
98 struct hikari_view *view;
99 wl_list_for_each (view, &group->visible_views, visible_group_views) {
100 hikari_view_damage_border(view);
101 }
102 }
103
104 void
hikari_group_show(struct hikari_group * group)105 hikari_group_show(struct hikari_group *group)
106 {
107 struct hikari_view *view, *view_temp, *top = NULL;
108 wl_list_for_each_reverse_safe (view, view_temp, &group->views, group_views) {
109 if (top == view) {
110 break;
111 }
112
113 if (top == NULL) {
114 top = view;
115 }
116
117 hikari_view_show(view);
118 }
119 }
120
121 void
hikari_group_hide(struct hikari_group * group)122 hikari_group_hide(struct hikari_group *group)
123 {
124 struct hikari_view *view, *view_temp;
125 wl_list_for_each_safe (
126 view, view_temp, &group->visible_views, visible_group_views) {
127 hikari_view_hide(view);
128 }
129 }
130