source: mainline/uspace/lib/gui/button.c@ 296e124e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 296e124e was 296e124e, checked in by Martin Decky <martin@…>, 11 years ago

improve visual appearance of GUI windows and buttons

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/*
2 * Copyright (c) 2012 Petr Koupy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29/** @addtogroup gui
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <str.h>
37#include <malloc.h>
38#include <drawctx.h>
39#include <surface.h>
40#include "common.h"
41#include "window.h"
42#include "button.h"
43
44static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
45static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
46
47static void paint_internal(widget_t *widget)
48{
49 button_t *btn = (button_t *) widget;
50
51 surface_t *surface = window_claim(btn->widget.window);
52 if (!surface)
53 window_yield(btn->widget.window);
54
55 source_t source;
56 source_init(&source);
57
58 drawctx_t drawctx;
59 drawctx_init(&drawctx, surface);
60
61 drawctx_set_source(&drawctx, &btn->background);
62 drawctx_transfer(&drawctx, widget->hpos, widget->vpos,
63 widget->width, widget->height);
64
65 if ((widget->width >= 8) && (widget->height >= 8)) {
66 drawctx_set_source(&drawctx, &source);
67 draw_bevel(&drawctx, &source, widget->hpos + 3, widget->vpos + 3,
68 widget->width - 6, widget->height - 6, color_highlight,
69 color_shadow);
70
71 drawctx_set_source(&drawctx, &btn->foreground);
72 drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4,
73 widget->width - 8, widget->height - 8);
74 }
75
76 sysarg_t cpt_width;
77 sysarg_t cpt_height;
78 font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
79
80 if ((widget->width >= cpt_width) && (widget->height >= cpt_height)) {
81 sysarg_t x = ((widget->width - cpt_width) / 2) + widget->hpos;
82 sysarg_t y = ((widget->height - cpt_height) / 2) + widget->vpos;
83
84 drawctx_set_source(&drawctx, &btn->text);
85 drawctx_set_font(&drawctx, &btn->font);
86
87 if (btn->caption)
88 drawctx_print(&drawctx, btn->caption, x, y);
89 }
90
91 window_yield(btn->widget.window);
92}
93
94void deinit_button(button_t *btn)
95{
96 widget_deinit(&btn->widget);
97 free(btn->caption);
98 font_release(&btn->font);
99}
100
101static void button_destroy(widget_t *widget)
102{
103 button_t *btn = (button_t *) widget;
104
105 deinit_button(btn);
106 free(btn);
107}
108
109static void button_reconfigure(widget_t *widget)
110{
111 /* no-op */
112}
113
114static void button_rearrange(widget_t *widget, sysarg_t hpos, sysarg_t vpos,
115 sysarg_t width, sysarg_t height)
116{
117 widget_modify(widget, hpos, vpos, width, height);
118 paint_internal(widget);
119}
120
121static void button_repaint(widget_t *widget)
122{
123 paint_internal(widget);
124 window_damage(widget->window);
125}
126
127static void button_handle_keyboard_event(widget_t *widget, kbd_event_t event)
128{
129 button_t *btn = (button_t *) widget;
130
131 if (event.key == KC_ENTER && event.type == KEY_PRESS)
132 sig_send(&btn->clicked, NULL);
133}
134
135static void button_handle_position_event(widget_t *widget, pos_event_t event)
136{
137 button_t *btn = (button_t *) widget;
138 widget->window->focus = widget;
139
140 // TODO make the click logic more robust (mouse grabbing, mouse moves)
141 if (event.btn_num == 1) {
142 if (event.type == POS_RELEASE)
143 sig_send(&btn->clicked, NULL);
144 }
145}
146
147bool init_button(button_t *btn, widget_t *parent, const char *caption,
148 uint16_t points, pixel_t background, pixel_t foreground, pixel_t text)
149{
150 widget_init(&btn->widget, parent);
151
152 btn->widget.destroy = button_destroy;
153 btn->widget.reconfigure = button_reconfigure;
154 btn->widget.rearrange = button_rearrange;
155 btn->widget.repaint = button_repaint;
156 btn->widget.handle_keyboard_event = button_handle_keyboard_event;
157 btn->widget.handle_position_event = button_handle_position_event;
158
159 source_init(&btn->background);
160 source_set_color(&btn->background, background);
161
162 source_init(&btn->foreground);
163 source_set_color(&btn->foreground, foreground);
164
165 source_init(&btn->text);
166 source_set_color(&btn->text, text);
167
168 if (caption == NULL)
169 btn->caption = NULL;
170 else
171 btn->caption = str_dup(caption);
172
173 font_init(&btn->font, FONT_DECODER_EMBEDDED, NULL, points);
174
175 sysarg_t cpt_width;
176 sysarg_t cpt_height;
177 font_get_box(&btn->font, btn->caption, &cpt_width, &cpt_height);
178 btn->widget.width_min = cpt_width + 10;
179 btn->widget.height_min = cpt_height + 10;
180 btn->widget.width_ideal = cpt_width + 30;
181 btn->widget.height_ideal = cpt_height + 10;
182
183 return true;
184}
185
186button_t *create_button(widget_t *parent, const char *caption, uint16_t points,
187 pixel_t background, pixel_t foreground, pixel_t text)
188{
189 button_t *btn = (button_t *) malloc(sizeof(button_t));
190 if (!btn)
191 return NULL;
192
193 if (init_button(btn, parent, caption, points, background, foreground,
194 text))
195 return btn;
196
197 free(btn);
198 return NULL;
199}
200
201/** @}
202 */
Note: See TracBrowser for help on using the repository browser.