another UI attempt, I guess.

sorry.
This commit is contained in:
StapleButter
2017-09-09 02:30:51 +02:00
parent 81747d6c34
commit 70e4841d31
244 changed files with 35965 additions and 0 deletions

View File

@ -0,0 +1,16 @@
# 3 june 2016
list(APPEND _LIBUI_SOURCES
common/areaevents.c
common/control.c
common/debug.c
common/matrix.c
common/shouldquit.c
common/userbugs.c
)
set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
list(APPEND _LIBUI_INCLUDEDIRS
common
)
set(_LIBUI_INCLUDEDIRS ${_LIBUI_INCLUDEDIRS} PARENT_SCOPE)

View File

@ -0,0 +1,167 @@
// 29 march 2014
#include "../ui.h"
#include "uipriv.h"
/*
Windows and GTK+ have a limit of 2 and 3 clicks, respectively, natively supported. Fortunately, we can simulate the double/triple-click behavior to build higher-order clicks. We can use the same algorithm Windows uses on both:
http://blogs.msdn.com/b/oldnewthing/archive/2004/10/18/243925.aspx
For GTK+, we pull the double-click time and double-click distance, which work the same as the equivalents on Windows (so the distance is in all directions), from the GtkSettings system.
On GTK+ this will also allow us to discard the GDK_BUTTON_2PRESS and GDK_BUTTON_3PRESS events, so the button press stream will be just like on other platforms.
Thanks to mclasen, garnacho_, halfline, and tristan in irc.gimp.net/#gtk+.
*/
// x, y, xdist, ydist, and c.rect must have the same units
// so must time, maxTime, and c.prevTime
int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist)
{
// different button than before? if so, don't count
if (button != c->curButton)
c->count = 0;
// (x, y) in the allowed region for a double-click? if not, don't count
if (x < c->rectX0)
c->count = 0;
if (y < c->rectY0)
c->count = 0;
if (x >= c->rectX1)
c->count = 0;
if (y >= c->rectY1)
c->count = 0;
// too slow? if so, don't count
// note the below expression; time > (c.prevTime + maxTime) can overflow!
if ((time - c->prevTime) > maxTime) // too slow; don't count
c->count = 0;
c->count++; // if either of the above ifs happened, this will make the click count 1; otherwise it will make the click count 2, 3, 4, 5, ...
// now we need to update the internal structures for the next test
c->curButton = button;
c->prevTime = time;
c->rectX0 = x - xdist;
c->rectY0 = y - ydist;
c->rectX1 = x + xdist;
c->rectY1 = y + ydist;
return c->count;
}
void clickCounterReset(clickCounter *c)
{
c->curButton = 0;
c->rectX0 = 0;
c->rectY0 = 0;
c->rectX1 = 0;
c->rectY1 = 0;
c->prevTime = 0;
c->count = 0;
}
/*
For position independence across international keyboard layouts, typewriter keys are read using scancodes (which are always set 1).
Windows provides the scancodes directly in the LPARAM.
GTK+ provides the scancodes directly from the underlying window system via GdkEventKey.hardware_keycode.
On X11, this is scancode + 8 (because X11 keyboard codes have a range of [8,255]).
Wayland is guaranteed to give the same result (thanks ebassi in irc.gimp.net/#gtk+).
On Linux, where evdev is used instead of polling scancodes directly from the keyboard, evdev's typewriter section key code constants are the same as scancodes anyway, so the rules above apply.
Typewriter section scancodes are the same across international keyboards with some exceptions that have been accounted for (see KeyEvent's documentation); see http://www.quadibloc.com/comp/scan.htm for details.
Non-typewriter keys can be handled safely using constants provided by the respective backend API.
Because GTK+ keysyms may or may not obey Num Lock, we also handle the 0-9 and . keys on the numeric keypad with scancodes (they match too).
*/
// use uintptr_t to be safe; the size of the scancode/hardware key code field on each platform is different
static const struct {
uintptr_t scancode;
char equiv;
} scancodeKeys[] = {
{ 0x02, '1' },
{ 0x03, '2' },
{ 0x04, '3' },
{ 0x05, '4' },
{ 0x06, '5' },
{ 0x07, '6' },
{ 0x08, '7' },
{ 0x09, '8' },
{ 0x0A, '9' },
{ 0x0B, '0' },
{ 0x0C, '-' },
{ 0x0D, '=' },
{ 0x0E, '\b' },
{ 0x0F, '\t' },
{ 0x10, 'q' },
{ 0x11, 'w' },
{ 0x12, 'e' },
{ 0x13, 'r' },
{ 0x14, 't' },
{ 0x15, 'y' },
{ 0x16, 'u' },
{ 0x17, 'i' },
{ 0x18, 'o' },
{ 0x19, 'p' },
{ 0x1A, '[' },
{ 0x1B, ']' },
{ 0x1C, '\n' },
{ 0x1E, 'a' },
{ 0x1F, 's' },
{ 0x20, 'd' },
{ 0x21, 'f' },
{ 0x22, 'g' },
{ 0x23, 'h' },
{ 0x24, 'j' },
{ 0x25, 'k' },
{ 0x26, 'l' },
{ 0x27, ';' },
{ 0x28, '\'' },
{ 0x29, '`' },
{ 0x2B, '\\' },
{ 0x2C, 'z' },
{ 0x2D, 'x' },
{ 0x2E, 'c' },
{ 0x2F, 'v' },
{ 0x30, 'b' },
{ 0x31, 'n' },
{ 0x32, 'm' },
{ 0x33, ',' },
{ 0x34, '.' },
{ 0x35, '/' },
{ 0x39, ' ' },
{ 0xFFFF, 0 },
};
static const struct {
uintptr_t scancode;
uiExtKey equiv;
} scancodeExtKeys[] = {
{ 0x47, uiExtKeyN7 },
{ 0x48, uiExtKeyN8 },
{ 0x49, uiExtKeyN9 },
{ 0x4B, uiExtKeyN4 },
{ 0x4C, uiExtKeyN5 },
{ 0x4D, uiExtKeyN6 },
{ 0x4F, uiExtKeyN1 },
{ 0x50, uiExtKeyN2 },
{ 0x51, uiExtKeyN3 },
{ 0x52, uiExtKeyN0 },
{ 0x53, uiExtKeyNDot },
{ 0xFFFF, 0 },
};
int fromScancode(uintptr_t scancode, uiAreaKeyEvent *ke)
{
int i;
for (i = 0; scancodeKeys[i].scancode != 0xFFFF; i++)
if (scancodeKeys[i].scancode == scancode) {
ke->Key = scancodeKeys[i].equiv;
return 1;
}
for (i = 0; scancodeExtKeys[i].scancode != 0xFFFF; i++)
if (scancodeExtKeys[i].scancode == scancode) {
ke->ExtKey = scancodeExtKeys[i].equiv;
return 1;
}
return 0;
}

