Use `errno_t` in all uspace and kernel code.
[helenos.git] / uspace / lib / gui / button.c
blob5d62894b465fe32e4d1ba4a56c56ee368c89febb
1 /*
2 * Copyright (c) 2012 Petr Koupy
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
29 /** @addtogroup gui
30 * @{
32 /**
33 * @file
36 #include <str.h>
37 #include <stdlib.h>
38 #include <drawctx.h>
39 #include <surface.h>
40 #include <font/embedded.h>
41 #include <errno.h>
42 #include "common.h"
43 #include "window.h"
44 #include "button.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);
54 if (!surface)
55 window_yield(btn->widget.window);
57 source_t source;
58 source_init(&source);
60 drawctx_t drawctx;
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,
71 color_shadow);
73 drawctx_set_source(&drawctx, &btn->foreground);
74 drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4,
75 widget->width - 8, widget->height - 8);
78 sysarg_t cpt_width;
79 sysarg_t cpt_height;
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);
89 if (btn->caption)
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);
99 free(btn->caption);
100 font_release(btn->font);
103 static void button_destroy(widget_t *widget)
105 button_t *btn = (button_t *) widget;
107 deinit_button(btn);
108 free(btn);
111 static void button_reconfigure(widget_t *widget)
113 /* no-op */
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);
171 if (caption == NULL)
172 btn->caption = NULL;
173 else
174 btn->caption = str_dup(caption);
176 errno_t rc = embedded_font_create(&btn->font, points);
177 if (rc != EOK) {
178 free(btn->caption);
179 btn->caption = NULL;
180 return false;
183 sysarg_t cpt_width;
184 sysarg_t cpt_height;
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;
191 return true;
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));
198 if (!btn)
199 return NULL;
201 if (init_button(btn, parent, data, caption, points, background, foreground,
202 text))
203 return btn;
205 free(btn);
206 return NULL;
209 /** @}