ui/ui/toolkit.h

Sun, 07 Apr 2024 21:56:56 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Apr 2024 21:56:56 +0200
branch
newapi
changeset 280
e3565cf7c831
parent 265
3756725aeaf4
permissions
-rw-r--r--

add threadpool

/*
 * 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.
 */

#ifndef UI_TOOLKIT_H
#define	UI_TOOLKIT_H

#include <inttypes.h>

#ifdef UI_COCOA

#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#define UIWIDGET NSView*
#define UIMENU   NSMenu*
#else
typedef void* UIWIDGET;
typedef void* UIMENU;
#endif

#elif UI_GTK2 || UI_GTK3

#include <gtk/gtk.h>
#define UIWIDGET GtkWidget*
#define UIMENU   GtkMenu*
#define UI_GTK

#elif UI_MOTIF

#include <Xm/XmAll.h> 
#define UIWIDGET Widget
#define UIMENU   Widget

#elif defined(UI_QT4) || defined(UI_QT5)
#ifdef	__cplusplus
#include <QApplication>
#include <QWidget>
#include <QMenu>
#define UIWIDGET QWidget*
#define UIMENU   QMenu*
#else /* __cplusplus */
#define UIWIDGET void*
#define UIMENU   void*
#endif

#elif UI_WINUI

#define UIEXPORT __declspec(dllexport) 

#ifdef __cplusplus

#ifndef UI_WINUI_PCH
#include <Windows.h>
#undef GetCurrentTime
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#endif

class UiWindow {
public:
    winrt::Microsoft::UI::Xaml::Window window { nullptr };

    UiWindow(winrt::Microsoft::UI::Xaml::Window& win);
};

class UiWidget {
public:
    winrt::Microsoft::UI::Xaml::UIElement uielement;
    void* data1 = nullptr;
    void* data2 = nullptr;
    void* data3 = nullptr;
    UiWidget(winrt::Microsoft::UI::Xaml::UIElement& elm);

};

#define UIWIDGET UiWidget*
#define UIWINDOW UiWindow*
#define UIMENU   void*

/*
// winrt::Microsoft::UI::Xaml::UIElement
#define UIWIDGET void*
// winrt::Microsoft::UI::Xaml::Window
#define UIWINDOW void*
#define UIMENU   void*
*/

#else
#define UIWIDGET void*
#define UIWINDOW void*
#define UIMENU   void*
#endif


#endif

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#ifndef UIEXPORT
#define UIEXPORT
#endif

