source: mainline/uspace/lib/gui/button.c@ 2cc1ec0

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

Refactor drawing of fonts into multiple layers.

This will need further work to split glyph resolution
process to separate functions in order to support ligatures,
addition of kerning support, separate text layout functions,
etc.

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[6d5e378]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>
[2cc1ec0]40#include <font/embedded.h>
41#include <errno.h>
[296e124e]42#include "common.h"
[6d5e378]43#include "window.h"
44#include "button.h"
45
[296e124e]46static pixel_t color_highlight = PIXEL(255, 255, 255, 255);
47static pixel_t color_shadow = PIXEL(255, 85, 85, 85);
[6d5e378]48
[296e124e]49static void paint_internal(widget_t *widget)
50{
51 button_t *btn = (button_t *) widget;
52
[6d5e378]53 surface_t *surface = window_claim(btn->widget.window);
[296e124e]54 if (!surface)
[6d5e378]55 window_yield(btn->widget.window);
[296e124e]56
57 source_t source;
58 source_init(&source);
59
[6d5e378]60 drawctx_t drawctx;
61 drawctx_init(&drawctx, surface);
[296e124e]62
63 drawctx_set_source(&drawctx, &btn->background);
64 drawctx_transfer(&drawctx, widget->hpos, widget->vpos,
65 widget->width, widget->height);
66
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);
72
73 drawctx_set_source(&drawctx, &btn->foreground);
74 drawctx_transfer(&drawctx, widget->hpos + 4, widget->vpos + 4,
75 widget->width - 8, widget->height - 8);
[6d5e378]76 }
[296e124e]77
[6d5e378]78 sysarg_t cpt_width;
79 sysarg_t cpt_height;
[2cc1ec0]80 font_get_box(btn->font, btn->caption, &cpt_width, &cpt_height);
[296e124e]81
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;
85
86 drawctx_set_source(&drawctx, &btn->text);
[2cc1ec0]87 drawctx_set_font(&drawctx, btn->font);
[296e124e]88
89 if (btn->caption)
[6d5e378]90 drawctx_print(&drawctx, btn->caption, x, y);
91 }
[296e124e]92
[6d5e378]93 window_yield(btn->widget.window);
94}
95
96void deinit_button(button_t *btn)
97{
98 widget_deinit(&btn->widget);
99 free(btn->caption);
[2cc1ec0]100 font_release(btn->font);
[6d5e378]101}
102
103static void button_destroy(widget_t *widget)
104{
105 button_t *btn = (button_t *) widget;
106
[296e124e]107 deinit_button(btn);
[6d5e378]108 free(btn);
109}
110
111static void button_reconfigure(widget_t *widget)
112{
113 /* no-op */
114}
115
116static void button_rearrange(widget_t *widget, sysarg_t hpos, sysarg_t vpos,
117 sysarg_t width, sysarg_t height)
118{
119 widget_modify(widget, hpos, vpos, width, height);
120 paint_internal(widget);
121}
122
123static void button_repaint(widget_t *widget)
124{
125 paint_internal(widget);
126 window_damage(widget->window);
127}
128
129static void button_handle_keyboard_event(widget_t *widget, kbd_event_t event)
130{
131 button_t *btn = (button_t *) widget;
[296e124e]132
133 if (event.key == KC_ENTER && event.type == KEY_PRESS)
[6d5e378]134 sig_send(&btn->clicked, NULL);
135}
136
137static void button_handle_position_event(widget_t *widget, pos_event_t event)
138{
139 button_t *btn = (button_t *) widget;
140 widget->window->focus = widget;
[296e124e]141
[6d5e378]142 // TODO make the click logic more robust (mouse grabbing, mouse moves)
143 if (event.btn_num == 1) {
[296e124e]144 if (event.type == POS_RELEASE)
[6d5e378]145 sig_send(&btn->clicked, NULL);
146 }
147}
148
[296e124e]149bool init_button(button_t *btn, widget_t *parent, const char *caption,
150 uint16_t points, pixel_t background, pixel_t foreground, pixel_t text)
[6d5e378]151{
152 widget_init(&btn->widget, parent);
[296e124e]153
[6d5e378]154 btn->widget.destroy = button_destroy;
155 btn->widget.reconfigure = button_reconfigure;
156 btn->widget.rearrange = button_rearrange;
157 btn->widget.repaint = button_repaint;
158 btn->widget.handle_keyboard_event = button_handle_keyboard_event;
159 btn->widget.handle_position_event = button_handle_position_event;
[296e124e]160
[6d5e378]161 source_init(&btn->background);
162 source_set_color(&btn->background, background);
[296e124e]163
[6d5e378]164 source_init(&btn->foreground);
165 source_set_color(&btn->foreground, foreground);
[296e124e]166
167 source_init(&btn->text);
168 source_set_color(&btn->text, text);
169
170 if (caption == NULL)
[6d5e378]171 btn->caption = NULL;
[296e124e]172 else
[6d5e378]173 btn->caption = str_dup(caption);
[296e124e]174
[2cc1ec0]175 int rc = embedded_font_create(&btn->font, points);
176 if (rc != EOK) {
177 free(btn->caption);
178 btn->caption = NULL;
179 return false;
180 }
[296e124e]181
[6d5e378]182 sysarg_t cpt_width;
183 sysarg_t cpt_height;
[2cc1ec0]184 font_get_box(btn->font, btn->caption, &cpt_width, &cpt_height);
[296e124e]185 btn->widget.width_min = cpt_width + 10;
186 btn->widget.height_min = cpt_height + 10;
187 btn->widget.width_ideal = cpt_width + 30;
188 btn->widget.height_ideal = cpt_height + 10;
189
[6d5e378]190 return true;
191}
192
[296e124e]193button_t *create_button(widget_t *parent, const char *caption, uint16_t points,
194 pixel_t background, pixel_t foreground, pixel_t text)
[6d5e378]195{
196 button_t *btn = (button_t *) malloc(sizeof(button_t));
[296e124e]197 if (!btn)
[6d5e378]198 return NULL;
[296e124e]199
200 if (init_button(btn, parent, caption, points, background, foreground,
201 text))
[6d5e378]202 return btn;
[296e124e]203
204 free(btn);
205 return NULL;
[6d5e378]206}
207
208/** @}
209 */
Note: See TracBrowser for help on using the repository browser.