ui/gtk/entry.c

Tue, 29 Oct 2024 11:52:01 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 29 Oct 2024 11:52:01 +0100
branch
newapi
changeset 370
822fcb83bdf1
parent 356
eae98e4f3f1f
permissions
-rw-r--r--

improve window close handling

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2017 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

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

#include "../common/context.h"
#include "../common/object.h"
#include "container.h"
#include "entry.h"


UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs args) {
    double min = 0;
    double max = 1000;
    
    UiObject* current = uic_current_obj(obj);
    
    UiVar *var = NULL;
    if(args.varname) {
        var = uic_get_var(obj->ctx, args.varname);
    }
    
    if(!var) {
        if(args.intvalue) {
            var = uic_widget_var(obj->ctx, current->ctx, args.intvalue, NULL, UI_VAR_INTEGER);
        } else if(args.doublevalue) {
            var = uic_widget_var(obj->ctx, current->ctx, args.doublevalue, NULL, UI_VAR_DOUBLE);
        } else if(args.rangevalue) {
            var = uic_widget_var(obj->ctx, current->ctx, args.rangevalue, NULL, UI_VAR_RANGE);
        }
    }
    
    if(var && var->type == UI_VAR_RANGE) {
        UiRange *r = var->value;
        min = r->min;
        max = r->max;
    }
    if(args.step == 0) {
        args.step = 1;
    }
#ifdef UI_GTK2LEGACY
    if(min == max) {
        max = min + 1;
    }
#endif
    GtkWidget *spin = gtk_spin_button_new_with_range(min, max, args.step);
    ui_set_name_and_style(spin, args.name, args.style_class);
    ui_set_widget_groups(obj->ctx, spin, args.groups);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), args.digits);
    UiObserver **obs = NULL;
    if(var) {
        double value = 0;
        switch(var->type) {
            default: break;
            case UI_VAR_INTEGER: {
                UiInteger *i = var->value;
                i->get = ui_spinbutton_getint;
                i->set = ui_spinbutton_setint;
                i->obj = spin;
                value = (double)i->value;
                obs = &i->observers;
                break;
            }
            case UI_VAR_DOUBLE: {
                UiDouble *d = var->value;
                d->get = ui_spinbutton_getdouble;
                d->set = ui_spinbutton_setdouble;
                d->obj = spin;
                value = d->value;
                obs = &d->observers;
                break;
            }
            case UI_VAR_RANGE: {
                UiRange *r = var->value;
                r->get = ui_spinbutton_getrangeval;
                r->set = ui_spinbutton_setrangeval;
                r->setrange = ui_spinbutton_setrange;
                r->setextent = ui_spinbutton_setextent;
                r->obj = spin;
                value = r->value;
                obs = &r->observers;
                break;
            }
        }
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin), value);
    }
    
    UiVarEventData *event = malloc(sizeof(UiVarEventData));
    event->obj = obj;
    event->var = var;
    event->observers = obs;
    event->callback = args.onchange;
    event->userdata = args.onchangedata;

    g_signal_connect(
            spin,
            "value-changed",
            G_CALLBACK(ui_spinner_changed),
            event);
    g_signal_connect(
            spin,
            "destroy",
            G_CALLBACK(ui_destroy_vardata),
            event);
    
    UI_APPLY_LAYOUT1(current, args);
    current->container->add(current->container, spin, FALSE);
    
    return spin;
}

void ui_spinner_setrange(UIWIDGET spinner, double min, double max) {
    gtk_spin_button_set_range(GTK_SPIN_BUTTON(spinner), min, max);
}

void ui_spinner_setdigits(UIWIDGET spinner, int digits) {
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spinner), digits);
}


void ui_spinner_changed(GtkSpinButton *spinner, UiVarEventData *event) {
    gdouble value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinner));
    UiEvent e;
    e.obj = event->obj;
    e.window = event->obj->window;
    e.document = event->obj->ctx->document;
    e.eventdata = &value;
    e.intval = (int64_t)value;
    
    if(event->callback) {
        event->callback(&e, event->userdata);
    }
    
    if(event->observers) {
        UiObserver *observer = *event->observers;
        ui_notify_evt(observer, &e);
    }
}


int64_t ui_spinbutton_getint(UiInteger *i) {
    i->value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(i->obj));
    return i->value;
}

void ui_spinbutton_setint(UiInteger *i, int64_t val) {
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(i->obj), (double)val);
    i->value = val;
}

double ui_spinbutton_getdouble(UiDouble *d) {
    d->value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(d->obj));
    return d->value;
}

void ui_spinbutton_setdouble(UiDouble *d, double val) {
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(d->obj), val);
    d->value = val;
}

double ui_spinbutton_getrangeval(UiRange *r) {
    r->value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(r->obj));
    return r->value;
}

void ui_spinbutton_setrangeval(UiRange *r, double val) {
    gtk_spin_button_set_value(GTK_SPIN_BUTTON(r->obj), val);
    r->value = val;
}
void ui_spinbutton_setrange(UiRange *r, double min, double max) {
    gtk_spin_button_set_range(GTK_SPIN_BUTTON(r->obj), min, max);
    r->min = min;
    r->max = max;
}

void ui_spinbutton_setextent(UiRange *r, double extent) {
    gtk_spin_button_set_increments(GTK_SPIN_BUTTON(r->obj), extent, extent*10);
    r->extent = extent;
}

mercurial