001 #ifndef UI_HH
002 #define UI_HH "Pressin B"
003 #include "GarbageCollector";
004 #include "Set.HC";
005 #include "Primtives3D";
006 class CUIElem {
007 //x,y are relative to last element
008 F64 x,y,w,h;
009 F64 x2,y2,w2,h2;
010 U0 (*draw_it)(CUIElem *self,CDC *dc);
011 Bool (*event_cb)(CUIElem *who,I64 type,I64 x,I64 y);
012 CI64Set *sub_elems;
013 Bool invisible,no_occupy_space,pad[6];
014 U8 *user_data;
015 };
016 class CUIButton:CUIElem {
017 U8 *text;
018 I64 bg_color,fg_color;
019 I64 border_color;
020 U0 (*cb)(CUIButton *btn);
021 };
022 class CUITree:CUIButton {
023 Bool open;
024 };
025
026 class CUIBigText:CUIElem {
027 I64 color;
028 U8 *text;
029 F64 scale;
030 };
031
032 class CUIText:CUIElem {
033 I64 color;
034 U8 *text;
035
036 };
037
038 class CUIRoot:CUIElem {
039 };
040
041
042 class CUIGrid:CUIElem {
043 I64 rows,cols;
044 I64 active_row,active_col;
045 CI64Set *items;//CUIGridItem
046 //Private,used for draging
047 I64 ms_down_at_x,ms_down_at_y;
048 }
049 class CUIGridItem {
050 I64 row,col;
051 U8 *sprite;
052 I64 ammo;
053 U0 (*cb)(CUIGridItem *);
054 U8 *user_data;
055 //Private
056 I64 x,y;
057 CUIGrid *parent;
058 };
059 CUIGridItem *UIGridItemNew(U8 *icon) {
060 CUIGridItem *item=GCCAlloc(sizeof CUIGridItem);
061 item->sprite=icon;
062 return item;
063 }
064 U0 UIGridItemRemove(CUIGridItem *i) {
065 CUIGrid *parent=i->parent;
066 if(!parent) return;
067 I64SetRem(parent->items,i);
068 i->parent=NULL;
069 }
070 Bool UIGridAddItem(CUIGrid *grid,CUIGridItem *i) {
071 CI64Set *items=grid->items;
072 CUIGridItem *other;
073 I64 cnt=items->cnt,x,y,idx;
074 for(x=0;x!=grid->cols;++x)
075 for(y=0;y!=grid->rows;++y) {
076 for(idx=0;idx!=cnt;++idx) {
077 other=items->body[idx];
078 if(other->row==y&&other->col==x) {
079 goto no;
080 }
081 }
082 i->parent=grid;
083 i->row=y,i->col=x;
084 I64SetAdd(items,i);
085 return TRUE;
086 no:;
087 }
088 return FALSE;
089 }
090 U0 UIGridDraw(CUIGrid *grid,CDC *dc) {
091 I64 x,y;
092 CI64Set *items;
093 CUIGridItem *item;
094 grid->w2=grid->cols*24;
095 grid->h2=grid->rows*24;
096 grid->w=grid->w2;
097 grid->h=grid->h2;
098
099 dc->color=DKGRAY;
100 GrRect(dc,grid->x2,grid->y2,grid->w2,grid->h2);
101 for(x=0;x!=grid->cols;++x) {
102 for(y=0;y!=grid->rows;++y) {
103 if(grid->active_row==y&&grid->active_col==x) {
104 if(Blink)
105 dc->color=LTRED;
106 else
107 dc->color=LTCYAN;
108 } else
109 dc->color=BLACK;
110 GrRect(dc,grid->x2+x*24+4,grid->y2+y*24+4,16,16);
111 }
112 }
113 items=grid->items;
114 for(x=0;x!=items->cnt;++x) {
115 item=items->body[x];
116 item->parent=grid;
117 item->x=item->col*24;
118 item->y=item->row*24;
119 if(item->sprite)
120 Sprite3(dc,grid->x2+item->x+4,grid->y2+item->y+4,0,item->sprite);
121 }
122 }
123 CUIGridItem *GridItemAtXY(CUIGrid *grid,I64 x,I64 y) {
124 I64 idx;
125 CI64Set *items;
126 CUIGridItem *item;
127 items=grid->items;
128 for(idx=0;idx!=items->cnt;++idx) {
129 item=items->body[idx];
130 if(0<=x-item->x<24)
131 if(0<=y-item->y<24) {
132 return item;
133 }
134 }
135 return NULL;
136 }
137 Bool UIGridInteract(CUIGrid *grid,I64 msg,I64 x,I64 y) {
138 CUIGridItem *item,*item2;
139 if(msg==MSG_MS_L_DOWN) {
140 item=GridItemAtXY(grid,x,y);
141 if(item) {
142 FramePtrAdd("GridDragActive",item);
143 return TRUE;
144 }
145 }
146 if(msg==MSG_MS_L_UP&&(item=FramePtr("GridDragActive"))) {
147 item2=GridItemAtXY(grid,x,y);
148 //Swap items
149 if(item!=item2&&item2) {
150 I64SetRem(item->parent->items,item);
151 I64SetRem(item2->parent->items,item2);
152 SwapI64(&item->parent,&item2->parent);
153 SwapI64(&item->row,&item2->row);
154 SwapI64(&item->col,&item2->col);
155 I64SetAdd(item->parent->items,item);
156 I64SetAdd(item2->parent->items,item2);
157 } else if(item&&!item2) {
158 I64SetRem(item->parent->items,item);
159 item->parent=grid;
160 item->col=x/24;
161 item->row=y/24;
162 I64SetAdd(item->parent->items,item);
163 if(item->cb)
164 (*item->cb)(item);
165 }
166 FramePtrDel("GridDragActive");
167 return TRUE;
168 }
169 return FALSE;
170 }
171 CUIGrid *UIGridNew(I64 w,I64 h) {
172 CUIGrid *bt=GCCAlloc(sizeof CUIGrid);
173 bt->event_cb=&UIGridInteract;
174 bt->draw_it=&UIGridDraw;
175 bt->sub_elems=I64SetNew;
176 bt->items=I64SetNew;
177 bt->rows=h;
178 bt->cols=w;
179 return bt;
180 }
181 U0 TextDrawIt(CUIText *t,CDC *dc) {
182 dc->color=t->color;
183 t->h2=(StrOcc(t->text,'\n')+1)*8;
184 GrPrint(dc,t->x2,t->y2,"%s",t->text);
185 }
186 U0 BigTextDrawIt(CUIBigText *t,CDC *dc) {
187 I64 oflags=dc->flags,ot=dc->transform;
188 CD6 *mesh=PrimitiveText3D(t->text,4,t->scale,t->color);
189 I64 rev[16],winx,winy,winz,ox,oy;
190 dc->flags|=DCF_TRANSFORMATION;
191 dc->transform=&WorldTransform;
192 Mat4x4IdentEqu(rev);
193 Mat4x4RotY(rev,pi);
194 mesh=CD6NewTransform(mesh,rev);
195 Mat4x4IdentEqu(rev);
196 Mat4x4TranslationEqu(rev,t->x2,t->y2,1000.);
197 winz=1.;
198 winy=ms.pos.y-mem_task->pix_top;
199 winx=ms.pos.x-mem_task->pix_left;
200 Mat4x4PointTo(rev,winx,winy,winz);
201 Mat4x4TranslationEqu(rev,0,0,350.);
202
203 ox=dc->x,oy=dc->y;
204 dc->x=t->x2;
205 dc->y=t->y2;
206 CD6Draw(mesh,0,0,0,dc,rev);
207 dc->x=ox,dc->y=oy;
208 GCFree(mesh);
209 dc->transform=ot;
210 dc->flags=oflags;
211 }
212 CUIBigText *UIBigTextNew(U8 *str,F64 scale=16.) {
213 CUIBigText *bt=GCCAlloc(sizeof CUIBigText);
214 bt->color=YELLOW;
215 bt->scale=scale;
216 bt->text=GCStrNew(str);
217 bt->draw_it=&BigTextDrawIt;
218 bt->sub_elems=I64SetNew;
219 return bt;
220 }
221 CUIText *UITextNew(U8 *str) {
222 CUIText *bt=GCCAlloc(sizeof CUIText);
223 bt->color=RED;
224 bt->text=GCStrNew(str);
225 bt->draw_it=&TextDrawIt;
226 bt->sub_elems=I64SetNew;
227 return bt;
228 }
229 //Returns height 21
230 F64 DrawSubElems(CUIElem *e,CDC *dc) {
231 F64 x=e->x2,y=e->y2+e->h2;
232 I64 cnt=e->sub_elems->cnt,idx;
233 CUIElem **sub=e->sub_elems->body,*cur;
234 for(idx=0;idx!=cnt;++idx) {
235 cur=sub[idx];
236 if(!cur->invisible) {
237 cur->x2=x+cur->x;
238 cur->y2=y+cur->y;
239 cur->w2=cur->w;
240 cur->h2=cur->h;
241 if(cur->draw_it)
242 (*cur->draw_it)(cur,dc);
243 if(!cur->no_occupy_space)
244 y+=cur->h2;
245 }
246 }
247 return y-e->y2;
248 }
249
250
251 U0 ButtonDrawIt(CUIButton *bt,CDC *dc) {
252 dc->color=bt->bg_color;
253 GrRect(dc,bt->x2,bt->y2,bt->w2,bt->h2);
254 dc->color=bt->border_color;
255 GrBorder(dc,bt->x2+4,bt->y2+4,bt->x2+bt->w2-8,bt->y2+bt->h2-8);
256 dc->color=bt->fg_color;
257 GrPutS(dc,bt->x2+8,bt->y2+bt->h2/2.-4,bt->text);
258 }
259
260 U0 TreeDrawIt(CUITree *tree,CDC *dc) {
261 I64 cnt=tree->sub_elems->cnt,idx;
262 CUIElem **sub=tree->sub_elems->body;
263 U8 *tmp=tree->text;
264 if(tree->open)
265 tree->text=MStrPrint("+] %s",tmp);
266 else
267 tree->text=MStrPrint("-] %s",tmp);
268 ButtonDrawIt(tree,dc);
269 Free(tree->text);
270 tree->text=tmp;
271
272 if(tree->open) {
273 for(idx=0;idx!=cnt;++idx) {
274 sub[idx]->invisible=FALSE;
275 }
276 tree->x2+=32.;
277 tree->h2=DrawSubElems(tree,dc);
278 tree->x2-=32.;
279 } else {
280 for(idx=0;idx!=cnt;++idx) {
281 sub[idx]->invisible=TRUE;
282 }
283 tree->h2=tree->h;
284 }
285 }
286
287 Bool ButtonInteract(CUIButton *bttn,I64 msg,I64 x,I64 y) {
288 if(msg==MSG_MS_L_DOWN) {
289 if(bttn->cb) {
290 (*bttn->cb)(bttn);
291 }
292 return TRUE;
293 }
294 return FALSE;
295 }
296
297 CUIButton *UIButtonNew(U8 *label,F64 w=100,F64 h=32) {
298 CUIButton *btn=GCCAlloc(sizeof CUIButton);
299 btn->border_color=WHITE;
300 btn->bg_color=BLACK;
301 btn->fg_color=WHITE;
302 btn->w=w,btn->h=h;
303 btn->text=GCStrNew(label);
304 btn->sub_elems=I64SetNew;
305 btn->draw_it=&ButtonDrawIt;
306 btn->event_cb=&ButtonInteract;
307 return btn;
308 }
309
310 Bool MouseInElem(CUIElem *e,I64 x,I64 y) {
311 if(e->x2<=x<e->x2+e->w) {
312 if(e->y2<=y<e->y2+e->h) {
313 return TRUE;
314 }
315 }
316 return FALSE;
317 }
318
319 Bool TreeInteract(CUITree *tree,I64 msg,I64 x,I64 y) {
320 if(msg==MSG_MS_L_DOWN) {
321 tree->open^=TRUE;
322 return TRUE;
323 }
324 return FALSE;
325 }
326 CUIButton *UITreeNew(U8 *label,F64 w=100,F64 h=32) {
327 CUIButton *btn=GCCAlloc(sizeof CUITree);
328 btn->w=w,btn->h=h;
329 btn->text=GCStrNew(label);
330 btn->sub_elems=I64SetNew;
331 btn->event_cb=&TreeInteract;
332 btn->border_color=PURPLE;
333 btn->bg_color=BLACK;
334 btn->fg_color=PURPLE;
335 btn->draw_it=&TreeDrawIt;
336 return btn;
337 }
338
339
340 CUIRoot *UIRootNew() {
341 CUIButton *root=GCCAlloc(sizeof CUIRoot);
342 root->w=GR_WIDTH,root->h=GR_HEIGHT;
343 root->sub_elems=I64SetNew;
344 return root;
345 }
346
347 U0 UIElemAdd(CUIElem *to,CUIElem *who) {
348 I64SetAdd(to->sub_elems,who);
349 }
350
351
352 CUIRoot *ui_root=UIRootNew;
353 U0 DrawUI(CTask *t,CDC *dc) {
354 DrawSubElems(ui_root,dc);
355 }
356 Bool UIMsg(CUIElem *e,I64 t,I64 x,I64 y,Bool root=TRUE) {
357 I64 cnt=e->sub_elems->cnt,idx;
358 CUIElem **sub=e->sub_elems->body,*cur;
359 Bool ret=FALSE;
360 for(idx=0;idx!=cnt;++idx) {
361 cur=sub[idx];
362 if(!cur->invisible) {
363 switch(t) {
364 case MSG_MS_L_UP:
365 case MSG_MS_MOVE:
366 case MSG_MS_L_DOWN:
367 case MSG_MS_R_UP:
368 case MSG_MS_R_DOWN:
369 case MSG_MS_L_D_UP:
370 case MSG_MS_R_D_UP:
371 case MSG_MS_L_D_DOWN:
372 case MSG_MS_R_D_DOWN:
373 if(ret=UIMsg(cur,t,x,y,FALSE))
374 goto en;
375 break;
376 default:
377 if(ret=UIMsg(cur,t,x,y,FALSE))
378 goto en;
379 }
380 }
381 }
382 if(e->event_cb) {
383 switch(t) {
384 case MSG_MS_L_UP:
385 case MSG_MS_MOVE:
386 case MSG_MS_L_DOWN:
387 case MSG_MS_R_UP:
388 case MSG_MS_R_DOWN:
389 case MSG_MS_L_D_UP:
390 case MSG_MS_R_D_UP:
391 case MSG_MS_L_D_DOWN:
392 case MSG_MS_R_D_DOWN:
393 if(MouseInElem(e,x,y))
394 if(ret=(*e->event_cb)(e,t,x-e->x2,y-e->y2))
395 goto en;
396 break;
397 default:
398 if(ret=(*e->event_cb)(e,t,x,y))
399 goto en;
400 break;
401 }
402 }
403 en:
404 if(t==MSG_MS_L_UP)
405 if(root&&!ret&&FramePtr("GridDragActive"))
406 FramePtrDel("GridDragActive");
407 return ret;
408 }
409
410 #if __CMD_LINE__
411 <1>////
412 ////
413 <2>////
414 ////
415
416
417
418
419
420 U8 *sprite;
421 U0 BeepPress(CUIButton *b) {
422 Beep;
423 }
424 CUITree *tree=UITreeNew("Asswipe");
425 CUIButton *btn1=UIButtonNew("tp");
426 CUIButton *btn2=UIButtonNew("tp2");
427 CUIBigText *bt=UIBigTextNew("Hello:\n$100",64);
428 CUIGrid *grid=UIGridNew(10,1);;
429 CUIGridItem *gride=UIGridItemNew(<1>);
430 CUIGridItem *gride2=UIGridItemNew(<2>);
431 UIGridAddItem(grid,gride);
432 UIGridAddItem(grid,gride2);
433 grid->x=300;
434 //grid->y=100;
435 bt->x=100;
436 bt->y=200;
437 CUIBigText *bt2=UIBigTextNew("World",64);
438 bt2->x=GR_WIDTH-100;
439 bt2->y=200;
440 CUIText *txt=UITextNew("Anal\nBeads");
441 UIElemAdd(ui_root,tree);
442 UIElemAdd(ui_root,grid);
443 UIElemAdd(ui_root,bt);
444 UIElemAdd(ui_root,bt2);
445 UIElemAdd(tree,btn1);
446 UIElemAdd(tree,btn2);
447 UIElemAdd(tree,txt);
448 btn2->cb=&BeepPress;
449 Fs->draw_it=&DrawUI;
450 I64 t,x,y;
451 DocClear;
452 while(TRUE) {
453 while(t=ScanMsg(&x,&y)) {
454 UIMsg(ui_root,t,x,y);
455 }
456 Refresh;
457 }
458 #endif
459 #endif