1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <ui_sb_view.h>
6 
7 #include "ui_sample_sb_view_lib.h"
8 #include "ui_arrow_data.h"
9 
10 #define TOP_MARGIN 0
11 #define BOTTOM_MARGIN 28
12 #define HEIGHT_MARGIN (TOP_MARGIN + BOTTOM_MARGIN)
13 #define WIDTH 13
14 
15 /* --- static functions --- */
16 
get_geometry_hints(ui_sb_view_t * view,unsigned int * width,unsigned int * top_margin,unsigned int * bottom_margin,int * up_button_y,unsigned int * up_button_height,int * down_button_y,unsigned int * down_button_height)17 static void get_geometry_hints(ui_sb_view_t *view, unsigned int *width, unsigned int *top_margin,
18                                unsigned int *bottom_margin, int *up_button_y,
19                                unsigned int *up_button_height, int *down_button_y,
20                                unsigned int *down_button_height) {
21   *width = WIDTH;
22   *top_margin = TOP_MARGIN;
23   *bottom_margin = BOTTOM_MARGIN;
24   *up_button_y = -BOTTOM_MARGIN;
25   *up_button_height = BOTTOM_MARGIN / 2;
26   *down_button_y = -(BOTTOM_MARGIN / 2);
27   *down_button_height = BOTTOM_MARGIN / 2;
28 }
29 
get_default_color(ui_sb_view_t * view,char ** fg_color,char ** bg_color)30 static void get_default_color(ui_sb_view_t *view, char **fg_color, char **bg_color) {
31   *fg_color = "gray";
32   *bg_color = "lightgray";
33 }
34 
realized(ui_sb_view_t * view,Display * display,int screen,Window window,GC gc,unsigned int height)35 static void realized(ui_sb_view_t *view, Display *display, int screen, Window window, GC gc,
36                      unsigned int height) {
37   sample_sb_view_t *sample;
38   XGCValues gc_value;
39   XWindowAttributes attr;
40   XColor black = {
41       0, 0, 0, 0, 0, 0,
42   };
43   XColor white = {
44       0, 0xffff, 0xffff, 0xffff, 0, 0,
45   };
46 
47   sample = (sample_sb_view_t*)view;
48 
49   view->display = display;
50   view->screen = screen;
51   view->window = window;
52   view->gc = gc;
53   view->height = height;
54 
55   gc_value.foreground = BlackPixel(view->display, view->screen);
56   gc_value.background = WhitePixel(view->display, view->screen);
57   gc_value.graphics_exposures = 0;
58 
59   sample->gc = XCreateGC(view->display, view->window,
60                          GCForeground | GCBackground | GCGraphicsExposures, &gc_value);
61 
62   XGetWindowAttributes(view->display, view->window, &attr);
63   XAllocColor(view->display, attr.colormap, &black);
64   XAllocColor(view->display, attr.colormap, &white);
65 
66   sample->arrow_up = ui_get_icon_pixmap(view, sample->gc, arrow_up_src, WIDTH, BOTTOM_MARGIN / 2,
67                                         attr.depth, black.pixel, white.pixel);
68   sample->arrow_down = ui_get_icon_pixmap(view, sample->gc, arrow_down_src, WIDTH,
69                                           BOTTOM_MARGIN / 2, attr.depth, black.pixel, white.pixel);
70   sample->arrow_up_dent =
71       ui_get_icon_pixmap(view, sample->gc, arrow_up_dent_src, WIDTH, BOTTOM_MARGIN / 2, attr.depth,
72                          black.pixel, white.pixel);
73   sample->arrow_down_dent =
74       ui_get_icon_pixmap(view, sample->gc, arrow_down_dent_src, WIDTH, BOTTOM_MARGIN / 2,
75                          attr.depth, black.pixel, white.pixel);
76 }
77 
resized(ui_sb_view_t * view,Window window,unsigned int height)78 static void resized(ui_sb_view_t *view, Window window, unsigned int height) {
79   view->window = window;
80   view->height = height;
81 }
82 
destroy(ui_sb_view_t * view)83 static void destroy(ui_sb_view_t *view) {
84   sample_sb_view_t *sample;
85 
86   sample = (sample_sb_view_t*)view;
87 
88   if (sample) {
89     XFreePixmap(view->display, sample->arrow_up);
90     XFreePixmap(view->display, sample->arrow_up_dent);
91     XFreePixmap(view->display, sample->arrow_down);
92     XFreePixmap(view->display, sample->arrow_down_dent);
93 
94     XFreeGC(view->display, sample->gc);
95 
96     free(sample);
97   }
98 }
99 
draw_arrow_up_icon(ui_sb_view_t * view,int is_dent)100 static void draw_arrow_up_icon(ui_sb_view_t *view, int is_dent) {
101   sample_sb_view_t *sample;
102   Pixmap arrow;
103   int x;
104   int y;
105   char **src;
106 
107   sample = (sample_sb_view_t*)view;
108 
109   if (is_dent) {
110     arrow = sample->arrow_up_dent;
111     src = arrow_up_dent_src;
112   } else {
113     arrow = sample->arrow_up;
114     src = arrow_up_src;
115   }
116 
117   XClearArea(view->display, view->window, 0, view->height - BOTTOM_MARGIN, WIDTH, BOTTOM_MARGIN / 2,
118              0);
119 
120   for (y = 0; y < BOTTOM_MARGIN / 2; y++) {
121     for (x = 0; x < WIDTH; x++) {
122       if (src[y][x] == '-') {
123         XCopyArea(view->display, view->window, arrow, view->gc, x,
124                   y + (view->height - BOTTOM_MARGIN), 1, 1, x, y);
125       }
126     }
127   }
128 
129   XCopyArea(view->display, arrow, view->window, view->gc, 0, 0, WIDTH, BOTTOM_MARGIN / 2, 0,
130             view->height - BOTTOM_MARGIN);
131 }
132 
draw_arrow_down_icon(ui_sb_view_t * view,int is_dent)133 static void draw_arrow_down_icon(ui_sb_view_t *view, int is_dent) {
134   sample_sb_view_t *sample;
135   Pixmap arrow;
136   int x;
137   int y;
138   char **src;
139 
140   sample = (sample_sb_view_t*)view;
141 
142   if (is_dent) {
143     arrow = sample->arrow_down_dent;
144     src = arrow_down_dent_src;
145   } else {
146     arrow = sample->arrow_down;
147     src = arrow_down_src;
148   }
149 
150   XClearArea(view->display, view->window, 0, view->height - BOTTOM_MARGIN / 2, WIDTH,
151              BOTTOM_MARGIN / 2, 0);
152 
153   for (y = 0; y < BOTTOM_MARGIN / 2; y++) {
154     for (x = 0; x < WIDTH; x++) {
155       if (src[y][x] == '-') {
156         XCopyArea(view->display, view->window, arrow, view->gc, x,
157                   y + (view->height - BOTTOM_MARGIN / 2), 1, 1, x, y);
158       }
159     }
160   }
161 
162   XCopyArea(view->display, arrow, view->window, view->gc, 0, 0, WIDTH, BOTTOM_MARGIN / 2, 0,
163             view->height - BOTTOM_MARGIN / 2);
164 }
165 
draw_scrollbar(ui_sb_view_t * view,int bar_top_y,unsigned int bar_height)166 static void draw_scrollbar(ui_sb_view_t *view, int bar_top_y, unsigned int bar_height) {
167   sample_sb_view_t *sample;
168 
169   sample = (sample_sb_view_t*)view;
170 
171   XClearArea(view->display, view->window, 0, TOP_MARGIN, WIDTH, view->height - HEIGHT_MARGIN, 0);
172 
173   /* drawing bar */
174 
175   /* left side shade */
176   XSetForeground(view->display, sample->gc, WhitePixel(view->display, view->screen));
177   XDrawLine(view->display, view->window, sample->gc, 0, bar_top_y, 0, bar_top_y + bar_height - 1);
178 
179   /* up side shade */
180   XDrawLine(view->display, view->window, sample->gc, 0, bar_top_y, WIDTH - 1, bar_top_y);
181 
182   /* right side shade */
183   XSetForeground(view->display, sample->gc, BlackPixel(view->display, view->screen));
184   XDrawLine(view->display, view->window, sample->gc, WIDTH - 1, bar_top_y, WIDTH - 1,
185             bar_top_y + bar_height - 1);
186 
187   /* down side shade */
188   XDrawLine(view->display, view->window, sample->gc, 1, bar_top_y + bar_height - 1, WIDTH,
189             bar_top_y + bar_height - 1);
190 }
191 
draw_up_button(ui_sb_view_t * view,int is_pressed)192 static void draw_up_button(ui_sb_view_t *view, int is_pressed) {
193   draw_arrow_up_icon(view, is_pressed);
194 }
195 
draw_down_button(ui_sb_view_t * view,int is_pressed)196 static void draw_down_button(ui_sb_view_t *view, int is_pressed) {
197   draw_arrow_down_icon(view, is_pressed);
198 }
199 
200 /* --- global functions --- */
201 
ui_sample_transparent_sb_view_new(void)202 ui_sb_view_t *ui_sample_transparent_sb_view_new(void) {
203   sample_sb_view_t *sample;
204 
205   if ((sample = calloc(1, sizeof(sample_sb_view_t))) == NULL) {
206     return NULL;
207   }
208 
209   sample->view.version = 1;
210 
211   sample->view.get_geometry_hints = get_geometry_hints;
212   sample->view.get_default_color = get_default_color;
213   sample->view.realized = realized;
214   sample->view.resized = resized;
215   sample->view.destroy = destroy;
216 
217   sample->view.draw_scrollbar = draw_scrollbar;
218   sample->view.draw_up_button = draw_up_button;
219   sample->view.draw_down_button = draw_down_button;
220 
221   return (ui_sb_view_t*)sample;
222 }
223