comparison libmlk-ui/mlk/ui/button.c @ 433:862b15c3a3ae

ui: cleanup hierarchy
author David Demelier <markand@malikania.fr>
date Sat, 15 Oct 2022 21:19:25 +0200
parents src/libmlk-ui/ui/button.c@8f59201dc76b
children 773a082f0b91
comparison
equal deleted inserted replaced
432:38cf60f5a1c4 433:862b15c3a3ae
1 /*
2 * button.c -- GUI button
3 *
4 * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <string.h>
21
22 #include <mlk/core/event.h>
23 #include <mlk/core/maths.h>
24 #include <mlk/core/painter.h>
25 #include <mlk/core/trace.h>
26
27 #include "align.h"
28 #include "button.h"
29 #include "label.h"
30 #include "theme.h"
31
32 static int
33 is_boxed(const struct button *button, const struct event_click *click)
34 {
35 assert(button);
36 assert(click);
37 assert(click->type == EVENT_CLICKDOWN || click->type == EVENT_CLICKUP);
38
39 return maths_is_boxed(button->x, button->y, button->w, button->h,
40 click->x, click->y);
41 }
42
43 void
44 button_draw_default(const struct theme *t, const struct button *button)
45 {
46 assert(t);
47 assert(button);
48
49 (void)t;
50
51 struct label label = {
52 .text = button->text,
53 };
54 unsigned int lw, lh;
55
56 label_query(&label, &lw, &lh);
57
58 if (lw > button->w)
59 tracef("button width is too small for text: %u < %u", button->w, lw);
60 if (lh > button->h)
61 tracef("button height is too small for text: %u < %u", button->h, lh);
62
63 align(ALIGN_CENTER, &label.x, &label.y, lw, lh,
64 button->x, button->y, button->w, button->h);
65
66 painter_set_color(0x577277ff);
67 painter_draw_rectangle(button->x, button->y, button->w, button->h);
68
69 label_draw(&label);
70 }
71
72 int
73 button_handle(struct button *button, const union event *ev)
74 {
75 assert(button);
76 assert(ev);
77
78 switch (ev->type) {
79 case EVENT_CLICKDOWN:
80 if (is_boxed(button, &ev->click))
81 button->state = BUTTON_STATE_PRESSED;
82 break;
83 case EVENT_CLICKUP:
84 /*
85 * If the button was pressed, indicate that the button is
86 * finally activated. This let the user to move the cursor
87 * outside the button to "forget" the press.
88 */
89 if (!is_boxed(button, &ev->click))
90 button->state = BUTTON_STATE_NONE;
91 else if (button->state == BUTTON_STATE_PRESSED)
92 button->state = BUTTON_STATE_ACTIVATED;
93 break;
94 default:
95 break;
96 }
97
98 return button->state == BUTTON_STATE_ACTIVATED;
99 }
100
101 void
102 button_reset(struct button *button)
103 {
104 assert(button);
105
106 button->state = BUTTON_STATE_NONE;
107 }
108
109 void
110 button_draw(const struct button *button)
111 {
112 assert(button);
113
114 theme_draw_button(button->theme, button);
115 }