mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-04 21:50:38 -04:00
1005 lines
20 KiB
C
1005 lines
20 KiB
C
#include <platform/platform.h>
|
|
//Gui system - object system + graphic
|
|
#include "types.h"
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include "memman.h"
|
|
#include "event.h"
|
|
#include "devices.h"
|
|
#include "bmouse.h"
|
|
#include "bgraph.h"
|
|
#include "gui.h"
|
|
|
|
#include <string.h>
|
|
#define E_REDRAW_DESKTOP 2010
|
|
#define E_REDRAW_WINDOW 2000
|
|
|
|
void *gui_background=NULL;
|
|
|
|
extern T_EVENT_ROOT *ev_tree;
|
|
|
|
WINDOW *desktop={NULL},*waktual={NULL};;
|
|
OBJREC *o_aktual={NULL},*o_end={NULL},*o_start={NULL};
|
|
CTL3D noneborder={0,0,0,0};
|
|
FC_TABLE f_default;
|
|
word desktop_y_size;
|
|
char force_redraw_desktop=0;
|
|
static char change_flag=0,f_cancel_event=0;
|
|
const word *default_font;
|
|
void empty(void)
|
|
{
|
|
}
|
|
|
|
|
|
void empty1(OBJREC *o)
|
|
{
|
|
o;
|
|
}
|
|
|
|
void empty2_p(OBJREC *o, va_list _)
|
|
{
|
|
o;
|
|
}
|
|
|
|
void empty3(EVENT_MSG *ms,OBJREC *o)
|
|
{
|
|
o;ms;
|
|
}
|
|
|
|
|
|
void empty2(int x1,int y1,int x2,int y2,OBJREC *o)
|
|
{
|
|
o;x1;y1;x2;y2;
|
|
}
|
|
|
|
|
|
|
|
void draw_border(integer x,integer y,integer xs,integer ys,CTL3D *btype)
|
|
{
|
|
word i,j,c;
|
|
|
|
c=curcolor;
|
|
j=btype->ctldef;
|
|
for (i=0;i<btype->bsize;i++)
|
|
{
|
|
x--;y--;xs+=2;ys+=2;
|
|
if (j & 1) curcolor=btype->shadow; else curcolor=btype->light;
|
|
hor_line32(x,y,xs+x);
|
|
ver_line32(x,y,ys+y);
|
|
if (j & 1) curcolor=btype->light; else curcolor=btype->shadow;
|
|
hor_line32(x,y+ys,xs+x);
|
|
ver_line32(x+xs,y,ys+y);
|
|
j>>=1;
|
|
}
|
|
curcolor=c;
|
|
}
|
|
void check_window(WINDOW *w)
|
|
{
|
|
if (w->x<=w->border3d.bsize) w->x=w->border3d.bsize;
|
|
if (w->y<=w->border3d.bsize) w->y=w->border3d.bsize;
|
|
if (w->x>=SCR_WIDTH_X-w->border3d.bsize-w->xs) w->x=SCR_WIDTH_X-w->border3d.bsize-w->xs-1;
|
|
if (w->y>=desktop_y_size-w->border3d.bsize-w->ys) w->y=desktop_y_size-w->border3d.bsize-w->ys-1;
|
|
}
|
|
|
|
void show_window(WINDOW *w)
|
|
{
|
|
int ok;
|
|
|
|
ok=w->border3d.bsize;
|
|
showview(w->x-ok,w->y-ok,w->xs+(ok<<1),w->ys+(ok<<1));
|
|
}
|
|
|
|
void draw_cl_window(WINDOW *o)
|
|
{
|
|
curcolor=o->color;
|
|
bar32(o->x,o->y,o->x+o->xs,o->y+o->ys);
|
|
draw_border(o->x,o->y,o->xs,o->ys,&o->border3d);
|
|
}
|
|
|
|
|
|
|
|
WINDOW *create_window(int x,int y, int xs, int ys, word color, CTL3D *okraj)
|
|
{
|
|
WINDOW *p;
|
|
|
|
p=(WINDOW *)getmem(sizeof(WINDOW));
|
|
p->x=x;p->y=y;p->xs=xs;p->ys=ys;
|
|
p->color=color;memcpy(&(p->border3d),okraj,sizeof(CTL3D));
|
|
p->objects=NULL;
|
|
p->modal=0;
|
|
p->popup=0;
|
|
p->minimized=0;
|
|
p->window_name=NULL;
|
|
p->minsizx=MINSIZX;
|
|
p->minsizy=MINSIZY;
|
|
p->idlist=NULL;
|
|
p->draw_event=draw_cl_window;
|
|
check_window(p);
|
|
return p;
|
|
}
|
|
|
|
int send_lost()
|
|
{
|
|
EVENT_MSG msg;
|
|
msg.msg=E_LOST_FOCUS;
|
|
if (o_aktual!=NULL)
|
|
{
|
|
o_aktual->on_exit();
|
|
if (f_cancel_event) return -1;
|
|
o_aktual->call_event(&msg,o_aktual);
|
|
o_aktual=NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void select_window(int32_t id)
|
|
{
|
|
WINDOW *p,*q;
|
|
|
|
if (waktual->id==id) return;
|
|
if (waktual->modal) return;
|
|
if (send_lost()) return;
|
|
p=desktop;
|
|
while (p!=NULL && p->id!=id) p=p->next;
|
|
if (p==NULL) return;
|
|
q=desktop;
|
|
if (p!=desktop)
|
|
{
|
|
while (q->next!=p) q=q->next;
|
|
q->next=p->next;
|
|
}
|
|
else
|
|
{
|
|
desktop=p->next;
|
|
}
|
|
p->next=NULL;
|
|
waktual->next=p;
|
|
waktual=p;
|
|
if (waktual->objects!=NULL)
|
|
{
|
|
o_start=waktual->objects;
|
|
o_aktual=NULL;
|
|
o_end=o_start;
|
|
while(o_end->next!=NULL) o_end=o_end->next;
|
|
}
|
|
else
|
|
{o_start=NULL;o_aktual=NULL;o_end=NULL;}
|
|
|
|
}
|
|
|
|
int32_t desktop_add_window(WINDOW *w)
|
|
{
|
|
static int32_t id_counter=0;
|
|
|
|
w->id=id_counter++;
|
|
w->next=NULL;
|
|
if (desktop==NULL)
|
|
{
|
|
waktual=w;
|
|
desktop=w;
|
|
}
|
|
else
|
|
{
|
|
if (o_aktual!=NULL)
|
|
{
|
|
EVENT_MSG msg;
|
|
|
|
msg.msg=E_LOST_FOCUS;
|
|
o_aktual->on_exit();
|
|
o_aktual->call_event(&msg,o_aktual);
|
|
}
|
|
waktual->next=w;
|
|
waktual=w;
|
|
}
|
|
o_aktual=NULL;
|
|
o_end=NULL;
|
|
o_start=NULL;
|
|
return w->id;
|
|
}
|
|
|
|
|
|
WINDOW *find_window(int32_t id)
|
|
{
|
|
WINDOW *p;
|
|
|
|
p=desktop;
|
|
while (p!=NULL && p->id!=id) p=p->next;
|
|
return p;
|
|
}
|
|
|
|
|
|
|
|
void absolute_window(WINDOW *w,OBJREC *o, int *x, int *y)
|
|
{
|
|
switch (o->align)
|
|
{
|
|
case 0:
|
|
case 1:*y=o->y+w->y;break;
|
|
case 2:
|
|
case 3:*y=(w->y+w->ys)-(o->y+o->ys);break;
|
|
}
|
|
switch (o->align)
|
|
{
|
|
case 0:
|
|
case 3:*x=o->x+w->x;break;
|
|
case 1:
|
|
case 2:*x=(w->x+w->xs)-(o->x+o->xs);break;
|
|
}
|
|
}
|
|
|
|
void disable_bar(int x,int y,int xs,int ys,word color)
|
|
{
|
|
int i,j;
|
|
word *a;
|
|
int32_t scr_linelen2 = GetScreenPitch();
|
|
|
|
for (i=y;i<=y+ys;i++)
|
|
{
|
|
a=GetScreenAdr()+scr_linelen2*i+x;
|
|
for(j=x;j<=x+xs;j++)
|
|
{
|
|
*a=((*a & RGB555(30,30,30))+(color & RGB555(30,30,30)))>>1;
|
|
*a=((*a & RGB555(30,30,30))+(color & RGB555(30,30,30)))>>1;
|
|
a++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void draw_object(WINDOW *w,OBJREC *o,char show)
|
|
{
|
|
int x = 0, y = 0;
|
|
int ok;
|
|
// WINDOW *ws;
|
|
|
|
if (o->draw_error==1) return;
|
|
o->draw_error=1;
|
|
ok=w->border3d.bsize;
|
|
absolute_window(w,o,&x,&y);
|
|
o->locx=x;o->locy=y;
|
|
if (o->xs<1 || o->ys<1)
|
|
{
|
|
o->draw_error=0;
|
|
return;
|
|
}
|
|
schovej_mysku();
|
|
draw_border(x,y,o->xs,o->ys,&o->border3d);
|
|
curcolor=o->color;
|
|
curfont=o->font;position(x,y);
|
|
memcpy(&charcolors,&o->f_color,sizeof(charcolors));
|
|
// ws=waktual;
|
|
// waktual=w;
|
|
o->call_draw(x,y,x+o->xs,y+o->ys,o);
|
|
// waktual=ws;
|
|
if (!o->enabled) disable_bar(x,y,o->xs,o->ys,o->color);
|
|
ukaz_mysku();
|
|
if (show) showview(x-ok,y-ok,o->xs+(ok<<1),o->ys+(ok<<1));
|
|
o->draw_error=0;
|
|
}
|
|
|
|
|
|
void redraw_object(OBJREC *o)
|
|
{
|
|
draw_object(waktual,o,1);
|
|
}
|
|
|
|
|
|
void redraw_window_call()
|
|
{
|
|
OBJREC *p;
|
|
|
|
schovej_mysku();
|
|
waktual->draw_event(waktual);
|
|
p=waktual->objects;
|
|
while (p!=NULL)
|
|
{
|
|
draw_object(waktual,p,0);
|
|
p=p->next;
|
|
}
|
|
ukaz_mysku();
|
|
show_window(waktual);
|
|
return;
|
|
}
|
|
|
|
void add_to_idlist(OBJREC *o)
|
|
{
|
|
TIDLIST *p,*q;
|
|
|
|
p=(TIDLIST *)getmem(sizeof(TIDLIST));
|
|
p->obj=o;
|
|
if (waktual->idlist==NULL)
|
|
{
|
|
p->next=NULL;
|
|
waktual->idlist=p;
|
|
return;
|
|
}
|
|
if (((waktual->idlist)->obj)->id>o->id)
|
|
{
|
|
p->next=waktual->idlist;
|
|
waktual->idlist=p;
|
|
return;
|
|
}
|
|
q=waktual->idlist;
|
|
while (q->next!=NULL && ((q->next)->obj)->id<o->id) q=q->next;
|
|
p->next=q->next;
|
|
q->next=p;
|
|
}
|
|
|
|
|
|
void define(int id,int x,int y,int xs,int ys,char align,void (*initproc)(OBJREC *),...)
|
|
{
|
|
OBJREC *o;
|
|
|
|
|
|
o=(OBJREC *)getmem(sizeof(OBJREC));
|
|
o->x=x;o->y=y;o->xs=xs;o->ys=ys;
|
|
o->id=id;
|
|
o->call_init=empty2_p;
|
|
o->call_draw=empty2;
|
|
o->call_event=empty3;
|
|
o->call_done=empty1;
|
|
o->autoresizex=0;
|
|
o->autoresizey=0;
|
|
o->on_event=empty3;
|
|
o->on_enter=empty;
|
|
o->on_exit=empty;
|
|
o->on_change=empty;
|
|
o->enabled=1;
|
|
o->draw_error=0;
|
|
o->color=waktual->color;memcpy(o->f_color,f_default,sizeof(f_default));
|
|
memcpy(&(o->border3d),&noneborder,sizeof(CTL3D));
|
|
o->userptr=NULL;
|
|
o->align=align;
|
|
o->font=default_font;
|
|
o->datasize=0;
|
|
initproc(o);
|
|
if (o->datasize) {
|
|
o->data=(void *)getmem(o->datasize);
|
|
memset(o->data,0,o->datasize);
|
|
}else {
|
|
o->data=NULL;
|
|
}
|
|
va_list vlst;
|
|
va_start(vlst, initproc);
|
|
o->call_init(o,vlst);
|
|
va_end(vlst);
|
|
if (o->datasize && o->data==NULL) {
|
|
o->data=(void *)getmem(o->datasize);
|
|
memset(o->data,0,o->datasize);
|
|
}
|
|
o->next=NULL;
|
|
if (o_start==NULL)
|
|
{
|
|
o_start=o;
|
|
o_end=o;
|
|
o_aktual=NULL;
|
|
waktual->objects=o;
|
|
}
|
|
else
|
|
{
|
|
o_end->next=o;
|
|
o_end=o;
|
|
}
|
|
add_to_idlist(o);
|
|
}
|
|
|
|
CTL3D *border(word light,word shadow, word bsize, word btype)
|
|
{
|
|
static CTL3D p;
|
|
|
|
p.light=light;p.shadow=shadow;p.bsize=bsize;p.ctldef=btype;
|
|
return &p;
|
|
}
|
|
|
|
void property(CTL3D *ctl,const word *font,FC_TABLE *fcolor,word color)
|
|
{
|
|
if (ctl!=NULL) memcpy(&o_end->border3d,ctl,sizeof(CTL3D));
|
|
if (font!=NULL) o_end->font=font;
|
|
if (fcolor!=NULL) memcpy(&o_end->f_color,fcolor,sizeof(FC_TABLE));
|
|
if (color!=0xffff) o_end->color=color;
|
|
}
|
|
|
|
FC_TABLE *flat_color(word color)
|
|
{
|
|
static FC_TABLE p;
|
|
|
|
p[0]=0xffff;
|
|
p[1]=color;p[2]=color;p[3]=color;p[4]=color;p[5]=color;p[6]=color;
|
|
return &p;
|
|
}
|
|
|
|
|
|
void aktivate_window(MS_EVENT *ms)
|
|
{
|
|
WINDOW *p,*q;
|
|
if (ms->event_type==1) return;
|
|
p=desktop;q=NULL;
|
|
while (p!=NULL)
|
|
{
|
|
if (ms->x>=p->x && ms->x<=p->x+p->xs && ms->y>=p->y && ms->y<=p->y+p->ys)
|
|
q=p;
|
|
p=p->next;
|
|
}
|
|
if (q==NULL) return;
|
|
if (q!=waktual)
|
|
{
|
|
select_window(q->id);
|
|
redraw_window();
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
void redraw_desktop_call(EVENT_MSG *msg,void **data)
|
|
{
|
|
WINDOW *w;
|
|
char *oz;
|
|
|
|
data;
|
|
if (msg->msg==E_INIT || msg->msg==E_DONE) return;
|
|
if (!force_redraw_desktop) return;
|
|
force_redraw_desktop=0;
|
|
schovej_mysku();
|
|
if (gui_background==NULL)
|
|
{
|
|
curcolor=DESK_TOP_COLOR;
|
|
bar32(0,0,SCR_WIDTH_X,SCR_WIDTH_Y-1);
|
|
}
|
|
else
|
|
put_picture(0,0,gui_background);
|
|
oz=otevri_zavoru;
|
|
do_events();
|
|
*oz=1;
|
|
w=desktop;
|
|
while (w!=NULL)
|
|
{
|
|
OBJREC *p;
|
|
w->draw_event(w);
|
|
p=w->objects;
|
|
while (p!=NULL)
|
|
{
|
|
draw_object(w,p,0);
|
|
p=p->next;
|
|
}
|
|
w=w->next;
|
|
*oz=0;
|
|
do_events();
|
|
*oz=1;
|
|
}
|
|
send_message(E_REDRAW);
|
|
ukaz_mysku();
|
|
showview(0,0,0,0);
|
|
move_ms_cursor(0,0,1);
|
|
}
|
|
|
|
void redraw_desktop()
|
|
{
|
|
force_redraw_desktop=1;
|
|
}
|
|
|
|
void redraw_window()
|
|
{
|
|
redraw_window_call();
|
|
}
|
|
|
|
void close_window(WINDOW *w)
|
|
{
|
|
WINDOW *p;
|
|
OBJREC *q;
|
|
|
|
if (waktual==w && send_lost()) return;
|
|
if (w==waktual && waktual!=desktop)
|
|
{
|
|
p=desktop;
|
|
while (p->next!=waktual) p=p->next;
|
|
w->modal=0;
|
|
select_window(p->id);
|
|
}
|
|
if (w!=desktop)
|
|
{
|
|
p=desktop;
|
|
while (p->next!=w) p=p->next;
|
|
p->next=w->next;
|
|
}
|
|
else
|
|
{
|
|
desktop=w->next;
|
|
if (desktop==NULL) waktual=NULL;
|
|
}
|
|
while (w->objects!=NULL)
|
|
{
|
|
q=w->objects;
|
|
w->objects=q->next;
|
|
q->call_done(q);
|
|
if (q->userptr!=NULL) free(q->userptr);
|
|
if (q->data!=NULL) free(q->data);
|
|
free(q);
|
|
}
|
|
while (w->idlist!=NULL)
|
|
{
|
|
TIDLIST *p;
|
|
|
|
p=w->idlist;
|
|
w->idlist=p->next;
|
|
free(p);
|
|
}
|
|
|
|
free(w);
|
|
if (desktop==NULL) exit_wait=1;
|
|
redraw_desktop();
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------- GUI EVENTS -------------------------
|
|
|
|
char mouse_in_object(MS_EVENT *ms,OBJREC *o, WINDOW *w)
|
|
{
|
|
int x1=0, y1=0, x2=0, y2=0;
|
|
|
|
absolute_window(w,o,&x1,&y1);
|
|
x2=x1+o->xs;
|
|
y2=y1+o->ys;
|
|
if (ms->x>=x1 && ms->x<=x2 && ms->y>=y1 && ms->y<=y2)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
OBJREC *get_last_id()
|
|
{
|
|
TIDLIST *p;
|
|
|
|
p=waktual->idlist;
|
|
while (p->next!=NULL) p=p->next;
|
|
return p->obj;
|
|
}
|
|
|
|
OBJREC *get_next_id(OBJREC *o)
|
|
{
|
|
TIDLIST *p;
|
|
|
|
p=waktual->idlist;
|
|
while (p!=NULL && p->obj!=o) p=p->next;
|
|
if (p==NULL) return NULL;
|
|
do
|
|
{
|
|
|
|
p=p->next;
|
|
if (p==NULL) p=waktual->idlist;
|
|
o=p->obj;
|
|
if (o->enabled && o->call_event!=empty3) return o;
|
|
}
|
|
while (1);
|
|
}
|
|
|
|
OBJREC *get_prev_id(OBJREC *o)
|
|
{
|
|
TIDLIST *p,*q;
|
|
|
|
p=waktual->idlist;
|
|
while (p!=NULL && p->obj!=o) p=p->next;
|
|
if (p==NULL) return NULL;
|
|
do
|
|
{
|
|
if (p==waktual->idlist)
|
|
{
|
|
p=waktual->idlist;
|
|
while (p->next!=NULL) p=p->next;
|
|
}
|
|
else
|
|
{
|
|
q=waktual->idlist;
|
|
while (q->next!=p) q=q->next;
|
|
p=q;
|
|
}
|
|
o=p->obj;
|
|
if (o->enabled && o->call_event!=empty3) return o;
|
|
}
|
|
while (1);
|
|
}
|
|
|
|
|
|
void do_it_events(EVENT_MSG *msg,void **user_data)
|
|
{
|
|
MS_EVENT *msev;
|
|
EVENT_MSG msg2;
|
|
char b;
|
|
static word cursor_tick=CURSOR_SPEED
|
|
OBJREC *p;
|
|
char *oz=otevri_zavoru;
|
|
|
|
user_data;
|
|
if (msg->msg==E_INIT) return;
|
|
if (desktop==NULL) {exit_wait=1;return;}
|
|
change_flag=0;f_cancel_event=0;
|
|
if (o_aktual!=NULL) {
|
|
EVENT_MSG mcpy = clone_message(msg);
|
|
o_aktual->on_event(&mcpy,o_aktual);
|
|
destroy_message(&mcpy);
|
|
}
|
|
if (msg->msg==E_MOUSE)
|
|
{
|
|
*oz=1;
|
|
EVENT_MSG fwmsg = clone_message(msg);
|
|
fwmsg.msg = msg->msg;
|
|
va_copy(fwmsg.data, msg->data);
|
|
msev=get_mouse(msg);
|
|
aktivate_window(msev);
|
|
if (o_aktual == NULL) {
|
|
if (o_start != NULL && (msev->tl1 || msev->tl2 || msev->tl3)) {
|
|
o_aktual = o_start;
|
|
while (o_aktual != NULL
|
|
&& (!o_aktual->enabled
|
|
|| !mouse_in_object(msev, o_aktual, waktual)
|
|
|| o_aktual->call_event == empty3))
|
|
o_aktual = o_aktual->next;
|
|
if (o_aktual != NULL) {
|
|
msg2.msg = E_GET_FOCUS;
|
|
o_aktual->call_event(&msg2, o_aktual);
|
|
o_aktual->on_enter();
|
|
o_aktual->call_event(&fwmsg, o_aktual);
|
|
}
|
|
}
|
|
} else {
|
|
if (o_aktual->enabled) {
|
|
b = mouse_in_object(msev, o_aktual, waktual);
|
|
} else {
|
|
b = 0;
|
|
}
|
|
if (b) {
|
|
o_aktual->call_event(&fwmsg, o_aktual);
|
|
}
|
|
if ((msev->tl1 || msev->tl2 || msev->tl3) && !b) {
|
|
o_aktual->on_exit();
|
|
if (f_cancel_event)
|
|
return;
|
|
msg2.msg = E_LOST_FOCUS;
|
|
o_aktual->call_event(&msg2, o_aktual);
|
|
p = o_start;
|
|
while (p != NULL
|
|
&& (!p->enabled || !mouse_in_object(msev, p, waktual)
|
|
|| p->call_event == empty3))
|
|
p = p->next;
|
|
if (p != NULL) {
|
|
o_aktual = p;
|
|
}
|
|
msg2.msg = E_GET_FOCUS;
|
|
o_aktual->call_event(&msg2, o_aktual);
|
|
o_aktual->on_enter();
|
|
if (p != NULL)
|
|
o_aktual->call_event(&fwmsg, o_aktual);
|
|
}
|
|
}
|
|
destroy_message(&fwmsg);
|
|
}
|
|
if (msg->msg==E_KEYBOARD)
|
|
{
|
|
*oz=1;
|
|
EVENT_MSG cmsg = clone_message(msg);
|
|
if (o_aktual!=NULL)
|
|
{
|
|
o_aktual->call_event(msg,o_aktual);
|
|
}
|
|
int code = va_arg(cmsg.data, int);
|
|
destroy_message(&cmsg);
|
|
if ((code>>8)==0xf && waktual->idlist!=NULL)
|
|
{
|
|
if (o_aktual==NULL) o_aktual=get_last_id();
|
|
if (o_aktual!=NULL)
|
|
{
|
|
f_cancel_event=0;
|
|
o_aktual->on_exit();
|
|
if (f_cancel_event) return;
|
|
msg2.msg=E_LOST_FOCUS;
|
|
o_aktual->call_event(&msg2,o_aktual);
|
|
}
|
|
if((code & 0xff)==9) o_aktual=get_next_id(o_aktual);
|
|
else o_aktual=get_prev_id(o_aktual);
|
|
if (o_aktual!=NULL)
|
|
{
|
|
msg2.msg=E_GET_FOCUS;
|
|
o_aktual->call_event(&msg2,o_aktual);
|
|
o_aktual->on_enter();
|
|
}
|
|
}
|
|
}
|
|
if (msg->msg==E_TIMER && o_aktual!=NULL)
|
|
{
|
|
o_aktual->call_event(msg,o_aktual);
|
|
if (!(cursor_tick--))
|
|
{
|
|
msg->msg=E_CURSOR_TICK;
|
|
o_aktual->call_event(msg,o_aktual);
|
|
o_aktual->on_event(msg,o_aktual);
|
|
cursor_tick=CURSOR_SPEED;
|
|
}
|
|
}
|
|
if (msg->msg==E_GUI)
|
|
{
|
|
OBJREC *o;
|
|
|
|
EVENT_MSG msg2 = clone_message(msg);
|
|
|
|
int control = va_arg(msg->data, int);
|
|
msg->msg = va_arg(msg->data, int);
|
|
o=find_object(waktual,control);
|
|
|
|
|
|
|
|
if (o!=NULL)
|
|
{
|
|
EVENT_MSG msg3 = clone_message(msg);
|
|
o->call_event(&msg2,o);
|
|
o->on_event(&msg3,o_aktual);
|
|
destroy_message(&msg3);
|
|
}
|
|
destroy_message(&msg2);
|
|
|
|
}
|
|
if (msg->msg==E_CHANGE)
|
|
run_background(o_aktual->on_change);
|
|
if (change_flag) send_message(E_CHANGE);
|
|
}
|
|
|
|
|
|
|
|
|
|
void install_gui(void)
|
|
{
|
|
desktop_y_size = SCR_WIDTH_Y;
|
|
send_message(E_ADD,E_MOUSE,do_it_events);
|
|
send_message(E_ADD,E_KEYBOARD,do_it_events);
|
|
send_message(E_ADD,E_CHANGE,do_it_events);
|
|
send_message(E_ADD,E_TIMER,do_it_events);
|
|
send_message(E_ADD,E_GUI,do_it_events);
|
|
send_message(E_ADD,E_IDLE,redraw_desktop_call);
|
|
}
|
|
|
|
void uninstall_gui(void)
|
|
{
|
|
send_message(E_DONE,E_MOUSE,do_it_events);
|
|
send_message(E_DONE,E_KEYBOARD,do_it_events);
|
|
send_message(E_DONE,E_CHANGE,do_it_events);
|
|
send_message(E_DONE,E_TIMER,do_it_events);
|
|
send_message(E_DONE,E_GUI,do_it_events);
|
|
send_message(E_DONE,E_IDLE,redraw_desktop_call);
|
|
}
|
|
|
|
//send_message(E_GUI,cislo,E_UDALOST,data....)
|
|
|
|
|
|
void on_control_change(void (*proc)(void))
|
|
{
|
|
o_end->on_change=proc;
|
|
}
|
|
|
|
void on_control_enter(void (*proc)(void))
|
|
{
|
|
o_end->on_enter=proc;
|
|
}
|
|
void on_control_exit(void (*proc)(void))
|
|
{
|
|
o_end->on_exit=proc;
|
|
}
|
|
void on_control_event(void (*proc)(EVENT_MSG *msg, struct objrec *))
|
|
{
|
|
o_end->on_event=proc;
|
|
}
|
|
void terminate_gui(void)
|
|
{
|
|
exit_wait=1;
|
|
}
|
|
void set_change(void)
|
|
{
|
|
change_flag=1;
|
|
}
|
|
|
|
void set_window_modal(void)
|
|
{
|
|
waktual->modal=1;
|
|
}
|
|
|
|
static void set_object_value(char redraw,OBJREC *o,const char *value)
|
|
{
|
|
if (strncmp(o->data, value, o->datasize))
|
|
{
|
|
strcopy_n(o->data,value,o->datasize);
|
|
if (redraw) redraw_object(o);
|
|
}
|
|
}
|
|
|
|
static void set_object_value_bin(char redraw,OBJREC *o,const void *value, size_t sz)
|
|
{
|
|
size_t cpsz = MIN((size_t)o->datasize, sz);
|
|
if (memcmp(o->data,value,cpsz))
|
|
{
|
|
memcpy(o->data,value,cpsz);
|
|
if (redraw) redraw_object(o);
|
|
}
|
|
}
|
|
|
|
OBJREC *find_object(WINDOW *w,int id)
|
|
{
|
|
OBJREC *p;
|
|
|
|
p=w->objects;
|
|
if (p==NULL) return NULL;
|
|
while (p!=NULL && p->id!=id) p=p->next;
|
|
return p;
|
|
}
|
|
|
|
OBJREC *find_object_desktop(int win_id,int obj_id,WINDOW **wi)
|
|
{
|
|
WINDOW *w;
|
|
OBJREC *o;
|
|
|
|
if (win_id<0) return NULL;
|
|
if (win_id==0) w=waktual;
|
|
else
|
|
w=find_window(win_id);
|
|
if (w==NULL) return NULL;
|
|
o=find_object(w,obj_id);
|
|
*wi=w;
|
|
return o;
|
|
}
|
|
void set_value(int win_id,int obj_id,void *value)
|
|
{
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
|
|
set_object_value((w==waktual),o,value);
|
|
}
|
|
|
|
void set_value_bin(int win_id,int obj_id,void *value, size_t value_size) {
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
|
|
set_object_value_bin((w==waktual),o,value, value_size);
|
|
|
|
}
|
|
|
|
void set_default(const char *value)
|
|
{
|
|
set_object_value(0,o_end,value);
|
|
}
|
|
|
|
void set_default_bin(const void *value, size_t value_size) {
|
|
set_object_value_bin(0, o_end, value, value_size);
|
|
}
|
|
|
|
void goto_control(int obj_id)
|
|
{
|
|
EVENT_MSG msg;
|
|
if (send_lost()) return;
|
|
|
|
OBJREC *x = find_object(waktual,obj_id);
|
|
if (x == NULL) return;
|
|
o_aktual=x;
|
|
msg.msg=E_GET_FOCUS;
|
|
o_aktual->on_event(&msg,o_aktual);
|
|
o_aktual->call_event(&msg,o_aktual);
|
|
}
|
|
|
|
void c_set_value(int win_id,int obj_id,int cnst)
|
|
{
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
|
|
set_object_value_bin((w==waktual),o,&cnst,sizeof(cnst));
|
|
}
|
|
|
|
void c_default(int cnst)
|
|
{
|
|
set_object_value_bin(0,o_end,&cnst,sizeof(cnst));
|
|
}
|
|
|
|
|
|
|
|
int f_get_value(int win_id,int obj_id)
|
|
{
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
int v;
|
|
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL) return 0;
|
|
memcpy(&v,o->data,o->datasize);
|
|
return v;
|
|
}
|
|
|
|
void get_value(int win_id,int obj_id,void *buff)
|
|
{
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL)return;
|
|
memcpy(buff,o->data,o->datasize);
|
|
}
|
|
|
|
void cancel_event()
|
|
{
|
|
f_cancel_event=1;
|
|
}
|
|
|
|
void set_enable(int win_id,int obj_id,int condition)
|
|
{
|
|
OBJREC *o;
|
|
WINDOW *w;
|
|
|
|
condition=(condition!=0);
|
|
if ((o=find_object_desktop(win_id,obj_id,&w))==NULL) return;
|
|
if (o==o_aktual) {
|
|
if (send_lost()) return;
|
|
} else {
|
|
o_aktual=NULL;
|
|
}
|
|
if (o->enabled!=condition)
|
|
{
|
|
o->enabled=condition;
|
|
if (w==waktual) redraw_object(o);
|
|
}
|
|
}
|
|
|
|
void close_current()
|
|
{
|
|
close_window(waktual);
|
|
}
|
|
|
|
typedef void (*PROG)(void);
|
|
|
|
void background_runner(EVENT_MSG *msg,void **prog)
|
|
{
|
|
PROG *prog_ptr = (PROG *)(prog);
|
|
|
|
|
|
if (msg->msg==E_INIT)
|
|
{
|
|
*prog_ptr = va_arg(msg->data, PROG);
|
|
return;
|
|
}
|
|
if (msg->msg==E_DONE)
|
|
{
|
|
*prog_ptr=NULL;
|
|
return;
|
|
}
|
|
|
|
(*prog_ptr)();
|
|
|
|
msg->msg=-2;
|
|
}
|
|
|
|
void run_background(PROG p)
|
|
{
|
|
send_message(E_ADD,E_IDLE,background_runner,p);
|
|
}
|
|
|
|
void movesize_win(WINDOW *w, int newx,int newy, int newxs, int newys)
|
|
{
|
|
int xsdif,ysdif;
|
|
OBJREC *p;
|
|
|
|
|
|
if (newxs<w->minsizx) newxs=w->minsizx;
|
|
if (newys<w->minsizy) newys=w->minsizy;
|
|
if (newxs>=(SCR_WIDTH_X-2*w->border3d.bsize)) newxs=(SCR_WIDTH_X-2*w->border3d.bsize)-1;
|
|
if (newys+2>=(desktop_y_size-2*w->border3d.bsize)) newys=(desktop_y_size-2*w->border3d.bsize)-2;
|
|
xsdif=newxs-w->xs;
|
|
ysdif=newys-w->ys;
|
|
p=w->objects;
|
|
while (p!=NULL)
|
|
{
|
|
if (p->autoresizex) p->xs+=xsdif;
|
|
if (p->autoresizey) p->ys+=ysdif;
|
|
p=p->next;
|
|
}
|
|
w->x=newx;
|
|
w->y=newy;
|
|
w->xs=newxs;
|
|
w->ys=newys;
|
|
check_window(w);
|
|
}
|
|
|