00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00040 #include "omicron/internal.h"
00041 #include "omicron/render.h"
00042 #include "omicron/image.h"
00043 #include "omicron/gui.h"
00044 #include "omicron/list.h"
00045 #include "omicron/input.h"
00046 #include "omicron/file.h"
00047 #include "omicron/texture.h"
00048
00049
00050
00051
00052
00053
00054
00055 ushort gui_c::get_key_ascii(uchar key)
00056 {
00057 AssertThisV;
00058
00059 switch(key)
00060 {
00061 case OK_LEFT:
00062 return UI_KEY_LEFT;
00063 case OK_RIGHT:
00064 return UI_KEY_RIGHT;
00065 case OK_UP:
00066 return UI_KEY_UP;
00067 case OK_DOWN:
00068 return UI_KEY_DOWN;
00069 case OK_BACKSPACE:
00070 return UI_KEY_BACKSPACE;
00071 case OK_DELETE:
00072 return UI_KEY_DELETE;
00073 case OK_HOME:
00074 return UI_KEY_HOME;
00075 case OK_END:
00076 return UI_KEY_END;
00077 }
00078
00079 return _get_key_ascii(key);
00080 }
00081
00082
00083
00084 uiobject_c::uiobject_c()
00085 {
00086 classname = "generic";
00087
00088 text = NULL;
00089 img = new image_c;
00090 children = new list_c<uiobject_c>;
00091 id = 0;
00092 parent = NULL;
00093
00094 visible = true;
00095 disabled = false;
00096
00097 growth[0] = 0;
00098 growth[1] = 0;
00099 growth[2] = 0;
00100 growth[3] = 0;
00101
00102 styleflags = 0;
00103
00104 width = 0;
00105 height = 0;
00106
00107 bgcolor = color_from_floats(1,1,1,1);
00108
00109 movable = false;
00110 mousedrag = false;
00111
00112 cursor = 0;
00113
00114 fnt = gv.gui->get_font(UIF_FONT8);
00115
00116 set_needs_refresh();
00117 }
00118
00119 uiobject_c::~uiobject_c()
00120 {
00121 AssertThis;
00122
00123 if (children)
00124 {
00125 uiobject_c *obj = (uiobject_c *)children->get_first();
00126
00127 while(obj)
00128 {
00129 SafeDelete(obj);
00130 obj = (uiobject_c *)children->get_next();
00131 }
00132 }
00133
00134 SafeDelete(children);
00135 SafeDelete(img);
00136 SafeArrayDelete(text);
00137 }
00138
00139 void uiobject_c::resize(ushort w, ushort h)
00140 {
00141 AssertThis;
00142
00143 ushort pw = 0, ph = 0;
00144 ushort lw = width, lh = height;
00145
00146 width=w; height=h;
00147
00148 if (parent)
00149 {
00150 if (!strcmp(parent->classname, "desktop"))
00151 {
00152 pw = parent->get_width();
00153 ph = parent->get_height();
00154 }
00155 }
00156 else
00157 {
00158 pw = gv.init.hres;
00159 ph = gv.init.vres;
00160 }
00161
00162 if (pw && ph)
00163 {
00164 if (posx+width>pw)
00165 width = pw-posx;
00166
00167 if (posy+height>ph)
00168 height = ph-posy;
00169 }
00170
00171 img->create(width,height);
00172 set_needs_refresh();
00173
00174 uievent_s eve;
00175
00176 eve.event = UIE_PARENTSIZE;
00177 eve.key = 0;
00178 eve.x = width-lw;
00179 eve.y = height-lh;
00180 eve.mod = 0;
00181
00182 if (children)
00183 {
00184 eve.obj = (uiobject_c *)children->get_first();
00185
00186 while(eve.obj)
00187 {
00188 eve.obj->event(&eve);
00189 eve.obj = (uiobject_c *)children->get_next();
00190 }
00191 }
00192 }
00193
00194 void uiobject_c::move(sshort x, sshort y)
00195 {
00196 AssertThis;
00197
00198 posx=x;
00199 posy=y;
00200
00201 if (!strcmp(classname, "desktop"))
00202 return;
00203
00204 if (!parent || (0 == strcmp(parent->get_classname(), "desktop")))
00205 {
00206 if (posx<0) posx = 0;
00207 if (posx>parent->get_width()-width) posx = parent->get_width()-width;
00208 if (posy<0)
00209 posy = 0;
00210 if (posy>parent->get_height()-height)
00211 posy = parent->get_height()-height;
00212
00213 if (parent)
00214 parent->set_needs_refresh();
00215 }
00216 }
00217
00218 void uiobject_c::draw(image_c *dst)
00219 {
00220 AssertThis;
00221
00222 if (!visible)
00223 return;
00224
00225 if (needsrefresh || this==gv.gui->get_desktop())
00226 refresh();
00227
00228 if (this==gv.gui->get_desktop())
00229 return;
00230
00231 if (dst)
00232 {
00233 dst->blt_blend(img, 0, 0, posx, posy, width, height, BT_BLEND);
00234 }
00235 else
00236 {
00237 img->draw(posx, posy);
00238 }
00239 }
00240
00241 void uiobject_c::refresh()
00242 {
00243 AssertThis;
00244
00245 paint();
00246
00247 uiobject_c *obj = (uiobject_c *)children->get_first();
00248
00249 while(obj)
00250 {
00251 if (this == gv.gui->get_desktop())
00252 obj->draw(NULL);
00253 else
00254 obj->draw(img);
00255
00256 obj = (uiobject_c *)children->get_next();
00257 }
00258
00259 needsrefresh = false;
00260 }
00261
00262 void uiobject_c::paint()
00263 {
00264 AssertThis;
00265
00266 if (gv.gui->get_desktop()==this)
00267 return;
00268
00269 if (!(styleflags&UI_TRANSPARENT))
00270 img->filled_rectangle(0,0,width,height, bgcolor);
00271
00272 if (styleflags&UI_BORDER_FLAT)
00273 {
00274 img->rectangle(0,0,width,height, gv.gui->get_color(UIC_BORDER));
00275 }
00276 else
00277 {
00278 if (styleflags&UI_BORDER_OUTERSUNKEN)
00279 {
00280
00281 img->hline(0, 0, width-2, gv.gui->get_color(UIC_BLACK));
00282 img->vline(0, 0, height-2, gv.gui->get_color(UIC_BLACK));
00283
00284
00285 img->hline(1, height-1, width-2, gv.gui->get_color(UIC_FACE));
00286 img->vline(width-1, 1, height-2, gv.gui->get_color(UIC_FACE));
00287 }
00288 if (styleflags&UI_BORDER_INNERSUNKEN)
00289 {
00290
00291 img->hline(1, 1, width-3, gv.gui->get_color(UIC_SHADOW));
00292 img->vline(1, 1, height-3, gv.gui->get_color(UIC_SHADOW));
00293
00294
00295 img->hline(2, height-2, width-3, gv.gui->get_color(UIC_LIGHT));
00296 img->vline(width-2, 2, height-3, gv.gui->get_color(UIC_LIGHT));
00297 }
00298 if (styleflags&UI_BORDER_OUTERRAISED)
00299 {
00300
00301 img->hline(0, 0, width-2, gv.gui->get_color(UIC_FACE));
00302 img->vline(0, 0, height-2, gv.gui->get_color(UIC_FACE));
00303
00304
00305 img->hline(1, height-1, width-2, gv.gui->get_color(UIC_BLACK));
00306 img->vline(width-1, 1, height-2, gv.gui->get_color(UIC_BLACK));
00307 }
00308 if (styleflags&UI_BORDER_INNERRAISED)
00309 {
00310
00311 img->hline(1, 1, width-3, gv.gui->get_color(UIC_LIGHT));
00312 img->vline(1, 1, height-3, gv.gui->get_color(UIC_LIGHT));
00313
00314
00315 img->hline(2, height-2, width-3, gv.gui->get_color(UIC_SHADOW));
00316 img->vline(width-2, 2, height-3, gv.gui->get_color(UIC_SHADOW));
00317 }
00318 }
00319 }
00320
00321 void uiobject_c::add_child(uiobject_c *obj)
00322 {
00323 AssertThis;
00324
00325 AssertReturn1(obj);
00326
00327 if (obj == this)
00328 return;
00329
00330 children->append(obj);
00331 obj->parent = this;
00332 }
00333
00334 void uiobject_c::remove_child(uiobject_c *obj)
00335 {
00336 AssertThis;
00337
00338 AssertReturn1(obj);
00339
00340 children->remove(obj);
00341 SafeDelete(obj);
00342 }
00343
00344 void uiobject_c::bring_child_to_front(uiobject_c *obj)
00345 {
00346 AssertThis;
00347
00348 AssertReturn1(obj);
00349 children->set_current(obj);
00350 if (obj != children->get_current())
00351 return;
00352
00353 children->remove(obj);
00354 children->append(obj);
00355 }
00356
00357 uiobject_c *uiobject_c::get_object(ulong id)
00358 {
00359 AssertThisV;
00360
00361 if (id==get_id())
00362 return this;
00363
00364 if (children)
00365 {
00366 uiobject_c *obj = (uiobject_c *)children->get_first();
00367
00368 while(obj)
00369 {
00370 if (obj->get_id() == id)
00371 return obj;
00372
00373 uiobject_c *obj2 = obj->get_object(id);
00374
00375 if (obj2)
00376 return obj2;
00377
00378 obj = (uiobject_c *)children->get_next();
00379 }
00380 }
00381 return NULL;
00382 }
00383
00384 uiobject_c *uiobject_c::find_mouse_object(ushort mx, ushort my)
00385 {
00386 AssertThisV;
00387
00388 uiobject_c *mouseobj = NULL,
00389 *obj = (uiobject_c*)children->get_last(),
00390 *subobj;
00391
00392
00393 while(obj)
00394 {
00395 sshort pos[4];
00396
00397 pos[0] = obj->posx;
00398 pos[1] = obj->posy;
00399 pos[2] = pos[0]+obj->width;
00400 pos[3] = pos[1]+obj->height;
00401
00402 if (mx>pos[0] && mx<pos[2] &&
00403 my>pos[1] && my<pos[3])
00404 {
00405 mouseobj = obj;
00406 subobj = mouseobj->find_mouse_object(mx-pos[0],my-pos[1]);
00407 if (subobj)
00408 mouseobj = subobj;
00409
00410 return mouseobj;
00411 }
00412
00413 obj = (uiobject_c*)children->get_prev();
00414 }
00415
00416 return mouseobj;
00417 }
00418
00419 void uiobject_c::event(uievent_s *eve)
00420 {
00421 AssertThis;
00422
00423 AssertReturn1(eve);
00424
00425 switch (eve->event)
00426 {
00427 case UIE_PARENTSIZE:
00428 {
00429 move(posx+eve->x*growth[0], posy+eve->y*growth[1]);
00430 resize(width+eve->x*growth[2], height+eve->y*growth[3]);
00431 }
00432 break;
00433
00434 case UIE_MOUSEOVER:
00435 if (movable && !(gv.mouse_b&1))
00436 mousedrag = false;
00437 break;
00438
00439 case UIE_MOUSEDOWN:
00440 if (movable)
00441 {
00442 mousedrag = true;
00443 dragdownx = eve->x;
00444 dragdowny = eve->y;
00445
00446
00447 if (parent)
00448 parent->bring_child_to_front(this);
00449 }
00450 break;
00451
00452 case UIE_MOUSEMOVE:
00453 if (movable & mousedrag)
00454 move(eve->x-dragdownx+posx, eve->y-dragdowny+posy);
00455 break;
00456
00457 case UIE_MOUSEUP:
00458 mousedrag = false;
00459 break;
00460 }
00461
00462 gv.iface->gui_callback(eve);
00463 }
00464
00465 void uiobject_c::set_text(const char *txt)
00466 {
00467 AssertThis;
00468
00469 SafeArrayDelete(text);
00470
00471 if (txt)
00472 {
00473 text = new char[strlen(txt)+1];
00474 strcpy(text, txt);
00475
00476 set_needs_refresh();
00477 }
00478 }
00479
00480 sshort uiobject_c::get_screenposx()
00481 {
00482 AssertThisV;
00483
00484 if (parent)
00485 return posx+parent->get_screenposx();
00486
00487 return posx;
00488 }
00489
00490 sshort uiobject_c::get_screenposy()
00491 {
00492 AssertThisV;
00493
00494 if (parent)
00495 return posy+parent->get_screenposy();
00496
00497 return posy;
00498 }
00499
00500 void uiobject_c::set_growth(sshort x, sshort y, sshort w, sshort h)
00501 {
00502 AssertThis;
00503
00504 growth[0] = x;
00505 growth[1] = y;
00506 growth[2] = w;
00507 growth[3] = h;
00508 }
00509
00510
00511
00512 gui_c::gui_c()
00513 {
00514 SafeDelete(gv.gui);
00515
00516 if (gv.init.nogfx)
00517 return;
00518
00519 gv.fileman->load_pak("gui.pak");
00520
00521 gv.gui = this;
00522
00523
00524 lastkeydown = 0;
00525 keylastrepeattime = 0;
00526 keydownstarttime = 0;
00527 currentkeymod = 0;
00528
00529
00530 mouseobj = lmouseobj = focus = NULL;
00531 cursorx = cursory = 0;
00532 cursor = 0;
00533
00534
00535 desktop = new uiobject_c;
00536
00537 if (desktop)
00538 {
00539 desktop->classname = "desktop";
00540 desktop->move(0,0);
00541 desktop->resize(gv.init.hres, gv.init.vres);
00542 }
00543
00544
00545 images = new animation_c[UII_COUNT];
00546 if (images)
00547 {
00548 images[UII_WINDOW ].load("gui/wndpix");
00549 images[UII_WINDOW ].set_framecount(8);
00550
00551 images[UII_CHECKBOX ].load("gui/checkbox");
00552 images[UII_CHECKBOX ].set_framecount(8);
00553
00554 images[UII_SLIDER ].load("gui/slider");
00555 images[UII_SLIDER ].set_framecount(8);
00556
00557 images[UII_CURSOR ].load("gui/cursor");
00558 images[UII_CURSOR ].set_framecount(8);
00559 }
00560
00561
00562 colors[UIC_FACE ] = color_from_floats(0.75f, 0.75f, 0.75f, 1.00f);
00563 colors[UIC_LIGHT ] = color_from_floats(1.00f, 1.00f, 1.00f, 1.00f);
00564 colors[UIC_SHADOW ] = color_from_floats(0.50f, 0.50f, 0.50f, 1.00f);
00565 colors[UIC_BLACK ] = color_from_floats(0.00f, 0.00f, 0.00f, 1.00f);
00566 colors[UIC_HIGHLIGHT] = color_from_floats(0.85f, 0.85f, 0.85f, 1.00f);
00567 colors[UIC_SELECTION] = color_from_floats(0.75f, 0.75f, 1.00f, 1.00f);
00568 colors[UIC_FOCUS ] = color_from_floats(0.50f, 0.50f, 0.50f, 1.00f);
00569 colors[UIC_DISABLED ] = color_from_floats(0.60f, 0.60f, 0.60f, 1.00f);
00570 colors[UIC_TEXT ] = color_from_floats(0.00f, 0.00f, 0.00f, 1.00f);
00571 colors[UIC_EDIT ] = color_from_floats(1.00f, 1.00f, 1.00f, 1.00f);
00572 colors[UIC_BORDER ] = color_from_floats(0.50f, 0.50f, 0.50f, 1.00f);
00573 colors[UIC_WINDOW ] = color_from_floats(1.00f, 1.00f, 1.00f, 1.00f);
00574
00575
00576 image_c *fntimg = NULL;
00577
00578 fntimg = new image_c;
00579
00580 if (fntimg)
00581 {
00582 fntimg->load("gui/chars8x8");
00583 font[UIF_FONT8] = gv.renderer->font_createfromimage_fixed(fntimg, 8);
00584
00585 fntimg->load("gui/chars8x8fixed");
00586 font[UIF_FONT8_FIXED] = gv.renderer->font_createfromimage_fixed(fntimg, 8);
00587
00588 fntimg->load("gui/chars16x16");
00589 font[UIF_FONT16] = gv.renderer->font_createfromimage_fixed(fntimg, 16);
00590
00591 fntimg->load("gui/chars16x16fixed");
00592 font[UIF_FONT16_FIXED] = gv.renderer->font_createfromimage_fixed(fntimg, 16);
00593
00594 SafeDelete(fntimg);
00595 }
00596
00597 if (font[UIF_FONT8])
00598 {
00599 font[UIF_FONT8]->widths[32] = 4; font[UIF_FONT8]->widths[33] = 2;
00600 font[UIF_FONT8]->widths[34] = 4; font[UIF_FONT8]->widths[35] = 6;
00601 font[UIF_FONT8]->widths[36] = 6; font[UIF_FONT8]->widths[37] = 7;
00602 font[UIF_FONT8]->widths[38] = 6; font[UIF_FONT8]->widths[39] = 2;
00603 font[UIF_FONT8]->widths[40] = 3; font[UIF_FONT8]->widths[41] = 3;
00604 font[UIF_FONT8]->widths[42] = 4; font[UIF_FONT8]->widths[43] = 4;
00605 font[UIF_FONT8]->widths[44] = 2; font[UIF_FONT8]->widths[45] = 4;
00606 font[UIF_FONT8]->widths[46] = 2; font[UIF_FONT8]->widths[47] = 3;
00607
00608 font[UIF_FONT8]->widths[48] = 5; font[UIF_FONT8]->widths[49] = 5;
00609 font[UIF_FONT8]->widths[50] = 5; font[UIF_FONT8]->widths[51] = 5;
00610 font[UIF_FONT8]->widths[52] = 5; font[UIF_FONT8]->widths[53] = 5;
00611 font[UIF_FONT8]->widths[54] = 5; font[UIF_FONT8]->widths[55] = 5;
00612 font[UIF_FONT8]->widths[56] = 5; font[UIF_FONT8]->widths[57] = 5;
00613 font[UIF_FONT8]->widths[58] = 2; font[UIF_FONT8]->widths[59] = 2;
00614 font[UIF_FONT8]->widths[60] = 4; font[UIF_FONT8]->widths[61] = 4;
00615 font[UIF_FONT8]->widths[62] = 4; font[UIF_FONT8]->widths[63] = 5;
00616
00617 font[UIF_FONT8]->widths[64] = 8; font[UIF_FONT8]->widths[65] = 8;
00618 font[UIF_FONT8]->widths[66] = 8; font[UIF_FONT8]->widths[67] = 8;
00619 font[UIF_FONT8]->widths[68] = 8; font[UIF_FONT8]->widths[69] = 8;
00620 font[UIF_FONT8]->widths[70] = 8; font[UIF_FONT8]->widths[71] = 8;
00621 font[UIF_FONT8]->widths[72] = 8; font[UIF_FONT8]->widths[73] = 2;
00622 font[UIF_FONT8]->widths[74] = 5; font[UIF_FONT8]->widths[75] = 6;
00623 font[UIF_FONT8]->widths[76] = 4; font[UIF_FONT8]->widths[77] = 8;
00624 font[UIF_FONT8]->widths[78] = 7; font[UIF_FONT8]->widths[79] = 7;
00625
00626 font[UIF_FONT8]->widths[80] = 7; font[UIF_FONT8]->widths[81] = 7;
00627 font[UIF_FONT8]->widths[82] = 7; font[UIF_FONT8]->widths[83] = 6;
00628 font[UIF_FONT8]->widths[84] = 6; font[UIF_FONT8]->widths[85] = 6;
00629 font[UIF_FONT8]->widths[86] = 6; font[UIF_FONT8]->widths[87] = 7;
00630 font[UIF_FONT8]->widths[88] = 7; font[UIF_FONT8]->widths[89] = 7;
00631 font[UIF_FONT8]->widths[90] = 7; font[UIF_FONT8]->widths[91] = 3;
00632 font[UIF_FONT8]->widths[92] = 3; font[UIF_FONT8]->widths[93] = 3;
00633 font[UIF_FONT8]->widths[94] = 4; font[UIF_FONT8]->widths[95] = 5;
00634
00635 font[UIF_FONT8]->widths[96] = 2; font[UIF_FONT8]->widths[97] = 5;
00636 font[UIF_FONT8]->widths[98] = 5; font[UIF_FONT8]->widths[99] = 5;
00637 font[UIF_FONT8]->widths[100] = 5; font[UIF_FONT8]->widths[101] = 5;
00638 font[UIF_FONT8]->widths[102] = 3; font[UIF_FONT8]->widths[103] = 5;
00639 font[UIF_FONT8]->widths[104] = 5; font[UIF_FONT8]->widths[105] = 2;
00640 font[UIF_FONT8]->widths[106] = 3; font[UIF_FONT8]->widths[107] = 5;
00641 font[UIF_FONT8]->widths[108] = 2; font[UIF_FONT8]->widths[109] = 8;
00642 font[UIF_FONT8]->widths[110] = 5; font[UIF_FONT8]->widths[111] = 6;
00643
00644 font[UIF_FONT8]->widths[112] = 5; font[UIF_FONT8]->widths[113] = 5;
00645 font[UIF_FONT8]->widths[114] = 3; font[UIF_FONT8]->widths[115] = 5;
00646 font[UIF_FONT8]->widths[116] = 3; font[UIF_FONT8]->widths[117] = 5;
00647 font[UIF_FONT8]->widths[118] = 5; font[UIF_FONT8]->widths[119] = 6;
00648 font[UIF_FONT8]->widths[120] = 4; font[UIF_FONT8]->widths[121] = 4;
00649 font[UIF_FONT8]->widths[122] = 4; font[UIF_FONT8]->widths[123] = 4;
00650 font[UIF_FONT8]->widths[124] = 2; font[UIF_FONT8]->widths[125] = 4;
00651 font[UIF_FONT8]->widths[126] = 8; font[UIF_FONT8]->widths[127] = 8;
00652 }
00653
00654 if (font[UIF_FONT16])
00655 {
00656 uchar widths[] = {
00657 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00659 8, 4, 9, 13, 12, 15, 13, 4, 5, 5, 8, 9, 6, 6, 6, 14,
00660 11, 8, 11, 11, 11, 11, 11, 11, 11, 11, 6, 6, 8, 10, 9, 8,
00661 16, 14, 12, 13, 12, 11, 10, 13, 12, 5, 11, 13, 10, 14, 12, 13,
00662 11, 13, 12, 12, 12, 12, 14, 14, 13, 14, 12, 6, 14, 6, 7, 15,
00663 4, 11, 11, 11, 11, 11, 8, 11, 10, 5, 7, 11, 5, 14, 10, 11,
00664 11, 11, 8, 10, 11, 10, 11, 14, 11, 11, 10, 8, 3, 8, 9, 14
00665 };
00666
00667 memcpy(font[UIF_FONT16]->widths, widths, sizeof(widths));
00668 }
00669 }
00670
00671 gui_c::~gui_c()
00672 {
00673 AssertThis;
00674
00675 SafeDelete(desktop);
00676 SafeArrayDelete(images);
00677
00678 for (ulong i=0; i<UIF_COUNT; i++)
00679 gv.renderer->font_free(font[i]);
00680 }
00681
00682 void gui_c::draw()
00683 {
00684 AssertThis;
00685
00686 gv.renderer->view_2d(gv.init.hres, gv.init.vres);
00687
00688 gv.texman->set(-1);
00689 gv.renderer->set_fog(false);
00690 gv.renderer->set_zbuffer(ZB_NONE);
00691 gv.renderer->set_color(COLOR_WHITE);
00692
00693 if (desktop)
00694 {
00695 if (desktop->width!=gv.init.hres || desktop->height!=gv.init.vres)
00696 desktop->resize(gv.init.hres, gv.init.vres);
00697
00698 desktop->draw(NULL);
00699 }
00700
00701 if (images)
00702 {
00703 images[UII_CURSOR].set_frame(cursor);
00704 images[UII_CURSOR].draw(cursorx, cursory);
00705 }
00706 }
00707
00708 void gui_c::update()
00709 {
00710 AssertThis;
00711
00712 AssertReturn1(desktop);
00713
00714
00715
00716 currentkeymod = 0;
00717
00718 if (gv.kbdstate[OK_LSHIFT] || gv.kbdstate[OK_RSHIFT])
00719 currentkeymod |= UI_KEYFLAG_SHIFT;
00720
00721 if (gv.kbdstate[OK_RALT])
00722 currentkeymod |= UI_KEYFLAG_ALTGR;
00723
00724 if (gv.kbdstate[OK_LALT])
00725 currentkeymod |= UI_KEYFLAG_ALT;
00726
00727 if (gv.kbdstate[OK_LCTRL] || gv.kbdstate[OK_RCTRL])
00728 currentkeymod |= UI_KEYFLAG_CTRL;
00729
00730
00731
00732 cursorlx = cursorx;
00733 cursorly = cursory;
00734
00735 if (gv.init.fullscreen)
00736 {
00737 cursorx += gv.mouse_dx;
00738 cursory += gv.mouse_dy;
00739 }
00740 else
00741 {
00742 #if defined(WIN32) || defined(_WIN32)
00743 POINT pt;
00744
00745 GetCursorPos(&pt);
00746 ScreenToClient((HWND)gv.init.wnd, &pt);
00747
00748 cursorx = pt.x;
00749 cursory = pt.y;
00750 #else
00751 #endif
00752 }
00753
00754 cursorx = (cursorx>gv.init.hres?gv.init.hres:(cursorx<0?0:cursorx));
00755 cursory = (cursory>gv.init.vres?gv.init.vres:(cursory<0?0:cursory));
00756
00757 cursordx = cursorx-cursordx;
00758 cursordy = cursory-cursordy;
00759
00760 lmouseobj = mouseobj;
00761 mouseobj = desktop->find_mouse_object(cursorx,cursory);
00762
00763 if (mouseobj)
00764 {
00765 if (cursordx || cursordy)
00766 send_mouse_event(mouseobj, UIE_MOUSEMOVE);
00767 }
00768
00769
00770
00771
00772 if (mouseobj != lmouseobj)
00773 {
00774 send_mouse_event(lmouseobj, UIE_MOUSEOUT);
00775
00776 if (cursordx || cursordy)
00777 send_mouse_event(lmouseobj, UIE_MOUSEMOVE);
00778
00779 send_mouse_event(mouseobj, UIE_MOUSEOVER);
00780 }
00781
00782
00783 if ((gv.mouse_b&1) && !(gv.mouse_lb&1))
00784 {
00785
00786
00787 send_generic_event(focus, UIE_LOSTFOCUS);
00788 focus = mouseobj;
00789 send_generic_event(focus, UIE_GETFOCUS);
00790 send_mouse_event(focus, UIE_MOUSEDOWN);
00791 }
00792
00793 else if (!(gv.mouse_b&1) && (gv.mouse_lb&1) && mouseobj)
00794 {
00795
00796
00797 send_mouse_event(mouseobj, UIE_MOUSEUP);
00798
00799
00800 if (mouseobj == focus)
00801 send_mouse_event(mouseobj, UIE_MOUSECLICK);
00802 }
00803
00804 if (focus!=mouseobj && (cursordx || cursordy))
00805 send_mouse_event(focus, UIE_MOUSEMOVE);
00806
00807
00808 if (mouseobj)
00809 cursor = mouseobj->get_cursor();
00810 else
00811 cursor = 0;
00812
00814 ushort i = 0;
00815 ulong t = _time_get();
00816
00817 for (i=0; i<255; i++)
00818 {
00819
00820 if (gv.kbdstate[i] && (!gv.lkbdstate[i] || (i == lastkeydown)))
00821 {
00822
00823 if (i == lastkeydown)
00824 {
00825 if (t-keydownstarttime<200)
00826 continue;
00827
00828 if (t-keylastrepeattime<20)
00829 continue;
00830 }
00831
00832
00833 if (!gv.lkbdstate[i])
00834 {
00835 lastkeydown = (uchar)i;
00836 keydownstarttime = t;
00837 }
00838
00839 ushort c = (ushort)get_key_ascii((uchar)i);
00840
00841 if (c)
00842 send_keyboard_event(focus, UIE_CHAR, c);
00843
00844 keylastrepeattime = t;
00845 }
00846 }
00847 }
00848
00849
00850 void gui_c::send_mouse_event(uiobject_c *obj, ushort event)
00851 {
00852 AssertThis;
00853
00854 if (!obj)
00855 return;
00856
00857 uievent_s eve;
00858
00859 eve.event = event;
00860 eve.key = 0;
00861 eve.obj = obj;
00862 eve.x = cursorx - obj->get_screenposx();
00863 eve.y = cursory - obj->get_screenposy();
00864 eve.mod = currentkeymod;
00865
00866 obj->event(&eve);
00867 }
00868
00869 void gui_c::send_generic_event(uiobject_c *obj, ushort event)
00870 {
00871 AssertThis;
00872
00873 if (!obj)
00874 return;
00875
00876 uievent_s eve;
00877
00878 eve.event = event;
00879 eve.key = 0;
00880 eve.obj = obj;
00881 eve.x = 0;
00882 eve.y = 0;
00883 eve.mod = currentkeymod;
00884
00885 obj->event(&eve);
00886 }
00887
00888 void gui_c::send_keyboard_event(uiobject_c *obj, ushort event, ushort key)
00889 {
00890 AssertThis;
00891
00892 if (!obj)
00893 return;
00894
00895 uievent_s eve;
00896
00897 eve.event = event;
00898 eve.key = key;
00899 eve.obj = obj;
00900 eve.x = 0;
00901 eve.y = 0;
00902 eve.mod = currentkeymod;
00903
00904 obj->event(&eve);
00905 }
00906
00907 void gui_c::load(const char *fname)
00908 {
00909 AssertThis;
00910
00911 file_t *f;
00912
00913 f = gv.fileman->load(fname, false);
00914
00915 if (!f)
00916 return;
00917
00918 uiobject_c *obj, *parentobj;
00919
00920 char *comment = NULL;
00921 char line[1024];
00922 char *linebeginning = line;
00923
00924 char cname[32];
00925 char mov, ena, checked;
00926 sshort x,y,w,h;
00927 int textpos;
00928 ulong parentid, thisid;
00929
00930 memset(line, 0, 1024);
00931
00932 while(!gv.fileman->eof(f))
00933 {
00934 gv.fileman->gets(line, 1024, f);
00935
00936 comment = strchr(line, '#');
00937 if (comment)
00938 *comment = 0;
00939
00940 linebeginning = _strtrm(line, " \n\r\t");
00941
00942 if (!strlen(linebeginning))
00943 continue;
00944
00945
00946 textpos = strlen(line);
00947 sscanf(line, "%s %lu %lu %hd %hd %hd %hd %c %c %c %n", cname, &parentid, &thisid, &x, &y, &w, &h, &mov, &ena, &checked, &textpos);
00948
00949 obj = NULL;
00950 parentobj = desktop->get_object(parentid);
00951
00952 if (!parentobj)
00953 continue;
00954
00955
00956 if (!strcmpi(cname, "window"))
00957 {
00958 obj = new uiwindow_c;
00959 }
00960 else if (!strcmpi(cname, "button"))
00961 {
00962 obj = new uibutton_c;
00963 }
00964 else if (!strcmpi(cname, "label"))
00965 {
00966 obj = new uilabel_c;
00967 }
00968 else if (!strcmpi(cname, "edit"))
00969 {
00970 obj = new uiedit_c;
00971 }
00972 else if (!strcmpi(cname, "checkbutton"))
00973 {
00974 obj = new uicheckbutton_c;
00975
00976 ((uicheckbutton_c*)obj)->set_radio(false);
00977 ((uicheckbutton_c*)obj)->set_checked(strchr(TRUE_STRING, mov)?true:false);
00978 }
00979 else if (!strcmpi(cname, "radiobutton"))
00980 {
00981 obj = new uicheckbutton_c;
00982
00983 ((uicheckbutton_c*)obj)->set_radio(true);
00984 ((uicheckbutton_c*)obj)->set_checked(strchr(TRUE_STRING, mov)?true:false);
00985 }
00986 else if (!strcmpi(cname, "slider"))
00987 {
00988 obj = new uislider_c;
00989 }
00990
00991 if (obj)
00992 {
00993 if (parentobj && parentobj!=obj)
00994 parentobj->add_child(obj);
00995
00996 obj->move(x,y);
00997 obj->resize(w,h);
00998
00999 obj->movable = strchr(TRUE_STRING, mov)?true:false;
01000 obj->disabled = (!strchr(TRUE_STRING, ena))?true:false;
01001
01002 obj->set_text(line+textpos);
01003
01004 obj->set_id(thisid);
01005 }
01006 }
01007
01008 gv.fileman->close(f);
01009 }
01010
01011 animation_c *gui_c::get_image(ulong nr)
01012 {
01013 AssertThisV;
01014
01015 AssertReturnValue2(nr>=0, nr<=UII_COUNT, images);
01016 return &images[nr];
01017 }