6 ex__gui__slider__default_8c
gullradriel edited this page 2026-10-09 00:55:18 +02:00

examples/ex_gui_slider_default.c

Functions

Name
void press_at(N_GUI_CTX * gui, int x, int y, int release)
Press the primary button at (x, y), and release it unless asked not to.
void on_change(int widget_id, double value, void * user_data)
The slider's on_change: count the calls and keep the value.
ALLEGRO_EVENT mouse_event(int type, int x, int y)
Build a left-button mouse event at (x, y).
int main(void )
void expect_true(const char * label, int cond)
Assert a condition, logging which check failed.

Attributes

Name
double last_value
how many times the picker called back, and with what
int failures
Count of failed assertions.
int changes
How many times on_change ran, and the last value it was given.

Defines

Name
ALLEGRO_UNSTABLE

Functions Documentation

function press_at

static void press_at(
    N_GUI_CTX * gui,
    int x,
    int y,
    int release
)

Press the primary button at (x, y), and release it unless asked not to.

Parameters:

  • gui GUI context.
  • x Cursor x.
  • y Cursor y.
  • release Non-zero to send the release as well.

function on_change

static void on_change(
    int widget_id,
    double value,
    void * user_data
)

The slider's on_change: count the calls and keep the value.

Parameters:

  • widget_id The slider.
  • value Its new value.
  • user_data Unused.

function mouse_event

static ALLEGRO_EVENT mouse_event(
    int type,
    int x,
    int y
)

Build a left-button mouse event at (x, y).

Parameters:

  • type The ALLEGRO_EVENT_MOUSE_* type.
  • x Cursor x.
  • y Cursor y.

Return: The event.

function main

int main(
    void 
)

function expect_true

static void expect_true(
    const char * label,
    int cond
)

Assert a condition, logging which check failed.

Parameters:

  • label What is being checked.
  • cond Non-zero to pass.

Attributes Documentation

variable last_value

static double last_value = -1.0;

how many times the picker called back, and with what

variable failures

static int failures = 0;

Count of failed assertions.

variable changes

static int changes = 0;

How many times on_change ran, and the last value it was given.

Macros Documentation

define ALLEGRO_UNSTABLE

#define ALLEGRO_UNSTABLE 1

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#define ALLEGRO_UNSTABLE 1

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "nilorea/n_common.h"
#include "nilorea/n_gui.h"
#include "nilorea/n_log.h"

static int failures = 0;

static int changes = 0;
static double last_value = -1.0;

static void expect_true(const char* label, int cond) {
    if (!cond) {
        n_log(LOG_ERR, "%s: FAILED", label);
        failures++;
    } else {
        n_log(LOG_INFO, "%s: OK", label);
    }
}

static void on_change(int widget_id, double value, void* user_data) {
    (void)widget_id;
    (void)user_data;
    changes++;
    last_value = value;
}

static ALLEGRO_EVENT mouse_event(int type, int x, int y) {
    ALLEGRO_EVENT ev;
    memset(&ev, 0, sizeof(ev));
    ev.type = (unsigned int)type;
    ev.mouse.x = x;
    ev.mouse.y = y;
    ev.mouse.button = 1;
    return ev;
}

static void press_at(N_GUI_CTX* gui, int x, int y, int release) {
    n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_AXES, x, y));
    n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_DOWN, x, y));
    if (release) n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_UP, x, y));
}

int main(void) {
    ALLEGRO_FONT* font;
    N_GUI_CTX* gui;
    int win, with, without;
    double def = 0.0, at_click = 0.0;

    set_log_level(LOG_ERR);
    if (!al_init() || !al_init_font_addon()) {
        n_log(LOG_ERR, "allegro init failed");
        return 1;
    }
    font = al_create_builtin_font(); /* no display needed */
    if (!font) {
        n_log(LOG_ERR, "al_create_builtin_font failed");
        return 1;
    }
    gui = n_gui_new_ctx(font);
    if (!gui) {
        n_log(LOG_ERR, "n_gui_new_ctx failed");
        al_destroy_font(font);
        return 1;
    }
    n_gui_set_display_size(gui, 800.0f, 600.0f);
    win = n_gui_add_window(gui, "W", 0.0f, 0.0f, 400.0f, 300.0f);
    n_gui_window_set_flags(gui, win, N_GUI_WIN_FRAMELESS);
    with = n_gui_add_slider(gui, win, 0.0f, 0.0f, 300.0f, 30.0f, 0.0, 100.0, 50.0, N_GUI_SLIDER_VALUE, on_change, NULL);
    without = n_gui_add_slider(gui, win, 0.0f, 60.0f, 300.0f, 30.0f, 0.0, 100.0, 50.0, N_GUI_SLIDER_VALUE, on_change, NULL);
    n_gui_open_window(gui, win);

    expect_true("a slider has no default until given one", !n_gui_slider_get_default(gui, with, NULL));
    n_gui_slider_set_default(gui, with, 50.0);
    expect_true("and has the one it is given",
                n_gui_slider_get_default(gui, with, &def) && fabs(def - 50.0) < 1e-9);

    /* One click near the left end moves the handle there, as always. */
    press_at(gui, 30, 15, 1);
    at_click = n_gui_slider_get_value(gui, with);
    expect_true("a click moves the handle to the pointer", at_click < 25.0 && changes == 1);

    /* The second press of a double click: it too moves the handle to the
       pointer, then the default is put back and on_change told. */
    press_at(gui, 30, 15, 0);
    expect_true("a double click puts the default back", fabs(n_gui_slider_get_value(gui, with) - 50.0) < 1e-9);
    expect_true("and on_change hears it", fabs(last_value - 50.0) < 1e-9);
    /* The button is still down. Moving the pointer must not drag it away. */
    n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_AXES, 250, 15));
    expect_true("the drag the second press began is over",
                fabs(n_gui_slider_get_value(gui, with) - 50.0) < 1e-9);
    n_gui_process_event(gui, mouse_event(ALLEGRO_EVENT_MOUSE_BUTTON_UP, 250, 15));

    /* A slider with no default is left where the clicks put it. */
    press_at(gui, 30, 75, 1);
    press_at(gui, 30, 75, 1);
    expect_true("a slider with no default ignores the gesture", n_gui_slider_get_value(gui, without) < 25.0);

    n_gui_destroy_ctx(&gui);
    al_destroy_font(font);
    if (failures) {
        n_log(LOG_ERR, "ex_gui_slider_default: %d failure(s)", failures);
        return 1;
    }
    n_log(LOG_NOTICE, "ex_gui_slider_default: all checks passed");
    return 0;
}