2 * Copyright (c) 2012 Petr Koupy
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #include <font/embedded.h>
46 static pixel_t color_highlight
= PIXEL(255, 255, 255, 255);
47 static pixel_t color_shadow
= PIXEL(255, 85, 85, 85);
49 static void paint_internal(widget_t
*widget
)
51 button_t
*btn
= (button_t
*) widget
;
53 surface_t
*surface
= window_claim(btn
->widget
.window
);
55 window_yield(btn
->widget
.window
);
61 drawctx_init(&drawctx
, surface
);
63 drawctx_set_source(&drawctx
, &btn
->background
);
64 drawctx_transfer(&drawctx
, widget
->hpos
, widget
->vpos
,
65 widget
->width
, widget
->height
);
67 if ((widget
->width
>= 8) && (widget
->height
>= 8)) {
68 drawctx_set_source(&drawctx
, &source
);
69 draw_bevel(&drawctx
, &source
, widget
->hpos
+ 3, widget
->vpos
+ 3,
70 widget
->width
- 6, widget
->height
- 6, color_highlight
,
73 drawctx_set_source(&drawctx
, &btn
->foreground
);
74 drawctx_transfer(&drawctx
, widget
->hpos
+ 4, widget
->vpos
+ 4,
75 widget
->width
- 8, widget
->height
- 8);
80 font_get_box(btn
->font
, btn
->caption
, &cpt_width
, &cpt_height
);
82 if ((widget
->width
>= cpt_width
) && (widget
->height
>= cpt_height
)) {
83 sysarg_t x
= ((widget
->width
- cpt_width
) / 2) + widget
->hpos
;
84 sysarg_t y
= ((widget
->height
- cpt_height
) / 2) + widget
->vpos
;
86 drawctx_set_source(&drawctx
, &btn
->text
);
87 drawctx_set_font(&drawctx
, btn
->font
);
90 drawctx_print(&drawctx
, btn
->caption
, x
, y
);
93 window_yield(btn
->widget
.window
);
96 void deinit_button(button_t
*btn
)
98 widget_deinit(&btn
->widget
);
100 font_release(btn
->font
);
103 static void button_destroy(widget_t
*widget
)
105 button_t
*btn
= (button_t
*) widget
;
111 static void button_reconfigure(widget_t
*widget
)
116 static void button_rearrange(widget_t
*widget
, sysarg_t hpos
, sysarg_t vpos
,
117 sysarg_t width
, sysarg_t height
)
119 widget_modify(widget
, hpos
, vpos
, width
, height
);
120 paint_internal(widget
);
123 static void button_repaint(widget_t
*widget
)
125 paint_internal(widget
);
126 window_damage(widget
->window
);
129 static void button_handle_keyboard_event(widget_t
*widget
, kbd_event_t event
)
131 button_t
*btn
= (button_t
*) widget
;
133 if (event
.key
== KC_ENTER
&& event
.type
== KEY_PRESS
)
134 sig_send(&btn
->clicked
, NULL
);
137 static void button_handle_position_event(widget_t
*widget
, pos_event_t event
)
139 button_t
*btn
= (button_t
*) widget
;
140 widget
->window
->focus
= widget
;
142 // TODO make the click logic more robust (mouse grabbing, mouse moves)
143 if (event
.btn_num
== 1) {
144 if (event
.type
== POS_RELEASE
)
145 sig_send(&btn
->clicked
, NULL
);
149 bool init_button(button_t
*btn
, widget_t
*parent
, const void *data
,
150 const char *caption
, uint16_t points
, pixel_t background
,
151 pixel_t foreground
, pixel_t text
)
153 widget_init(&btn
->widget
, parent
, data
);
155 btn
->widget
.destroy
= button_destroy
;
156 btn
->widget
.reconfigure
= button_reconfigure
;
157 btn
->widget
.rearrange
= button_rearrange
;
158 btn
->widget
.repaint
= button_repaint
;
159 btn
->widget
.handle_keyboard_event
= button_handle_keyboard_event
;
160 btn
->widget
.handle_position_event
= button_handle_position_event
;
162 source_init(&btn
->background
);
163 source_set_color(&btn
->background
, background
);
165 source_init(&btn
->foreground
);
166 source_set_color(&btn
->foreground
, foreground
);
168 source_init(&btn
->text
);
169 source_set_color(&btn
->text
, text
);
174 btn
->caption
= str_dup(caption
);
176 errno_t rc
= embedded_font_create(&btn
->font
, points
);
185 font_get_box(btn
->font
, btn
->caption
, &cpt_width
, &cpt_height
);
186 btn
->widget
.width_min
= cpt_width
+ 10;
187 btn
->widget
.height_min
= cpt_height
+ 10;
188 btn
->widget
.width_ideal
= cpt_width
+ 30;
189 btn
->widget
.height_ideal
= cpt_height
+ 10;
194 button_t
*create_button(widget_t
*parent
, const void *data
, const char *caption
,
195 uint16_t points
, pixel_t background
, pixel_t foreground
, pixel_t text
)
197 button_t
*btn
= (button_t
*) malloc(sizeof(button_t
));
201 if (init_button(btn
, parent
, data
, caption
, points
, background
, foreground
,