#ifdef	__cplusplus
extern "C" {
#endif

#define UI_GROUP_SELECTION  20000

#define UI_GROUPS(...) (int[]){ __VA_ARGS__, -1 }
    
/* public types */
typedef int UiBool;

typedef struct UiObject     UiObject;
typedef struct UiEvent      UiEvent;
typedef struct UiMouseEvent UiMouseEvent;
typedef struct UiObserver   UiObserver;

typedef struct UiInteger    UiInteger;
typedef struct UiDouble     UiDouble;
typedef struct UiString     UiString;
typedef struct UiText       UiText;
typedef struct UiList       UiList;
typedef struct UiRange      UiRange;

typedef struct UiStr        UiStr;

typedef struct UiFileList   UiFileList;

typedef struct UiListSelection UiListSelection;

/* begin opaque types */
typedef struct UiContext    UiContext;
typedef struct UiContainer  UiContainer;

typedef struct UiIcon       UiIcon;
typedef struct UiImage      UiImage;

typedef struct UiDnD        UiDnD;

typedef struct UiThreadpool UiThreadpool;
/* end opaque types */

typedef struct UiTabbedPane UiTabbedPane;

typedef enum UiTri UiTri;
typedef enum UiLabelType UiLabelType;

enum UiMouseEventType { UI_PRESS = 0, UI_PRESS2 };

enum UiLabelType { UI_LABEL_DEFAULT, UI_LABEL_TEXT, UI_LABEL_ICON, UI_LABEL_TEXT_ICON };


  
typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */

typedef void*(*ui_getvaluefunc)(void*, int);

typedef int(*ui_threadfunc)(void*);

typedef void(*ui_freefunc)(void*);

typedef void(*ui_enablefunc)(void*, UiBool);

struct UiObject {
    /*
     * native widget
     */
    UIWIDGET    widget;

#ifdef UI_WINUI
    /*
     * native window object 
     */
    UIWINDOW    wobj;
#endif
    
    /*
     * user window data
     */
    void        *window;
    
    /*
     * window context
     */
    UiContext   *ctx;
    
    /*
     * container interface
     */
    UiContainer *container;
    
    /*
     * next container object
     */
    UiObject    *next;
};

struct UiTabbedPane {
    /*
     * native widget
     */
    UIWIDGET  widget;
    
    /*
     * current document
     */
    void      *document;
    
    /*
     * parent context
     */
    UiContext *ctx;
};

struct UiEvent {
    UiObject *obj;
    void     *document;
    void     *window;
    void     *eventdata;
    int      intval;
};

struct UiMouseEvent {
    int x;
    int y;
    enum UiMouseEventType type;
    int button;
};

struct UiObserver {
    ui_callback callback;
    void *data;
    UiObserver *next;
};

struct UiStr {
    char *ptr;
    void (*free)(void *v);
};

struct UiInteger {
    int64_t  (*get)(UiInteger*);
    void (*set)(UiInteger*, int64_t);
    void *obj;
    
    int64_t value;
    UiObserver *observers;
};

struct UiDouble {
    double  (*get)(UiDouble*);
    void (*set)(UiDouble*, double);
    void *obj;
    
    double value;
    UiObserver *observers;
};

struct UiString {
    char* (*get)(UiString*);
    void  (*set)(UiString*, const char*);
    void  *obj;
    
    UiStr value;
    UiObserver *observers;
};

struct UiText {
    void  (*set)(UiText*, const char*);
    char* (*get)(UiText*);
    char* (*getsubstr)(UiText*, int, int); /* text, begin, end */
    void  (*insert)(UiText*, int, char*);
    void  (*setposition)(UiText*,int);
    int   (*position)(UiText*);
    void  (*selection)(UiText*, int*, int*); /* text, begin, end */
    int   (*length)(UiText*);
    void  (*remove)(UiText*, int, int); /* text, begin, end */
    UiStr value;
    int   pos;
    void  *obj;
    void  *undomgr;
    // TODO: replacefunc, ...
    UiObserver *observers;
};
    
/*
 * abstract list
 */
struct UiList {
    /* get the first element */
    void*(*first)(UiList *list);
    /* get the next element */
    void*(*next)(UiList *list);
    /* get the nth element */
    void*(*get)(UiList *list, int i);
    /* get the number of elements */
    int(*count)(UiList *list);
    /* iterator changes after first() next() and get() */
    void *iter;
    /* private - implementation dependent */
    void *data;
    
    /* binding functions */
    void (*update)(UiList *list, int i);
    UiListSelection (*getselection)(UiList *list);
    /* binding object */
    void *obj;
    
    /* list of observers */
    UiObserver *observers;
};


struct UiListSelection {
    /*
    * number of selected items
    */
    int count;

    /*
    * indices of selected rows
    */
    int *rows;
};

struct UiRange {
    double (*get)(UiRange *range);
    void   (*set)(UiRange *range, double value);
    void   (*setrange)(UiRange *range, double min, double max);
    void   (*setextent)(UiRange *range, double extent);
    double value;
    double min;
    double max;
    double extent;
    void   *obj;
    /* list of observers */
    UiObserver *observers;
};

enum UiTri {
    UI_DEFAULT = 0,
    UI_ON,
    UI_OFF
};

struct UiFileList {
    char **files;
    size_t nfiles;
};


UIEXPORT void ui_init(const char *appname, int argc, char **argv);
UIEXPORT const char* ui_appname();

UIEXPORT UiContext* ui_global_context(void);

UIEXPORT void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);

UIEXPORT void ui_context_destroy(UiContext *ctx);

UIEXPORT void ui_onstartup(ui_callback f, void *userdata);
UIEXPORT void ui_onopen(ui_callback f, void *userdata);
UIEXPORT void ui_onexit(ui_callback f, void *userdata);

UIEXPORT void ui_main();
UIEXPORT void ui_show(UiObject *obj);
UIEXPORT void ui_close(UiObject *obj);

UIEXPORT void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd);
UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td);
UIEXPORT UiThreadpool* ui_threadpool_create(int nthreads);
UIEXPORT void ui_threadpool_destroy(UiThreadpool* pool);
UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd);

UIEXPORT void* ui_document_new(size_t size);
UIEXPORT void  ui_document_destroy(void *doc);

UIEXPORT void ui_set_document(UiObject *obj, void *document);    // deprecated
UIEXPORT void ui_detach_document(UiObject *obj);                 // deprecated
UIEXPORT void* ui_get_document(UiObject *obj);                   // deprecated
UIEXPORT void ui_set_subdocument(void *document, void *sub);     // deprecated
UIEXPORT void ui_detach_subdocument(void *document, void *sub);  // deprecated
UIEXPORT void* ui_get_subdocument(void *document);               // deprecated

UIEXPORT UiContext* ui_document_context(void *doc);

