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   XGetWindowAttributes(view->display, view->window, &attr);
56   XAllocColor(view->display, attr.colormap, &black);
57   XAllocColor(view->display, attr.colormap, &white);
58 
59   sample->black_pixel = gc_value.foreground = black.pixel;
60   sample->white_pixel = gc_value.background = white.pixel;
61   gc_value.graphics_exposures = 0;
62 
63   sample->gc = XCreateGC(view->display, view->window,
64                          GCForeground | GCBackground | GCGraphicsExposures, &gc_value);
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 
color_changed(ui_sb_view_t * view,int is_fg)83 static void color_changed(ui_sb_view_t *view, int is_fg /* 1=fg , 0=bg */
84                           ) {
85   if (is_fg) {
86     sample_sb_view_t *sample;
87 
88     sample = (sample_sb_view_t*)view;
89 
90     ui_draw_icon_pixmap_fg(view, sample->arrow_up, arrow_up_src, WIDTH, BOTTOM_MARGIN / 2);
91     ui_draw_icon_pixmap_fg(view, sample->arrow_down, arrow_down_src, WIDTH, BOTTOM_MARGIN / 2);
92     ui_draw_icon_pixmap_fg(view, sample->arrow_up_dent, arrow_up_dent_src, WIDTH,
93                            BOTTOM_MARGIN / 2);
94     ui_draw_icon_pixmap_fg(view, sample->arrow_down_dent, arrow_down_dent_src, WIDTH,
95                            BOTTOM_MARGIN / 2);
96   }
97 }
98 
destroy(ui_sb_view_t * view)99 static void destroy(ui_sb_view_t *view) {
100   sample_sb_view_t *sample;
101 
102   sample = (sample_sb_view_t*)view;
103 
104   if (sample) {
105     XFreePixmap(view->display, sample->arrow_up);
106     XFreePixmap(view->display, sample->arrow_up_dent);
107     XFreePixmap(view->display, sample->arrow_down);
108     XFreePixmap(view->display, sample->arrow_down_dent);
109 
110     XFreeGC(view->display, sample->gc);
111 
112     free(sample);
113   }
114 }
115 
draw_arrow_up_icon(ui_sb_view_t * view,int is_dent)116 static void draw_arrow_up_icon(ui_sb_view_t *view, int is_dent) {
117   sample_sb_view_t *sample;
118   Pixmap arrow;
119 
120   sample = (sample_sb_view_t*)view;
121 
122   if (is_dent) {
123     arrow = sample->arrow_up_dent;
124   } else {
125     arrow = sample->arrow_up;
126   }
127 
128   XCopyArea(view->display, arrow, view->window, view->gc, 0, 0, WIDTH, BOTTOM_MARGIN / 2, 0,
129             view->height - BOTTOM_MARGIN);
130 }
131 
draw_arrow_down_icon(ui_sb_view_t * view,int is_dent)132 static void draw_arrow_down_icon(ui_sb_view_t *view, int is_dent) {
133   sample_sb_view_t *sample;
134   Pixmap arrow;
135 
136   sample = (sample_sb_view_t*)view;
137 
138   if (is_dent) {
139     arrow = sample->arrow_down_dent;
140   } else {
141     arrow = sample->arrow_down;
142   }
143 
144   XCopyArea(view->display, arrow, view->window, view->gc, 0, 0, WIDTH, BOTTOM_MARGIN / 2, 0,
145             view->height - BOTTOM_MARGIN / 2);
146 }
147 
draw_scrollbar(ui_sb_view_t * view,int bar_top_y,unsigned int bar_height)148 static void draw_scrollbar(ui_sb_view_t *view, int bar_top_y, unsigned int bar_height) {
149   sample_sb_view_t *sample;
150 
151   sample = (sample_sb_view_t*)view;
152 
153   /* drawing bar */
154   XFillRectangle(view->display, view->window, view->gc, 1, bar_top_y, WIDTH - 1, bar_height);
155 
156   /* left side shade */
157   XSetForeground(view->display, sample->gc, sample->white_pixel);
158   XDrawLine(view->display, view->window, sample->gc, 0, bar_top_y, 0, bar_top_y + bar_height - 1);
159 
160   /* up side shade */
161   XDrawLine(view->display, view->window, sample->gc, 0, bar_top_y, WIDTH - 1, bar_top_y);
162 
163   /* right side shade */
164   XSetForeground(view->display, sample->gc, sample->black_pixel);
165   XDrawLine(view->display, view->window, sample->gc, WIDTH - 1, bar_top_y, WIDTH - 1,
166             bar_top_y + bar_height - 1);
167 
168   /* down side shade */
169   XDrawLine(view->display, view->window, sample->gc, 1, bar_top_y + bar_height - 1, WIDTH,
170             bar_top_y + bar_height - 1);
171 }
172 
draw_background(ui_sb_view_t * view,int y,unsigned int height)173 static void draw_background(ui_sb_view_t *view, int y, unsigned int height) {
174   XClearArea(view->display, view->window, 0, y, WIDTH, height, 0);
175 }
176 
draw_up_button(ui_sb_view_t * view,int is_pressed)177 static void draw_up_button(ui_sb_view_t *view, int is_pressed) {
178   draw_arrow_up_icon(view, is_pressed);
179 }
180 
draw_down_button(ui_sb_view_t * view,int is_pressed)181 static void draw_down_button(ui_sb_view_t *view, int is_pressed) {
182   draw_arrow_down_icon(view, is_pressed);
183 }
184 
185 /* --- global functions --- */
186 
ui_sample_sb_view_new(void)187 ui_sb_view_t *ui_sample_sb_view_new(void) {
188   sample_sb_view_t *sample;
189 
190   if ((sample = calloc(1, sizeof(sample_sb_view_t))) == NULL) {
191     return NULL;
192   }
193 
194   sample->view.version = 1;
195 
196   sample->view.get_geometry_hints = get_geometry_hints;
197   sample->view.get_default_color = get_default_color;
198   sample->view.realized = realized;
199   sample->view.resized = resized;
200   sample->view.color_changed = color_changed;
201   sample->view.destroy = destroy;
202 
203   sample->view.draw_scrollbar = draw_scrollbar;
204   sample->view.draw_background = draw_background;
205   sample->view.draw_up_button = draw_up_button;
206   sample->view.draw_down_button = draw_down_button;
207 
208   return (ui_sb_view_t*)sample;
209 }
210