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