UIEXPORT void ui_attach_document(UiContext *ctx, void *document);
UIEXPORT void ui_detach_document2(UiContext *ctx, void *document);

UIEXPORT void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...);

UIEXPORT void ui_set_group(UiContext *ctx, int group);
UIEXPORT void ui_unset_group(UiContext *ctx, int group);
UIEXPORT int* ui_active_groups(UiContext *ctx, int *ngroups);
    
UIEXPORT void* ui_malloc(UiContext *ctx, size_t size);
UIEXPORT void* ui_calloc(UiContext *ctx, size_t nelem, size_t elsize);
UIEXPORT void  ui_free(UiContext *ctx, void *ptr);
UIEXPORT void* ui_realloc(UiContext *ctx, void *ptr, size_t size);

// types

UIEXPORT UiInteger* ui_int_new(UiContext *ctx, char *name);
UIEXPORT UiDouble* ui_double_new(UiContext *ctx, char *name);
UIEXPORT UiString* ui_string_new(UiContext *ctx, char *name);
UIEXPORT UiText* ui_text_new(UiContext *ctx, char *name);
UIEXPORT UiRange* ui_range_new(UiContext *ctx, char *name);

#define ui_get(v) _Generic(v, \
    UiInteger*: ui_int_get, \
    UiDouble*: ui_double_get, \
    UiString*: ui_string_get, \
    UiText*:ui_text_get) (v)

#define ui_set(v, n) _Generic(v, \
    UiInteger*: ui_int_set, \
    UiDouble*: ui_double_set, \
    UiString*: ui_string_set, \
    UiText*:ui_text_set) (v, n)

UIEXPORT void ui_int_set(UiInteger *i, int64_t value);
UIEXPORT int64_t ui_int_get(UiInteger *i);
UIEXPORT void ui_double_set(UiDouble *d, double value);
UIEXPORT double ui_double_get(UiDouble *d);
UIEXPORT void ui_string_set(UiString *s, const char *value);
UIEXPORT char* ui_string_get(UiString *s);
UIEXPORT void ui_text_set(UiText *s, const char* value);
UIEXPORT char* ui_text_get(UiText *s);


UIEXPORT UiObserver* ui_observer_new(ui_callback f, void *data);
UIEXPORT UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer);
UIEXPORT UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data);
UIEXPORT void ui_notify(UiObserver *observer, void *data);
UIEXPORT void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data);
UIEXPORT void ui_notify_evt(UiObserver *observer, UiEvent *event);


UIEXPORT UiList* ui_list_new(UiContext *ctx, char *name);
UIEXPORT void* ui_list_first(UiList *list);
UIEXPORT void* ui_list_next(UiList *list);
UIEXPORT void* ui_list_get(UiList *list, int i);
UIEXPORT int   ui_list_count(UiList *list);
UIEXPORT void  ui_list_append(UiList *list, void *data);
UIEXPORT void  ui_list_prepend(UiList *list, void *data);
UIEXPORT void ui_list_remove(UiList *list, int i);
UIEXPORT void ui_list_clear(UiList *list);
UIEXPORT void  ui_list_addobsv(UiList *list, ui_callback f, void *data);
UIEXPORT void  ui_list_notify(UiList *list);

UIEXPORT UiListSelection ui_list_getselection(UiList *list);

UIEXPORT UiFileList ui_filelist_copy(UiFileList list);
UIEXPORT void ui_filelist_free(UiFileList list);

UIEXPORT void ui_clipboard_set(char *str);
UIEXPORT char* ui_clipboard_get();

UIEXPORT void ui_add_image(char *imgname, char *filename); // TODO: remove?

// general widget functions
UIEXPORT void ui_set_enabled(UIWIDGET widget, int enabled);
UIEXPORT void ui_set_show_all(UIWIDGET widget, int value);
UIEXPORT void ui_set_visible(UIWIDGET widget, int visible);



UIEXPORT void ui_listselection_free(UiListSelection selection);

UIEXPORT UiIcon* ui_icon(const char* name, size_t size);
UIEXPORT UiIcon* ui_icon_unscaled(const char *name, int size);
UIEXPORT UiIcon* ui_imageicon(const char* file);
UIEXPORT void ui_icon_free(UiIcon* icon);

UIEXPORT UiIcon* ui_foldericon(size_t size);
UIEXPORT UiIcon* ui_fileicon(size_t size);


UIEXPORT UiStr ui_str(char *cstr);
UIEXPORT UiStr ui_str_free(char *str, void (*free)(void *v));

#ifdef	__cplusplus
}
#endif

#endif	/* UI_TOOLKIT_H */

mercurial