Mercurial > molko
view examples/example-ui/example-ui.c @ 493:fce3b3c4b496
ui: label -> mlk_label
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 28 Feb 2023 13:26:53 +0100 |
parents | 734b598534c4 |
children | 2af25db99273 |
line wrap: on
line source
/* * example-action.c -- example on how to use automatic actions * * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <mlk/core/core.h> #include <mlk/core/err.h> #include <mlk/core/event.h> #include <mlk/core/game.h> #include <mlk/core/maths.h> #include <mlk/core/panic.h> #include <mlk/core/painter.h> #include <mlk/core/state.h> #include <mlk/core/sys.h> #include <mlk/core/util.h> #include <mlk/core/window.h> #include <mlk/ui/align.h> #include <mlk/ui/button.h> #include <mlk/ui/checkbox.h> #include <mlk/ui/frame.h> #include <mlk/ui/label.h> #include <mlk/ui/theme.h> #include <mlk/ui/ui.h> #include <mlk/example/example.h> #define FRAME_ORIGIN_X (10) #define FRAME_ORIGIN_Y (10) #define FRAME_WIDTH (400) #define FRAME_HEIGHT (200) #define HEADER_HEIGHT (32) #define ELEMENT_HEIGHT (20) /* * We design a basic UI like this. * * FRAME_WIDTH * +---------------------------------------------+-- * | Title | | HEADER_HEIGHT * +---------------------------------------------+-- * | [x] Auto save | * | | * | | * | [ Quit ] | * +---------------------------------------------+ */ static struct { struct { int active; int x; int y; } motion; struct { struct mlk_frame frame; } panel; struct { struct mlk_label label; } header; struct { struct mlk_checkbox cb; struct mlk_label label; } autosave; struct { struct mlk_button button; } quit; } ui = { .panel = { .frame = { .x = FRAME_ORIGIN_X, .y = FRAME_ORIGIN_Y, .w = FRAME_WIDTH, .h = FRAME_HEIGHT } }, .header = { .label = { .text = "Preferences", .x = FRAME_ORIGIN_X, .y = FRAME_ORIGIN_Y, .flags = MLK_LABEL_FLAGS_SHADOW, } }, .autosave = { .cb = { .w = ELEMENT_HEIGHT, .h = ELEMENT_HEIGHT }, .label = { .text = "Auto save game", .flags = MLK_LABEL_FLAGS_SHADOW, } }, .quit = { .button = { .text = "Quit", .h = ELEMENT_HEIGHT } } }; static struct mlk_state *states[1]; static void init(void) { int err; if ((err = mlk_example_init("example-ui")) < 0) mlk_panicf("mlk_example_init: %s", mlk_err_string(err)); } static void resize_header(void) { struct mlk_frame *f = &ui.panel.frame; struct mlk_label *l = &ui.header.label; unsigned int w, h; /* Header. */ mlk_label_query(l, &w, &h); mlk_align(MLK_ALIGN_LEFT, &l->x, &l->y, w, h, f->x, f->y, f->w, HEADER_HEIGHT); l->x += theme_default()->padding; } static void resize_autosave(void) { unsigned int padding = theme_default()->padding; struct mlk_frame *f = &ui.panel.frame; struct mlk_checkbox *c = &ui.autosave.cb; struct mlk_label *l = &ui.autosave.label; c->x = f->x + padding; c->y = f->y + HEADER_HEIGHT + padding; l->x = c->x + c->w + padding; l->y = c->y; } static void resize_button(void) { unsigned int padding = theme_default()->padding; struct mlk_frame *f = &ui.panel.frame; struct mlk_button *b = &ui.quit.button; /* Button. */ b->w = f->w / 4; mlk_align(MLK_ALIGN_BOTTOM_RIGHT, &b->x, &b->y, b->w, b->h, f->x, f->y, f->w, f->h); b->x -= padding; b->y -= padding; } static void resize(void) { resize_header(); resize_autosave(); resize_button(); } static int headerclick(int x, int y) { return mlk_maths_is_boxed( ui.panel.frame.x, ui.panel.frame.y, ui.panel.frame.w, HEADER_HEIGHT, x, y ); } static void handle(struct mlk_state *st, const union mlk_event *ev) { (void)st; switch (ev->type) { case MLK_EVENT_QUIT: mlk_game_quit(); break; case MLK_EVENT_MOUSE: if (ui.motion.active) { ui.panel.frame.x += ev->mouse.x - ui.motion.x; ui.panel.frame.y += ev->mouse.y - ui.motion.y; ui.motion.x = ev->mouse.x; ui.motion.y = ev->mouse.y; resize(); } break; case MLK_EVENT_CLICKDOWN: if (headerclick(ev->click.x, ev->click.y)) { ui.motion.active = 1; ui.motion.x = ev->click.x; ui.motion.y = ev->click.y; mlk_window_set_cursor(MLK_WINDOW_CURSOR_SIZE); } break; case MLK_EVENT_CLICKUP: ui.motion.active = 0; mlk_window_set_cursor(MLK_WINDOW_CURSOR_ARROW); break; default: break; } mlk_checkbox_handle(&ui.autosave.cb, ev); if (mlk_button_handle(&ui.quit.button, ev)) mlk_game_quit(); } static void draw(struct mlk_state *st) { (void)st; mlk_painter_set_color(0xffffffff); mlk_painter_clear(); mlk_frame_draw(&ui.panel.frame); mlk_label_draw(&ui.header.label); mlk_checkbox_draw(&ui.autosave.cb); mlk_label_draw(&ui.autosave.label); mlk_button_draw(&ui.quit.button); mlk_painter_present(); } static void run(void) { struct mlk_state state = { .handle = handle, .draw = draw }; resize(); mlk_game_init(states, MLK_UTIL_SIZE(states)); mlk_game_push(&state); mlk_game_loop(); } static void quit(void) { mlk_window_finish(); ui_finish(); mlk_core_finish(); } int main(int argc, char **argv) { (void)argc; (void)argv; init(); run(); quit(); return 0; }