View File

@ -0,0 +1,101 @@
// 26 may 2015
#include "../ui.h"
#include "uipriv.h"
void uiControlDestroy(uiControl *c)
{
(*(c->Destroy))(c);
}
uintptr_t uiControlHandle(uiControl *c)
{
return (*(c->Handle))(c);
}
uiControl *uiControlParent(uiControl *c)
{
return (*(c->Parent))(c);
}
void uiControlSetParent(uiControl *c, uiControl *parent)
{
(*(c->SetParent))(c, parent);
}
int uiControlToplevel(uiControl *c)
{
return (*(c->Toplevel))(c);
}
int uiControlVisible(uiControl *c)
{
return (*(c->Visible))(c);
}
void uiControlShow(uiControl *c)
{
(*(c->Show))(c);
}
void uiControlHide(uiControl *c)
{
(*(c->Hide))(c);
}
int uiControlEnabled(uiControl *c)
{
return (*(c->Enabled))(c);
}
void uiControlEnable(uiControl *c)
{
(*(c->Enable))(c);
}
void uiControlDisable(uiControl *c)
{
(*(c->Disable))(c);
}
#define uiControlSignature 0x7569436F
uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr)
{
uiControl *c;
c = (uiControl *) uiAlloc(size, typenamestr);
c->Signature = uiControlSignature;
c->OSSignature = OSsig;
c->TypeSignature = typesig;
return c;
}
void uiFreeControl(uiControl *c)
{
if (uiControlParent(c) != NULL)
userbug("You cannot destroy a uiControl while it still has a parent. (control: %p)", c);
uiFree(c);
}
void uiControlVerifySetParent(uiControl *c, uiControl *parent)
{
uiControl *curParent;
if (uiControlToplevel(c))
userbug("You cannot give a toplevel uiControl a parent. (control: %p)", c);
curParent = uiControlParent(c);
if (parent != NULL && curParent != NULL)
userbug("You cannot give a uiControl a parent while it already has one. (control: %p; current parent: %p; new parent: %p)", c, curParent, parent);
if (parent == NULL && curParent == NULL)
implbug("attempt to double unparent uiControl %p", c);
}
int uiControlEnabledToUser(uiControl *c)
{
while (c != NULL) {
if (!uiControlEnabled(c))
return 0;
c = uiControlParent(c);
}
return 1;
}

View File

@ -0,0 +1,25 @@
// 24 april 2016
#define uiAreaSignature 0x41726561
#define uiBoxSignature 0x426F784C
#define uiButtonSignature 0x42746F6E
#define uiCheckboxSignature 0x43686B62
#define uiColorButtonSignature 0x436F6C42
#define uiComboboxSignature 0x436F6D62
#define uiDateTimePickerSignature 0x44545069
#define uiEditableComboboxSignature 0x45644362
#define uiEntrySignature 0x456E7472
#define uiFontButtonSignature 0x466F6E42
#define uiFormSignature 0x466F726D
#define uiGridSignature 0x47726964
#define uiGroupSignature 0x47727062
#define uiLabelSignature 0x4C61626C
#define uiMultilineEntrySignature 0x4D6C6E45
#define uiProgressBarSignature 0x50426172
#define uiRadioButtonsSignature 0x5264696F
#define uiSeparatorSignature 0x53657061
#define uiSliderSignature 0x536C6964
#define uiSpinboxSignature 0x5370696E
#define uiTabSignature 0x54616273
#define uiTableSignature 0x5461626C
#define uiWindowSignature 0x57696E64

