Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_gui_frameless_drag.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
40
41#define ALLEGRO_UNSTABLE 1
42
43#include <math.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47
48#include "nilorea/n_common.h"
49#include "nilorea/n_gui.h"
50#include "nilorea/n_log.h"
51
53static int failures = 0;
54
56static int slider_changes = 0;
57
63static void expect_true(const char* label, int cond) {
64 if (!cond) {
65 n_log(LOG_ERR, "%s: FAILED", label);
66 failures++;
67 } else {
68 n_log(LOG_INFO, "%s: OK", label);
69 }
70}
71
78static void on_slider(int id, double value, void* data) {
79 (void)id;
80 (void)value;
81 (void)data;
83}
84
92static ALLEGRO_EVENT mouse_event(int type, int x, int y) {
93 ALLEGRO_EVENT ev;
94 memset(&ev, 0, sizeof(ev));
95 ev.type = (unsigned int)type;
96 ev.mouse.x = x;
97 ev.mouse.y = y;
98 ev.mouse.button = 1;
99 return ev;
100}
101
110static void drag_right(N_GUI_CTX* gui, int x, int y, int step) {
111 int i = 0;
112
113 n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, x, y));
114 for (i = 1; i <= 3; i++) {
115 n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_AXES, x + i * step, y));
116 }
117 n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_UP, x + 3 * step, y));
118}
119
120int main(void) {
121 ALLEGRO_FONT* font;
122 ALLEGRO_BITMAP* pic;
123 N_GUI_CTX* gui;
124 N_GUI_WINDOW* w;
125 int win, slider;
126 double before;
127
129 if (!al_init() || !al_init_font_addon()) {
130 n_log(LOG_ERR, "allegro init failed");
131 return 1;
132 }
133 font = al_create_builtin_font(); /* no display needed */
134 if (!font) {
135 n_log(LOG_ERR, "al_create_builtin_font failed");
136 return 1;
137 }
138 /* a memory bitmap, since there is no display to make a video one on */
139 al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
140 pic = al_create_bitmap(16, 16);
141 if (!pic) {
142 n_log(LOG_ERR, "al_create_bitmap failed");
143 al_destroy_font(font);
144 return 1;
145 }
147 if (!gui) {
148 n_log(LOG_ERR, "n_gui_new_ctx failed");
149 al_destroy_bitmap(pic);
150 al_destroy_font(font);
151 return 1;
152 }
153 n_gui_set_display_size(gui, 800.0f, 600.0f);
154 win = n_gui_add_window(gui, "W", 0.0f, 0.0f, 400.0f, 300.0f);
155 /* frameless and NOT fixed: the body is a drag handle for the window */
157 slider = n_gui_add_slider(gui, win, 0.0f, 0.0f, 200.0f, 24.0f, 0.0, 1.0, 0.0,
159 n_gui_add_image(gui, win, 0.0f, 100.0f, 50.0f, 50.0f, pic, N_GUI_IMAGE_FIT);
161 w = n_gui_get_window(gui, win);
162 if (!w) {
163 n_log(LOG_ERR, "n_gui_get_window failed");
165 al_destroy_bitmap(pic);
166 al_destroy_font(font);
167 return 1;
168 }
169
170 /* A drag on the slider moves the slider and leaves the window where it
171 is. Before the fix the window moved by exactly the pointer's travel and
172 the slider stayed at its first value. */
173 n_gui_slider_set_value(gui, slider, 0.0);
174 before = n_gui_slider_get_value(gui, slider);
175 slider_changes = 0;
176 drag_right(gui, 40, 12, 20);
177 expect_true("a drag on a slider leaves the window where it was",
178 w->x == 0.0f && w->y == 0.0f);
179 expect_true("and moves the slider", n_gui_slider_get_value(gui, slider) > before);
180 /* one for the press and one per motion event */
181 expect_true("and reports every step of it", slider_changes >= 4);
182
183 /* The empty body is still a handle for the window. */
184 drag_right(gui, 300, 250, 10);
185 expect_true("a drag on the empty body moves the window", w->x == 30.0f && w->y == 0.0f);
186
187 /* So is an image, which does nothing with a press. The window is now 30
188 to the right, so the image is too. */
189 drag_right(gui, 30 + 20, 120, 10);
190 expect_true("a drag on an image moves the window", w->x == 60.0f);
191
193 al_destroy_bitmap(pic);
194 al_destroy_font(font);
195 if (failures) {
196 n_log(LOG_ERR, "ex_gui_frameless_drag: %d failure(s)", failures);
197 return 1;
198 }
199 n_log(LOG_NOTICE, "ex_gui_frameless_drag: all checks passed");
200 return 0;
201}
static int failures
Definition ex_atlas.c:51
int main(void)
Definition ex_atlas.c:117
static void expect_true(const char *label, int cond)
Definition ex_atlas.c:53
static ALLEGRO_EVENT mouse_event(int type, int x, int y, int dz)
Build a left-button mouse event at (x, y).
static N_GUI_CTX * gui
static int slider_changes
How many times the slider's callback fired.
static void drag_right(N_GUI_CTX *gui, int x, int y, int step)
Press at (x, y), move right in three steps of step with the button held, and release where the pointe...
static void on_slider(int id, double value, void *data)
Slider callback: counts the changes it is told about.
static void type(N_GUI_CTX *gui, const char *s)
Type a whole string into whatever has focus.
FONT * font
the default 8x8 font, valid after allegro_init()
float x
position x on screen
Definition n_gui.h:1312
float y
position y on screen
Definition n_gui.h:1314
void n_gui_set_display_size(N_GUI_CTX *ctx, float w, float h)
set the display (viewport) size so global scrollbars can be computed.
Definition n_gui.c:12348
#define N_GUI_IMAGE_FIT
scale to fit within bounds, keep aspect ratio
Definition n_gui.h:204
int n_gui_add_slider(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, double min_val, double max_val, double initial, int mode, void(*on_change)(int, double, void *), void *user_data)
Add a slider widget.
Definition n_gui.c:3106
#define N_GUI_SLIDER_VALUE
slider uses raw start/end values
Definition n_gui.h:178
int n_gui_process_event(N_GUI_CTX *ctx, ALLEGRO_EVENT event)
Process an allegro event through the GUI system.
Definition n_gui.c:13611
double n_gui_slider_get_value(N_GUI_CTX *ctx, int widget_id)
get the current value of a slider widget
Definition n_gui.c:3962
#define N_GUI_WIN_FRAMELESS
frameless window: no title bar drawn, drag via window body unless N_GUI_WIN_FIXED_POSITION is also se...
Definition n_gui.h:276
int n_gui_add_image(N_GUI_CTX *ctx, int window_id, float x, float y, float w, float h, ALLEGRO_BITMAP *bitmap, int scale_mode)
Add an image display widget.
Definition n_gui.c:3610
N_GUI_WINDOW * n_gui_get_window(N_GUI_CTX *ctx, int window_id)
Get a window pointer by id.
Definition n_gui.c:1397
int n_gui_add_window(N_GUI_CTX *ctx, const char *title, float x, float y, float w, float h)
Add a new pseudo-window to the context.
Definition n_gui.c:1277
N_GUI_CTX * n_gui_new_ctx(ALLEGRO_FONT *default_font)
Create a new GUI context.
Definition n_gui.c:1103
void n_gui_destroy_ctx(N_GUI_CTX **ctx)
Destroy a GUI context and all its windows/widgets.
Definition n_gui.c:1209
void n_gui_open_window(N_GUI_CTX *ctx, int window_id)
Open (show) a window.
Definition n_gui.c:1436
void n_gui_slider_set_value(N_GUI_CTX *ctx, int widget_id, double value)
set the value of a slider widget
Definition n_gui.c:3976
void n_gui_window_set_flags(N_GUI_CTX *ctx, int window_id, int flags)
Set feature flags on a window.
Definition n_gui.c:2515
The top-level GUI context that holds all windows.
Definition n_gui.h:1669
A pseudo window that contains widgets.
Definition n_gui.h:1298
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:113
#define LOG_ERR
error conditions
Definition n_log.h:100
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
Definition n_log.c:123
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:104
#define LOG_INFO
informational
Definition n_log.h:106
Common headers and low-level functions & define.
GUI system: buttons, sliders, text areas, checkboxes, scrollbars, dropdown menus, windows.
Generic log system.