mirror of
https://gitea.nishi.boats/pyrite-dev/milsko
synced 2025-12-31 06:30:52 +00:00
200 lines
4.3 KiB
C
200 lines
4.3 KiB
C
#include <Mw/Milsko.h>
|
|
|
|
static void vscroll_changed(MwWidget handle, void* user, void* call) {
|
|
MwViewport vp = user;
|
|
|
|
(void)handle;
|
|
(void)call;
|
|
|
|
vp->vchanged = 1;
|
|
}
|
|
|
|
static void hscroll_changed(MwWidget handle, void* user, void* call) {
|
|
MwViewport vp = user;
|
|
|
|
(void)handle;
|
|
(void)call;
|
|
|
|
vp->hchanged = 1;
|
|
}
|
|
|
|
static void resize(MwWidget handle) {
|
|
MwViewport vp = handle->internal;
|
|
int w = MwGetInteger(handle, MwNwidth);
|
|
int h = MwGetInteger(handle, MwNheight);
|
|
int iw;
|
|
int ih;
|
|
if(vp->vscroll == NULL) {
|
|
vp->vscroll = MwVaCreateWidget(MwScrollBarClass, "vscroll", handle, w - 16, 0, 16, h - 16, NULL);
|
|
MwAddUserHandler(vp->vscroll, MwNchangedHandler, vscroll_changed, vp);
|
|
} else {
|
|
MwVaApply(vp->vscroll,
|
|
MwNx, w - 16,
|
|
MwNy, 0,
|
|
MwNwidth, 16,
|
|
MwNheight, h - 16,
|
|
NULL);
|
|
}
|
|
if(vp->hscroll == NULL) {
|
|
vp->hscroll = MwVaCreateWidget(MwScrollBarClass, "hscroll", handle, 0, h - 16, w - 16, 16, MwNorientation, MwHORIZONTAL, NULL);
|
|
MwAddUserHandler(vp->hscroll, MwNchangedHandler, hscroll_changed, vp);
|
|
} else {
|
|
MwVaApply(vp->hscroll,
|
|
MwNx, 0,
|
|
MwNy, h - 16,
|
|
MwNwidth, w - 16,
|
|
MwNheight, 16,
|
|
NULL);
|
|
}
|
|
if(vp->frame == NULL) {
|
|
vp->frame = MwCreateWidget(MwFrameClass, "frame", handle, 0, 0, w - 16, h - 16);
|
|
} else {
|
|
MwVaApply(vp->frame,
|
|
MwNx, 0,
|
|
MwNy, 0,
|
|
MwNwidth, w - 16,
|
|
MwNheight, h - 16,
|
|
NULL);
|
|
}
|
|
if(vp->inframe == NULL) {
|
|
vp->inframe = MwCreateWidget(MwFrameClass, "inframe", vp->frame, 0, 0, w - 16, h - 16);
|
|
}
|
|
|
|
iw = MwGetInteger(vp->inframe, MwNwidth);
|
|
ih = MwGetInteger(vp->inframe, MwNheight);
|
|
|
|
MwVaApply(vp->vscroll,
|
|
MwNareaShown, h - 16,
|
|
MwNmaxValue, ih,
|
|
NULL);
|
|
|
|
MwVaApply(vp->hscroll,
|
|
MwNareaShown, w - 16,
|
|
MwNmaxValue, iw,
|
|
NULL);
|
|
}
|
|
|
|
static int create(MwWidget handle) {
|
|
MwViewport vp = malloc(sizeof(*vp));
|
|
memset(vp, 0, sizeof(*vp));
|
|
|
|
handle->internal = vp;
|
|
|
|
MwSetDefault(handle);
|
|
|
|
vp->vchanged = 0;
|
|
vp->hchanged = 0;
|
|
|
|
resize(handle);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void destroy(MwWidget handle) {
|
|
free(handle->internal);
|
|
}
|
|
|
|
static void draw(MwWidget handle) {
|
|
MwRect r;
|
|
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
|
|
|
|
r.x = 0;
|
|
r.y = 0;
|
|
r.width = MwGetInteger(handle, MwNwidth);
|
|
r.height = MwGetInteger(handle, MwNheight);
|
|
|
|
MwDrawRect(handle, &r, base);
|
|
|
|
MwLLFreeColor(base);
|
|
}
|
|
|
|
static void prop_change(MwWidget handle, const char* prop) {
|
|
if(strcmp(prop, MwNwidth) == 0 || strcmp(prop, MwNheight) == 0) resize(handle);
|
|
}
|
|
|
|
static MwWidget mwViewportGetViewportImpl(MwWidget handle) {
|
|
MwViewport vp = handle->internal;
|
|
|
|
return vp->inframe;
|
|
}
|
|
|
|
static void mwViewportSetSizeImpl(MwWidget handle, int w, int h) {
|
|
MwViewport vp = handle->internal;
|
|
|
|
MwVaApply(vp->inframe,
|
|
MwNwidth, w,
|
|
MwNheight, h,
|
|
NULL);
|
|
|
|
resize(handle);
|
|
}
|
|
|
|
static void func_handler(MwWidget handle, const char* name, void* out, va_list va) {
|
|
if(strcmp(name, "mwViewportGetViewport") == 0) {
|
|
*(MwWidget*)out = mwViewportGetViewportImpl(handle);
|
|
}
|
|
if(strcmp(name, "mwViewportSetSize") == 0) {
|
|
int w = va_arg(va, int);
|
|
int h = va_arg(va, int);
|
|
mwViewportSetSizeImpl(handle, w, h);
|
|
}
|
|
}
|
|
|
|
static void tick(MwWidget handle) {
|
|
MwViewport vp = handle->internal;
|
|
|
|
if(vp->vchanged) {
|
|
int v, mv, l;
|
|
|
|
vp->vchanged = 0;
|
|
|
|
v = MwGetInteger(vp->vscroll, MwNvalue);
|
|
mv = MwGetInteger(vp->vscroll, MwNmaxValue);
|
|
l = MwGetInteger(vp->frame, MwNheight);
|
|
v = (mv - l) * (double)v / mv;
|
|
|
|
if(v < 0) v = 0;
|
|
MwVaApply(vp->inframe,
|
|
MwNy, -v,
|
|
NULL);
|
|
}
|
|
if(vp->hchanged) {
|
|
int v, mv, l;
|
|
|
|
vp->vchanged = 0;
|
|
|
|
v = MwGetInteger(vp->hscroll, MwNvalue);
|
|
mv = MwGetInteger(vp->hscroll, MwNmaxValue);
|
|
l = MwGetInteger(vp->frame, MwNwidth);
|
|
v = (mv - l) * (double)v / mv;
|
|
|
|
if(v < 0) v = 0;
|
|
MwVaApply(vp->inframe,
|
|
MwNx, -v,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
MwClassRec MwViewportClassRec = {
|
|
create, /* create */
|
|
destroy, /* destroy */
|
|
draw, /* draw */
|
|
NULL, /* click */
|
|
NULL, /* parent_resize */
|
|
prop_change, /* prop_change */
|
|
NULL, /* mouse_move */
|
|
NULL, /* mouse_up */
|
|
NULL, /* mouse_down */
|
|
NULL, /* key */
|
|
func_handler, /* execute */
|
|
tick, /* tick */
|
|
NULL, /* resize */
|
|
NULL, /* children_update */
|
|
NULL, /* children_prop_change */
|
|
NULL, /* clipboard */
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL};
|
|
MwClass MwViewportClass = &MwViewportClassRec;
|