View File

@ -0,0 +1,21 @@
// 13 may 2016
#include "../ui.h"
#include "uipriv.h"
void _implbug(const char *file, const char *line, const char *func, const char *format, ...)
{
va_list ap;
va_start(ap, format);
realbug(file, line, func, "POSSIBLE IMPLEMENTATION BUG; CONTACT ANDLABS:\n", format, ap);
va_end(ap);
}
void _userbug(const char *file, const char *line, const char *func, const char *format, ...)
{
va_list ap;
va_start(ap, format);
realbug(file, line, func, "You have a bug: ", format, ap);
va_end(ap);
}

View File

@ -0,0 +1,50 @@
// 11 october 2015
#include <math.h>
#include "../ui.h"
#include "uipriv.h"
void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
{
m->M11 = 1;
m->M12 = 0;
m->M21 = 0;
m->M22 = 1;
m->M31 = 0;
m->M32 = 0;
}
// The rest of this file provides basic utilities in case the platform doesn't provide any of its own for these tasks.
// Keep these as minimal as possible. They should generally not call other fallbacks.
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ff684171%28v=vs.85%29.aspx#skew_transform
// TODO see if there's a way we can avoid the multiplication
void fallbackSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
{
uiDrawMatrix n;
uiDrawMatrixSetIdentity(&n);
// TODO explain this
n.M12 = tan(yamount);
n.M21 = tan(xamount);
n.M31 = -y * tan(xamount);
n.M32 = -x * tan(yamount);
uiDrawMatrixMultiply(m, &n);
}
void scaleCenter(double xCenter, double yCenter, double *x, double *y)
{
*x = xCenter - (*x * xCenter);
*y = yCenter - (*y * yCenter);
}
// the basic algorithm is from cairo
// but it's the same algorithm as the transform point, just without M31 and M32 taken into account, so let's just do that instead
void fallbackTransformSize(uiDrawMatrix *m, double *x, double *y)
{
uiDrawMatrix m2;
m2 = *m;
m2.M31 = 0;
m2.M32 = 0;
uiDrawMatrixTransformPoint(&m2, x, y);
}

View File

@ -0,0 +1,22 @@
// 9 may 2015
#include "../ui.h"
#include "uipriv.h"
static int defaultOnShouldQuit(void *data)
{
return 0;
}
static int (*onShouldQuit)(void *) = defaultOnShouldQuit;
static void *onShouldQuitData;
void uiOnShouldQuit(int (*f)(void *), void *data)
{
onShouldQuit = f;
onShouldQuitData = data;
}
int shouldQuit(void)
{
return (*onShouldQuit)(onShouldQuitData);
}

View File

@ -0,0 +1,58 @@
// 6 april 2015
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include "controlsigs.h"
extern uiInitOptions options;
extern void *uiAlloc(size_t, const char *);
#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T))
extern void *uiRealloc(void *, size_t, const char *);
extern void uiFree(void *);
// ugh, this was only introduced in MSVC 2015...
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
extern void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap);
#define _ns2(s) #s
#define _ns(s) _ns2(s)
extern void _implbug(const char *file, const char *line, const char *func, const char *format, ...);
#define implbug(...) _implbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__)
extern void _userbug(const char *file, const char *line, const char *func, const char *format, ...);
#define userbug(...) _userbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__)
// control.c
extern uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr);
// shouldquit.c
extern int shouldQuit(void);
// areaevents.c
typedef struct clickCounter clickCounter;
// you should call Reset() to zero-initialize a new instance
// it doesn't matter that all the non-count fields are zero: the first click will fail the curButton test straightaway, so it'll return 1 and set the rest of the structure accordingly
struct clickCounter {
int curButton;
int rectX0;
int rectY0;
int rectX1;
int rectY1;
uintptr_t prevTime;
int count;
};
int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist);
extern void clickCounterReset(clickCounter *);
extern int fromScancode(uintptr_t, uiAreaKeyEvent *);
// matrix.c
extern void fallbackSkew(uiDrawMatrix *, double, double, double, double);
extern void scaleCenter(double, double, double *, double *);
extern void fallbackTransformSize(uiDrawMatrix *, double *, double *);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,8 @@
// 22 may 2016
#include "../ui.h"
#include "uipriv.h"
void uiUserBugCannotSetParentOnToplevel(const char *type)
{
userbug("You cannot make a %s a child of another uiControl,", type);
}