1 /*
2  *                           0BSD
3  *
4  *                    BSD Zero Clause License
5  *
6  *  Copyright (c) 2019 Hermann Meyer
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted.
10 
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  *
19  */
20 
21 
22 #include "xcombobox_private.h"
23 #include "xtooltip.h"
24 
25 
_draw_combobox_button(void * w_,void * user_data)26 void _draw_combobox_button(void *w_, void* user_data) {
27     Widget_t *w = (Widget_t*)w_;
28     if (!w) return;
29     XWindowAttributes attrs;
30     XGetWindowAttributes(w->app->dpy, (Window)w->widget, &attrs);
31     int width = attrs.width-2;
32     int height = attrs.height-4;
33     if (attrs.map_state != IsViewable) return;
34     if (!w->state && (int)w->adj_y->value)
35         w->state = 3;
36 
37     cairo_rectangle(w->crb,2.0, 4.0, width, height);
38 
39     if(w->state==0) {
40         cairo_set_line_width(w->crb, 1.0);
41         _pattern_out(w, NORMAL_, height);
42         cairo_fill_preserve(w->crb);
43         use_frame_color_scheme(w, PRELIGHT_);
44     } else if(w->state==1) {
45         _pattern_out(w, PRELIGHT_, height);
46         cairo_fill_preserve(w->crb);
47         cairo_set_line_width(w->crb, 1.5);
48         use_frame_color_scheme(w, PRELIGHT_);
49     } else if(w->state==2) {
50         _pattern_in(w, SELECTED_, height);
51         cairo_fill_preserve(w->crb);
52         cairo_set_line_width(w->crb, 1.0);
53         use_frame_color_scheme(w, PRELIGHT_);
54     } else if(w->state==3) {
55         _pattern_in(w, ACTIVE_, height);
56         cairo_fill_preserve(w->crb);
57         cairo_set_line_width(w->crb, 1.0);
58         use_frame_color_scheme(w, PRELIGHT_);
59     }
60     cairo_stroke(w->crb);
61 
62     if(w->state==2) {
63         cairo_rectangle(w->crb,4.0, 6.0, width, height);
64         cairo_stroke(w->crb);
65         cairo_rectangle(w->crb,3.0, 4.0, width, height);
66         cairo_stroke(w->crb);
67     } else if (w->state==3) {
68         cairo_rectangle(w->crb,3.0, 4.0, width, height);
69         cairo_stroke(w->crb);
70     }
71 
72     float offset = 0.0;
73     if(w->state==0) {
74         use_fg_color_scheme(w, NORMAL_);
75     } else if(w->state==1) {
76         use_fg_color_scheme(w, PRELIGHT_);
77         offset = 1.0;
78     } else if(w->state==2) {
79         use_fg_color_scheme(w, SELECTED_);
80         offset = 2.0;
81     } else if(w->state==3) {
82         use_fg_color_scheme(w, ACTIVE_);
83         offset = 1.0;
84     }
85     use_text_color_scheme(w, get_color_state(w));
86     int wa = width/1.1;
87     int h = height/2.2;
88     int wa1 = width/1.55;
89     int h1 = height/1.3;
90     int wa2 = width/2.8;
91 
92     cairo_move_to(w->crb, wa+offset, h+offset);
93     cairo_line_to(w->crb, wa1+offset, h1+offset);
94     cairo_line_to(w->crb, wa2+offset, h+offset);
95     cairo_line_to(w->crb, wa+offset, h+offset);
96     cairo_fill(w->crb);
97 
98 }
99 
_draw_combobox(void * w_,void * user_data)100 void _draw_combobox(void *w_, void* user_data) {
101     Widget_t *w = (Widget_t*)w_;
102     if (!w) return;
103     XWindowAttributes attrs;
104     XGetWindowAttributes(w->app->dpy, (Window)w->widget, &attrs);
105     int width = attrs.width-2;
106     int height = attrs.height-2;
107     if (attrs.map_state != IsViewable) return;
108 
109     cairo_rectangle(w->crb,2.0, 2.0, width, height);
110 
111     if(w->state==0) {
112         cairo_set_line_width(w->crb, 1.0);
113         use_shadow_color_scheme(w, NORMAL_);
114         cairo_fill_preserve(w->crb);
115         use_frame_color_scheme(w, NORMAL_);
116     } else if(w->state==1) {
117         use_shadow_color_scheme(w, PRELIGHT_);
118         cairo_fill_preserve(w->crb);
119         cairo_set_line_width(w->crb, 1.5);
120         use_frame_color_scheme(w, NORMAL_);
121     } else if(w->state==2) {
122         use_shadow_color_scheme(w, SELECTED_);
123         cairo_fill_preserve(w->crb);
124         cairo_set_line_width(w->crb, 1.0);
125         use_frame_color_scheme(w, SELECTED_);
126     } else if(w->state==3) {
127         use_shadow_color_scheme(w, ACTIVE_);
128         cairo_fill_preserve(w->crb);
129         cairo_set_line_width(w->crb, 1.0);
130         use_frame_color_scheme(w, ACTIVE_);
131     } else if(w->state==4) {
132         use_shadow_color_scheme(w, INSENSITIVE_);
133         cairo_fill_preserve(w->crb);
134         cairo_set_line_width(w->crb, 1.0);
135         use_frame_color_scheme(w, INSENSITIVE_);
136     }
137     cairo_stroke(w->crb);
138 
139     cairo_rectangle(w->crb,4.0, 4.0, width, height);
140     cairo_stroke(w->crb);
141     cairo_rectangle(w->crb,3.0, 3.0, width, height);
142     cairo_stroke(w->crb);
143 
144     cairo_text_extents_t extents;
145 
146     use_text_color_scheme(w, get_color_state(w));
147     float font_size = w->app->normal_font/w->scale.ascale;
148     cairo_set_font_size (w->crb, font_size);
149     cairo_text_extents(w->crb,w->label , &extents);
150 
151     cairo_move_to (w->crb, (width-extents.width)*0.4, (height+extents.height)*0.55);
152     cairo_show_text(w->crb, w->label);
153     cairo_new_path (w->crb);
154     if (extents.width > (float)width-20) {
155         tooltip_set_text(w,w->label);
156         w->flags |= HAS_TOOLTIP;
157     } else {
158         w->flags &= ~HAS_TOOLTIP;
159     }
160 }
161 
_combobox_button_released(void * w_,void * button_,void * user_data)162 void _combobox_button_released(void *w_, void* button_, void* user_data) {
163     Widget_t *w = (Widget_t*)w_;
164     if (w->flags & HAS_POINTER){
165         XButtonEvent *xbutton = (XButtonEvent*)button_;
166         if (xbutton->button == Button3) {
167             w->state=1;
168             pop_menu_show(w, w->childlist->childs[1], 6, true);
169         }
170     }
171 }
172 
_button_combobox_released(void * w_,void * button_,void * user_data)173 void _button_combobox_released(void *w_, void* button_, void* user_data) {
174     Widget_t *w = (Widget_t*)w_;
175     XButtonEvent *xbutton = (XButtonEvent*)button_;
176     if (w->flags & HAS_POINTER && xbutton->button == Button1) {
177         Widget_t *parent = (Widget_t*)w->parent;
178         w->state=1;
179         pop_menu_show(parent, parent->childlist->childs[1], 6, true);
180     }
181     adj_set_value(w->adj, 0.0);
182 }
183 
_entry_released(void * w_,void * item_,void * user_data)184 void _entry_released(void *w_, void* item_, void* user_data) {
185     Widget_t *w = (Widget_t*)w_;
186     Widget_t * combo = NULL;
187     int i = w->app->childlist->elem-1;
188     for(;i>-1;i--) {
189         Widget_t *wid = w->app->childlist->childs[i];
190         if (wid == w) {
191             combo = w->app->childlist->childs[i-2];
192             adj_set_value(combo->adj, (float)*(int*)item_);
193             break;
194         }
195     }
196 }
197 
_set_entry(void * w_,void * user_data)198 void _set_entry(void *w_, void* user_data) {
199     Widget_t *w = (Widget_t*)w_;
200     int v = (int)adj_get_value(w->adj);
201     Widget_t * menu = w->childlist->childs[1];
202     if (!childlist_has_child(menu->childlist)) return;
203     Widget_t* view_port =  menu->childlist->childs[0];
204     if(v>=0) {
205         w->label = view_port->childlist->childs[v]->label;
206         transparent_draw(w, user_data);
207     }
208 }
209