00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "htatom.h"
00022 #include "cmds.h"
00023 #include "htapp.h"
00024 #include "htctrl.h"
00025 #include "htdebug.h"
00026 #include "htkeyb.h"
00027 #include "htmenu.h"
00028 #include "htobj.h"
00029 #include "htpal.h"
00030 #include "htreg.h"
00031 #include "htstring.h"
00032 #include "snprintf.h"
00033 #include "store.h"
00034 #include "tools.h"
00035
00036 #include <stdarg.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #define ATOM_HT_VIEW MAGICD("OBJ\0")
00041 #define ATOM_HT_GROUP MAGICD("OBJ\1")
00042 #define ATOM_HT_XGROUP MAGICD("OBJ\2")
00043 #define ATOM_HT_WINDOW MAGICD("OBJ\3")
00044 #define ATOM_HT_FRAME MAGICD("OBJ\4")
00045 #define ATOM_HT_SCROLLBAR MAGICD("OBJ\5")
00046
00047 #define DEFAULT_VIEW_MIN_WIDTH 25
00048 #define DEFAULT_VIEW_MIN_HEIGHT 6
00049
00050 void bounds_and(bounds *a, bounds *b)
00051 {
00052 if (b->x>a->x) {
00053 a->w-=b->x-a->x;
00054 a->x=b->x;
00055 }
00056 if (b->y>a->y) {
00057 a->h-=b->y-a->y;
00058 a->y=b->y;
00059 }
00060 if (a->x+a->w>b->x+b->w) a->w-=a->x+a->w-b->x-b->w;
00061 if (a->y+a->h>b->y+b->h) a->h-=a->y+a->h-b->y-b->h;
00062 if (a->w<0) a->w=0;
00063 if (a->h<0) a->h=0;
00064 }
00065
00066 void put_bounds(ht_object_stream *s, bounds *b)
00067 {
00068 s->putIntDec(b->x, 4, NULL);
00069 s->putIntDec(b->y, 4, NULL);
00070 s->putIntDec(b->w, 4, NULL);
00071 s->putIntDec(b->h, 4, NULL);
00072 }
00073
00074 void clearmsg(htmsg *msg)
00075 {
00076 msg->msg=msg_empty;
00077 msg->type=mt_empty;
00078 }
00079
00080
00081
00082
00083
00084 void ht_text::settext(const char *text)
00085 {
00086 }
00087
00088
00089
00090
00091
00092 void ht_view::init(bounds *b, int o, const char *d)
00093 {
00094 Object::init();
00095 VIEW_DEBUG_NAME("ht_view");
00096 desc = ht_strdup(d);
00097 group = 0;
00098 focused = 0;
00099 browse_idx = 0;
00100 view_is_dirty = true;
00101 size.x = 0;
00102 size.y = 0;
00103 size.w = 0;
00104 size.h = 0;
00105 prev = NULL;
00106 next = NULL;
00107 setoptions(o);
00108 buf = 0;
00109 enabled = true;
00110
00111 growmode = MK_GM(GMH_LEFT, GMV_TOP);
00112
00113 if (options & VO_OWNBUFFER) {
00114 buf = new drawbuf(&size);
00115 enable_buffering();
00116 } else {
00117 buf = screen;
00118 disable_buffering();
00119 }
00120
00121 g_hdist = 0;
00122 g_vdist = 0;
00123
00124 setbounds(b);
00125
00126 pal.data = NULL;
00127 pal.size = 0;
00128
00129 pal_class = defaultpaletteclass();
00130 pal_name = defaultpalette();
00131
00132 reloadpalette();
00133 }
00134
00135 void ht_view::done()
00136 {
00137 if (desc) free(desc);
00138 if (pal.data) free(pal.data);
00139 if (options & VO_OWNBUFFER) delete buf;
00140 Object::done();
00141 }
00142
00143 int ht_view::alone()
00144 {
00145 return (group && group->isalone(this));
00146 }
00147
00148 int ht_view::buf_lprint(int x, int y, int c, int l, char *text)
00149 {
00150 if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) {
00151 if (size.x+x+l>vsize.x+vsize.w) l=vsize.x+vsize.w-size.x-x;
00152 if (size.x+x-vsize.x<0) {
00153 int kqx=-size.x-x+vsize.x;
00154 for (int i=0; i<kqx; i++) {
00155 if (!*text) return 0;
00156 text++;
00157 x++;
00158 l--;
00159 }
00160 }
00161 return (l>0) ? buf->b_lprint(size.x+x, size.y+y, c, l, text) : 0;
00162 }
00163 return 0;
00164 }
00165
00166 int ht_view::buf_lprintw(int x, int y, int c, int l, int *text)
00167 {
00168 if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) {
00169 if (size.x+x+l>vsize.x+vsize.w) l=vsize.x+vsize.w-size.x-x;
00170 if (size.x+x-vsize.x<0) {
00171 int kqx=-size.x-x+vsize.x;
00172 for (int i=0; i<kqx; i++) {
00173 if (!*text) return 0;
00174 text++;
00175 x++;
00176 l--;
00177 }
00178 }
00179 return (l>0) ? buf->b_lprintw(size.x+x, size.y+y, c, l, text) : 0;
00180 }
00181 return 0;
00182 }
00183
00184 int ht_view::buf_print(int x, int y, int c, char *text)
00185 {
00186 if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) {
00187 int l=vsize.x+vsize.w-x-size.x;
00188 if (size.x+x-vsize.x<0) {
00189 int kqx=-size.x-x+vsize.x;
00190 for (int i=0; i<kqx; i++) {
00191 if (!*text) return 0;
00192 text++;
00193 x++;
00194 l--;
00195 }
00196 }
00197 return (l>0) ? buf->b_lprint(size.x+x, size.y+y, c, l, text) : 0;
00198 }
00199 return 0;
00200 }
00201
00202 void ht_view::buf_printchar(int x, int y, int c, int ch)
00203 {
00204 if (pointvisible(size.x+x, size.y+y)) buf->b_printchar(size.x+x, size.y+y, c, ch);
00205 }
00206
00207 int ht_view::buf_printf(int x, int y, int c, char *format, ...)
00208 {
00209 char buf[256];
00210 va_list arg;
00211 va_start(arg, format);
00212 ht_vsnprintf(buf, sizeof buf, format, arg);
00213 va_end(arg);
00214 return buf_print(x, y, c, buf);
00215 }
00216
00217 int ht_view::buf_printw(int x, int y, int c, int *text)
00218 {
00219 if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) {
00220 int l=vsize.x+vsize.w-x-size.x;
00221 if (size.x+x-vsize.x<0) {
00222 int kqx=-size.x-x+vsize.x;
00223 for (int i=0; i<kqx; i++) {
00224 if (!*text) return 0;
00225 text++;
00226 x++;
00227 l--;
00228 }
00229 }
00230 return (l>0) ? buf->b_lprintw(size.x+x, size.y+y, c, l, text) : 0;
00231 }
00232 return 0;
00233 }
00234
00235 int ht_view::childcount()
00236 {
00237 return 1;
00238 }
00239
00240 void ht_view::cleanview()
00241 {
00242 view_is_dirty=0;
00243 }
00244
00245 void ht_view::clear(int c)
00246 {
00247 buf->b_fill(vsize.x, vsize.y, vsize.w, vsize.h, c, ' ');
00248 }
00249
00250 void ht_view::clipbounds(bounds *b)
00251 {
00252 bounds c;
00253 getbounds(&c);
00254 bounds_and(b, &c);
00255 bounds_and(b, &vsize);
00256 }
00257
00258 void ht_view::config_changed()
00259 {
00260 reloadpalette();
00261 dirtyview();
00262 }
00263
00264 int ht_view::countselectables()
00265 {
00266 return (options & VO_SELECTABLE) ? 1 : 0;
00267 }
00268
00269 int ht_view::datasize()
00270 {
00271 return 0;
00272 }
00273
00274 char *ht_view::defaultpalette()
00275 {
00276 return palkey_generic_window_default;
00277 }
00278
00279 char *ht_view::defaultpaletteclass()
00280 {
00281 return palclasskey_generic;
00282 }
00283
00284 void ht_view::dirtyview()
00285 {
00286 view_is_dirty=1;
00287 }
00288
00289 void ht_view::disable()
00290 {
00291 enabled=0;
00292 }
00293
00294 void ht_view::disable_buffering()
00295 {
00296 if (options & VO_OWNBUFFER) {
00297 if (buf) delete buf;
00298 buf=screen;
00299 setoptions(options&(~VO_OWNBUFFER));
00300 }
00301 }
00302
00303 void ht_view::draw()
00304 {
00305 }
00306
00307 void ht_view::enable()
00308 {
00309 enabled=1;
00310 }
00311
00312 void ht_view::enable_buffering()
00313 {
00314 if (!(options & VO_OWNBUFFER)) {
00315 buf=new drawbuf(&size);
00316 setoptions(options | VO_OWNBUFFER);
00317 }
00318 }
00319
00320 bool view_line_exposed(ht_view *v, int y, int x1, int x2)
00321 {
00322 ht_group *g=v->group;
00323 while (g) {
00324 if ((y>=g->size.y) && (y<g->size.y+g->size.h)) {
00325 if (x1<g->size.x) x1=g->size.x;
00326 if (x2>g->size.x+g->size.w) x2=g->size.x+g->size.w;
00327 ht_view *n=g->first;
00328 while (n && n!=v) n=n->next;
00329 if (n) {
00330 n=n->next;
00331 if (n)
00332 while (n) {
00333 if (!(n->options & VO_TRANSPARENT_CHARS)) {
00334 if ((y>=n->size.y) && (y<n->size.y+n->size.h)) {
00335 if (n->size.x<=x1) {
00336 if (n->size.x+n->size.w>=x2) {
00337 return 0;
00338 } else if (n->size.x+n->size.w>x1) {
00339 x1=n->size.x+n->size.w;
00340 }
00341 } else if (n->size.x<=x2) {
00342 if (n->size.x+n->size.w<x2) {
00343 if (!view_line_exposed(n, y, x1, n->size.x)) return 0;
00344 x1=n->size.x+n->size.w;
00345 } else {
00346 x2=n->size.x;
00347 }
00348 }
00349 }
00350 }
00351 n=n->next;
00352 }
00353 }
00354 } else break;
00355 v=g;
00356 g=g->group;
00357 }
00358 return 1;
00359 }
00360
00361 int ht_view::enum_start()
00362 {
00363 return 0;
00364 }
00365
00366 ht_view *ht_view::enum_next(int *handle)
00367 {
00368 return 0;
00369 }
00370
00371 bool ht_view::exposed()
00372 {
00373 #if 1
00374 for (int y=0; y<size.h; y++) {
00375 if (view_line_exposed(this, size.y+y, size.x, size.x+size.w)) return 1;
00376 }
00377 return 0;
00378 #else
00379 return 1;
00380 #endif
00381 }
00382
00383 void ht_view::fill(int x, int y, int w, int h, int c, int chr)
00384 {
00385 bounds b;
00386 b.x=size.x+x;
00387 b.y=size.y+y;
00388 b.w=w;
00389 b.h=h;
00390 bounds_and(&b, &vsize);
00391 buf->b_fill(b.x, b.y, b.w, b.h, c, chr);
00392 }
00393
00394 int ht_view::focus(ht_view *view)
00395 {
00396 if (view==this) {
00397 if (!focused) receivefocus();
00398 return 1;
00399 }
00400 return 0;
00401 }
00402
00403 void ht_view::getbounds(bounds *b)
00404 {
00405 *b=size;
00406 }
00407
00408 vcp ht_view::getcolor(UINT index)
00409 {
00410 return getcolorv(&pal, index);
00411 }
00412
00413 void ht_view::getminbounds(int *width, int *height)
00414 {
00415 *width = DEFAULT_VIEW_MIN_WIDTH;
00416 *height = DEFAULT_VIEW_MIN_HEIGHT;
00417 }
00418
00419 struct databufdup_s {
00420 ht_memmap_file *f;
00421 ht_object_stream_memmap *s;
00422 };
00423
00424 void ht_view::databuf_freedup(void *handle)
00425 {
00426 databufdup_s *s=(databufdup_s*)handle;
00427
00428 s->s->done();
00429 delete s->s;
00430
00431 s->f->done();
00432 delete s->f;
00433
00434 free(s);
00435 }
00436
00437 void ht_view::databuf_get(void *buf, int bufsize)
00438 {
00439 ht_memmap_file *f=new ht_memmap_file();
00440 f->init((byte*)buf, bufsize);
00441
00442 ht_object_stream_memmap *s=new ht_object_stream_memmap();
00443 s->init(f, false);
00444
00445 getdata(s);
00446
00447 s->done();
00448 delete s;
00449
00450 f->done();
00451 delete f;
00452 }
00453
00454 void *ht_view::databuf_getdup(void *buf, int bufsize)
00455 {
00456 ht_memmap_file *f=new ht_memmap_file();
00457 f->init((byte*)buf, bufsize);
00458
00459 ht_object_stream_memmap *s=new ht_object_stream_memmap();
00460 s->init(f, true);
00461
00462 getdata(s);
00463
00464 databufdup_s *q=(databufdup_s*)malloc(sizeof (databufdup_s));
00465 q->f=f;
00466 q->s=s;
00467 return q;
00468 }
00469
00470 void ht_view::databuf_set(void *buf, int bufsize)
00471 {
00472 ht_memmap_file *f=new ht_memmap_file();
00473 f->init((byte*)buf, bufsize);
00474
00475 ht_object_stream_memmap *s=new ht_object_stream_memmap();
00476 s->init(f, false);
00477
00478 setdata(s);
00479
00480 s->done();
00481 delete s;
00482
00483 f->done();
00484 delete f;
00485 }
00486
00487 void ht_view::getdata(ht_object_stream *s)
00488 {
00489 }
00490
00491 ht_view *ht_view::getfirstchild()
00492 {
00493 return 0;
00494 }
00495
00496 UINT ht_view::getnumber()
00497 {
00498 return 0;
00499 }
00500
00501 char *ht_view::getpalette()
00502 {
00503 return pal_name;
00504 }
00505
00506 ht_view *ht_view::getselected()
00507 {
00508 return this;
00509 }
00510
00511 void ht_view::handlemsg(htmsg *msg)
00512 {
00513 switch (msg->msg) {
00514 case msg_draw:
00515 redraw();
00516 return;
00517 case msg_dirtyview:
00518 dirtyview();
00519 if (msg->type & mt_broadcast==0) clearmsg(msg);
00520 return;
00521 case msg_config_changed:
00522 config_changed();
00523
00524 return;
00525 }
00526 }
00527
00528 void ht_view::hidecursor()
00529 {
00530 screen->hidecursor();
00531 }
00532
00533 int ht_view::isalone(ht_view *view)
00534 {
00535 return (view==this) && (countselectables()==1);
00536 }
00537
00538 int ht_view::isviewdirty()
00539 {
00540 return view_is_dirty;
00541 }
00542
00543 int ht_view::load(ht_object_stream *s)
00544 {
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 return 1;
00556 }
00557
00558 void ht_view::move(int rx, int ry)
00559 {
00560 size.x+=rx;
00561 size.y+=ry;
00562 buf->b_rmove(rx, ry);
00563 vsize=size;
00564 if (group) group->clipbounds(&vsize);
00565 app->clipbounds(&vsize);
00566 }
00567
00568 OBJECT_ID ht_view::object_id() const
00569 {
00570 return ATOM_HT_VIEW;
00571 }
00572
00573 int ht_view::pointvisible(int x, int y)
00574 {
00575 return ((x>=vsize.x) && (y>=vsize.y) && (x<vsize.x+vsize.w) && (y<vsize.y+vsize.h));
00576 }
00577
00578 void ht_view::receivefocus()
00579 {
00580 dirtyview();
00581 focused=1;
00582 }
00583
00584 void ht_view::redraw()
00585 {
00586 if (exposed()) {
00587 if (options & VO_OWNBUFFER) {
00588 if (isviewdirty()) {
00589 draw();
00590 cleanview();
00591 }
00592 screen->drawbuffer((drawbuf*)buf, size.x, size.y, &vsize);
00593 } else {
00594 draw();
00595 cleanview();
00596 }
00597 }
00598 }
00599
00600 void ht_view::resize(int sx, int sy)
00601 {
00602 if (options & VO_RESIZE) {
00603 if (size.w+sx <= 0) sx=-size.w+1;
00604 if (size.h+sy <= 0) sy=-size.h+1;
00605 size.w+=sx;
00606 size.h+=sy;
00607 buf->b_resize(sx, sy);
00608 }
00609 vsize = size;
00610 if (group) group->clipbounds(&vsize);
00611 app->clipbounds(&vsize);
00612 }
00613
00614 void ht_view::releasefocus()
00615 {
00616 dirtyview();
00617 hidecursor();
00618 focused=0;
00619 }
00620
00621 void ht_view::reloadpalette()
00622 {
00623 if (pal.data) {
00624 free(pal.data);
00625 pal.data=0;
00626 }
00627 load_pal(pal_class, pal_name, &pal);
00628 }
00629
00630 void ht_view::relocate_to(ht_view *view)
00631 {
00632 bounds b;
00633 view->getbounds(&b);
00634 move(b.x, b.y);
00635 }
00636
00637 int ht_view::select(ht_view *view)
00638 {
00639 return (view==this);
00640 }
00641
00642 void ht_view::selectfirst()
00643 {
00644 }
00645
00646 void ht_view::selectlast()
00647 {
00648 }
00649
00650 void ht_view::sendmsg(htmsg *msg)
00651 {
00652 if (enabled) handlemsg(msg);
00653 }
00654
00655 void ht_view::sendmsg(int msg, void *data1, void *data2)
00656 {
00657 htmsg m;
00658 m.msg=msg;
00659 m.type=mt_empty;
00660 m.data1.ptr=data1;
00661 m.data2.ptr=data2;
00662 sendmsg(&m);
00663 }
00664
00665 void ht_view::sendmsg(int msg, int data1, int data2)
00666 {
00667 htmsg m;
00668 switch (msg) {
00669 case msg_empty:
00670 return;
00671 case msg_draw:
00672 case msg_dirtyview:
00673 m.msg=msg;
00674 m.type=mt_broadcast;
00675 m.data1.integer=data1;
00676 m.data2.integer=data2;
00677 break;
00678 default:
00679 m.msg=msg;
00680 m.type=mt_empty;
00681 m.data1.integer=data1;
00682 m.data2.integer=data2;
00683 break;
00684 }
00685 sendmsg(&m);
00686 }
00687
00688 void ht_view::setbounds(bounds *b)
00689 {
00690 size=*b;
00691 setvisualbounds(&size);
00692 }
00693
00694 void ht_view::setvisualbounds(bounds *b)
00695 {
00696 vsize=*b;
00697 if (options & VO_OWNBUFFER) {
00698 buf->b_setbounds(b);
00699 }
00700 }
00701
00702 void ht_view::setcursor(int x, int y, cursor_mode c)
00703 {
00704 if (pointvisible(size.x+x, size.y+y)) {
00705 screen->setcursor(size.x+x, size.y+y);
00706 switch (c) {
00707 case cm_normal:
00708 screen->setcursormode(0);
00709 break;
00710 case cm_overwrite:
00711 screen->setcursormode(1);
00712 break;
00713 }
00714 } else {
00715 screen->hidecursor();
00716 }
00717 }
00718
00719 void ht_view::setdata(ht_object_stream *s)
00720 {
00721 }
00722
00723 void ht_view::setgroup(ht_group *_group)
00724 {
00725 group=_group;
00726 }
00727
00728 void ht_view::setnumber(UINT number)
00729 {
00730 }
00731
00732 void ht_view::setoptions(int Options)
00733 {
00734 options = Options;
00735 }
00736
00737 void ht_view::setpalette(char *Pal_name)
00738 {
00739 pal_name = Pal_name;
00740 reloadpalette();
00741 }
00742
00743 void ht_view::setpalettefull(char *_pal_name, char *_pal_class)
00744 {
00745 pal_class=_pal_class;
00746 setpalette(pal_name);
00747 }
00748
00749 void ht_view::store(ht_object_stream *s)
00750 {
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 }
00762
00763 void ht_view::unrelocate_to(ht_view *view)
00764 {
00765 bounds b;
00766 view->getbounds(&b);
00767 b.x=-b.x;
00768 b.y=-b.y;
00769 move(b.x, b.y);
00770 }
00771
00772
00773
00774
00775
00776 void ht_group::init(bounds *b, int options, const char *desc)
00777 {
00778 first=0;
00779 current=0;
00780 last=0;
00781 ht_view::init(b, options, desc);
00782 VIEW_DEBUG_NAME("ht_group");
00783 view_count=0;
00784 shared_data=0;
00785
00786 growmode = MK_GM(GMH_FIT, GMV_FIT);
00787 }
00788
00789 void ht_group::done()
00790 {
00791 ht_view *a, *b;
00792 a=first;
00793 while (a) {
00794 b=a->next;
00795 a->done();
00796 delete a;
00797 a=b;
00798 }
00799 ht_view::done();
00800 }
00801
00802 int ht_group::childcount()
00803 {
00804 return view_count;
00805 }
00806
00807 int ht_group::countselectables()
00808 {
00809 int c=0;
00810 ht_view *v=first;
00811 while (v) {
00812 c+=v->countselectables();
00813 v=v->next;
00814 }
00815 return c;
00816 }
00817
00818 int ht_group::datasize()
00819 {
00820 UINT size=0;
00821 ht_view *v=first;
00822 while (v) {
00823 size+=v->datasize();
00824 v=v->next;
00825 }
00826 return size;
00827 }
00828
00829 int ht_group::enum_start()
00830 {
00831 return -1;
00832 }
00833
00834 ht_view *ht_group::enum_next(int *handle)
00835 {
00836 int lowest=0x7fffffff;
00837 ht_view *view=0;
00838
00839 ht_view *v=first;
00840 while (v) {
00841 if ((v->browse_idx > *handle) && (v->browse_idx < lowest)) {
00842 lowest=v->browse_idx;
00843 view=v;
00844 }
00845 v=v->next;
00846 }
00847 *handle=lowest;
00848 return view;
00849 }
00850
00851 int ht_group::focus(ht_view *view)
00852 {
00853 ht_view *v=first;
00854 while (v) {
00855 if (v->focus(view)) {
00856 releasefocus();
00857 current=v;
00858 putontop(v);
00859 receivefocus();
00860 return 1;
00861 }
00862 v=v->next;
00863 }
00864 return ht_view::focus(view);
00865 }
00866
00867 int ht_group::focusnext()
00868 {
00869 int i=current->browse_idx;
00870 int r=(options & VO_SELBOUND);
00871 ht_view *x=NULL;
00872 while (1) {
00873 i++;
00874 if (i>view_count-1) i=0;
00875 if (i==current->browse_idx) break;
00876 ht_view *v=get_by_browse_idx(i);
00877 if (v && (v->options & VO_SELECTABLE)) {
00878 x=v;
00879 break;
00880 }
00881 }
00882 if ((i < current->browse_idx) && !alone() && !r) {
00883 return 0;
00884 }
00885 if (x) {
00886 x->selectfirst();
00887 focus(x);
00888 return 1;
00889 }
00890 return r;
00891 }
00892
00893 int ht_group::focusprev()
00894 {
00895 int i=current->browse_idx;
00896 int r=(options & VO_SELBOUND);
00897 if (!i && !alone() && !r) {
00898 return 0;
00899 }
00900 while (1) {
00901 i--;
00902 if (i<0) i=view_count-1;
00903 if (i==current->browse_idx) break;
00904 ht_view *v=get_by_browse_idx(i);
00905 if (v && (v->options & VO_SELECTABLE)) {
00906 v->selectlast();
00907 focus(v);
00908 return 1;
00909 }
00910 }
00911 return r;
00912 }
00913
00914 ht_view *ht_group::get_by_browse_idx(int i)
00915 {
00916 ht_view *v=first;
00917 while (v) {
00918 if (v->browse_idx==i) return v;
00919 v=v->next;
00920 }
00921 return 0;
00922 }
00923
00924 void ht_group::getdata(ht_object_stream *s)
00925 {
00926 ht_view *v;
00927 int h=enum_start();
00928 while ((v=enum_next(&h))) {
00929 v->getdata(s);
00930 }
00931 }
00932
00933 ht_view *ht_group::getselected()
00934 {
00935 if (current) return current->getselected(); else return 0;
00936 }
00937
00938 ht_view *ht_group::getfirstchild()
00939 {
00940 return first;
00941 }
00942
00943 void ht_group::handlemsg(htmsg *msg)
00944 {
00945 if (!enabled) return;
00946 if (msg->type==mt_broadcast) {
00947 ht_view::handlemsg(msg);
00948 ht_view *v=first;
00949 while (v) {
00950 v->handlemsg(msg);
00951 v=v->next;
00952 }
00953 } else if (msg->type==mt_empty) {
00954 int msgtype=msg->type;
00955 ht_view *v;
00956
00957 msg->type=mt_preprocess;
00958 v=first;
00959 while (v) {
00960 if (v->options & VO_PREPROCESS) {
00961 v->handlemsg(msg);
00962 }
00963 v=v->next;
00964 }
00965
00966 msg->type=mt_empty;
00967 if (current) current->handlemsg(msg);
00968
00969 msg->type=mt_postprocess;
00970 v=first;
00971 while (v) {
00972 if (v->options & VO_POSTPROCESS) {
00973 v->handlemsg(msg);
00974 }
00975 v=v->next;
00976 }
00977
00978 msg->type=msgtype;
00979 ht_view::handlemsg(msg);
00980 } else if (msg->type==mt_preprocess) {
00981 ht_view *v;
00982
00983 v=first;
00984 while (v) {
00985 if (v->options & VO_PREPROCESS) {
00986 v->handlemsg(msg);
00987 }
00988 v=v->next;
00989 }
00990 } else if (msg->type==mt_postprocess) {
00991 ht_view *v;
00992
00993 v=first;
00994 while (v) {
00995 if (v->options & VO_POSTPROCESS) {
00996 v->handlemsg(msg);
00997 }
00998 v=v->next;
00999 }
01000 }
01001
01002 if (((msg->type==mt_empty) || (msg->type==mt_broadcast)) && (msg->msg==msg_keypressed)) {
01003 switch (msg->data1.integer) {
01004 case K_Left:
01005 case K_BackTab: {
01006 if (focusprev()) {
01007 clearmsg(msg);
01008 dirtyview();
01009 return;
01010 }
01011 break;
01012 }
01013 case K_Right:
01014 case K_Tab: {
01015 if (focusnext()) {
01016 clearmsg(msg);
01017 dirtyview();
01018 return;
01019 }
01020 break;
01021 }
01022 }
01023 }
01024 }
01025
01026 void ht_group::insert(ht_view *view)
01027 {
01028 if (current) current->releasefocus();
01029 if (view->options & VO_PREPROCESS) setoptions(options | VO_PREPROCESS);
01030 if (view->options & VO_POSTPROCESS) setoptions(options | VO_POSTPROCESS);
01031 if (view->pal_class && pal_class && strcmp(view->pal_class, pal_class)==0) view->setpalette(pal_name);
01032
01033 view->g_hdist=size.w - (view->size.x+view->size.w);
01034 view->g_vdist=size.h - (view->size.y+view->size.h);
01035
01036 bounds c;
01037 getbounds(&c);
01038 view->move(c.x, c.y);
01039
01040 if (last) last->next=view;
01041 view->prev=last;
01042 view->next=0;
01043 last=view;
01044 if (!first) first=view;
01045 view->setgroup(this);
01046 view->browse_idx=view_count++;
01047 if ((!current) || ((current) && (!(current->options & VO_SELECTABLE)) && (view->options & VO_SELECTABLE))) {
01048 current=view;
01049 }
01050 if ((current) && (current->options & VO_SELECTABLE)) {
01051 if (focused) {
01052 focus(current);
01053 } else {
01054 select(current);
01055 }
01056 }
01057 }
01058
01059 int ht_group::isalone(ht_view *view)
01060 {
01061 ht_view *v=first;
01062 while (v) {
01063 if ((v!=view) && (v->countselectables())) return 0;
01064 v=v->next;
01065 }
01066 return 1;
01067 }
01068
01069 int ht_group::isviewdirty()
01070 {
01071 ht_view *v=first;
01072 while (v) {
01073 if (v->isviewdirty()) return 1;
01074 v=v->next;
01075 }
01076 return 0;
01077 }
01078
01079 int ht_group::load(ht_object_stream *f)
01080 {
01081 return 1;
01082 }
01083
01084 void ht_group::move(int rx, int ry)
01085 {
01086 ht_view::move(rx, ry);
01087 ht_view *v=first;
01088 while (v) {
01089 v->move(rx, ry);
01090 v=v->next;
01091 }
01092 }
01093
01094 OBJECT_ID ht_group::object_id() const
01095 {
01096 return ATOM_HT_GROUP;
01097 }
01098
01099 void ht_group::putontop(ht_view *view)
01100 {
01101 if (view->next) {
01102 if (view->prev) view->prev->next=view->next; else first=view->next;
01103 view->next->prev=view->prev;
01104 view->prev=last;
01105 view->next=0;
01106 last->next=view;
01107 last=view;
01108 }
01109 }
01110
01111 void ht_group::receivefocus()
01112 {
01113 ht_view::receivefocus();
01114 if (current) current->receivefocus();
01115 }
01116
01117 void ht_group::releasefocus()
01118 {
01119 ht_view::releasefocus();
01120 if (current)
01121 current->releasefocus();
01122 }
01123
01124 void ht_group::remove(ht_view *view)
01125 {
01126 ht_view *n=view->next ? view->next : view->prev;
01127 if (n) focus(n); else {
01128 releasefocus();
01129 current=0;
01130 }
01131
01132 bounds c;
01133 getbounds(&c);
01134 view->move(-c.x, -c.y);
01135
01136 if (view->prev) view->prev->next=view->next;
01137 if (view->next) view->next->prev=view->prev;
01138 if (first==view) first=first->next;
01139 if (last==view) last=last->prev;
01140 }
01141
01142 void ht_group::reorder_view(ht_view *v, int rx, int ry)
01143 {
01144 int px=0, py=0;
01145 int sx=0, sy=0;
01146
01147 int gmv = GET_GM_V(v->growmode);
01148 int gmh = GET_GM_H(v->growmode);
01149 switch (gmh) {
01150 case GMH_LEFT:
01151
01152 break;
01153 case GMH_RIGHT:
01154 px = rx;
01155 break;
01156 case GMH_FIT:
01157 sx = rx;
01158 break;
01159 }
01160
01161 switch (gmv) {
01162 case GMV_TOP:
01163
01164 break;
01165 case GMV_BOTTOM:
01166 py = ry;
01167 break;
01168 case GMV_FIT:
01169 sy = ry;
01170 break;
01171 }
01172
01173 v->move(px, py);
01174 v->resize(sx, sy);
01175 }
01176
01177 void ht_group::resize(int rx, int ry)
01178 {
01179 ht_view::resize(rx, ry);
01180
01181 ht_view *v = first;
01182 while (v) {
01183 reorder_view(v, rx, ry);
01184 v = v->next;
01185 }
01186 }
01187
01188 int ht_group::select(ht_view *view)
01189 {
01190 ht_view *v=first;
01191 while (v) {
01192 if (v->select(view)) {
01193 current=v;
01194 putontop(v);
01195 return 1;
01196 }
01197 v=v->next;
01198 }
01199 return ht_view::select(view);
01200 }
01201
01202 void ht_group::selectfirst()
01203 {
01204 for (int i=0; i<view_count; i++) {
01205 ht_view *v=first;
01206 while (v) {
01207 if ((v->browse_idx==i) && (v->options & VO_SELECTABLE)) {
01208 select(v);
01209 return;
01210 }
01211 v=v->next;
01212 }
01213 }
01214 }
01215
01216 void ht_group::selectlast()
01217 {
01218 for (int i=view_count-1; i>=0; i--) {
01219 ht_view *v=first;
01220 while (v) {
01221 if ((v->browse_idx==i) && (v->options & VO_SELECTABLE)) {
01222 select(v);
01223 return;
01224 }
01225 v=v->next;
01226 }
01227 }
01228 }
01229
01230 void ht_group::setdata(ht_object_stream *s)
01231 {
01232 ht_view *v;
01233 int h=enum_start();
01234 while ((v=enum_next(&h))) {
01235 v->setdata(s);
01236 }
01237 }
01238
01239 void ht_group::setpalette(char *pal_name)
01240 {
01241 ht_view *v=first;
01242 while (v) {
01243 if (strcmp(pal_class, v->pal_class)==0) v->setpalette(pal_name);
01244 v=v->next;
01245 }
01246 ht_view::setpalette(pal_name);
01247 }
01248
01249 void ht_group::store(ht_object_stream *s)
01250 {
01251 ht_view::store(s);
01252 s->putIntDec(childcount(), 4, NULL);
01253 ht_view *v=first;
01254 while (v) {
01255 s->putObject(v, NULL);
01256 v=v->next;
01257 }
01258 }
01259
01260
01261
01262
01263
01264 void ht_xgroup::init(bounds *b, int options, const char *desc)
01265 {
01266 ht_group::init(b, options, desc);
01267 VIEW_DEBUG_NAME("ht_xgroup");
01268 first=0;
01269 current=0;
01270 last=0;
01271 }
01272
01273 void ht_xgroup::done()
01274 {
01275 ht_group::done();
01276 }
01277
01278 int ht_xgroup::countselectables()
01279 {
01280 return current->countselectables();
01281 }
01282
01283 void ht_xgroup::handlemsg(htmsg *msg)
01284 {
01285 if ((msg->msg!=msg_draw) && (msg->type==mt_broadcast)) {
01286 ht_group::handlemsg(msg);
01287 } else {
01288 if (msg->msg==msg_complete_init) return;
01289 if (current) current->handlemsg(msg);
01290 ht_view::handlemsg(msg);
01291 }
01292 }
01293
01294 int ht_xgroup::isalone(ht_view *view)
01295 {
01296 if (group) return group->isalone(this);
01297 return 0;
01298 }
01299
01300 int ht_xgroup::load(ht_object_stream *s)
01301 {
01302 return ht_group::load(s);
01303 }
01304
01305 OBJECT_ID ht_xgroup::object_id() const
01306 {
01307 return ATOM_HT_XGROUP;
01308 }
01309
01310 void ht_xgroup::redraw()
01311 {
01312 ht_view::redraw();
01313
01314 if (current) current->redraw();
01315 }
01316
01317 void ht_xgroup::selectfirst()
01318 {
01319 current->selectfirst();
01320 }
01321
01322 void ht_xgroup::selectlast()
01323 {
01324 current->selectlast();
01325 }
01326
01327 void ht_xgroup::store(ht_object_stream *s)
01328 {
01329 ht_group::store(s);
01330 }
01331
01332
01333
01334
01335
01336 bool scrollbar_pos(int start, int size, int all, int *pstart, int *psize)
01337 {
01338 if (!all) return false;
01339 if (start+size >= all) {
01340 if (size >= all) return false;
01341 *psize = (int)(((double)size)*100/all);
01342 *pstart = 100-*psize;
01343 } else {
01344 *psize = (int)(((double)size)*100/all);
01345 *pstart = (int)(((double)start)*100/all);
01346 }
01347 return true;
01348 }
01349
01350 void ht_scrollbar::init(bounds *b, palette *p, bool isv)
01351 {
01352 ht_view::init(b, VO_RESIZE, 0);
01353 VIEW_DEBUG_NAME("ht_scrollbar");
01354
01355 pstart = 0;
01356 psize = 0;
01357
01358 gpal = p;
01359
01360 isvertical = isv;
01361
01362 if (isvertical) {
01363 growmode = MK_GM(GMH_RIGHT, GMV_FIT);
01364 } else {
01365 growmode = MK_GM(GMH_FIT, GMV_BOTTOM);
01366 }
01367
01368 enable();
01369 }
01370
01371 void ht_scrollbar::done()
01372 {
01373 ht_view::done();
01374 }
01375
01376 void ht_scrollbar::enable()
01377 {
01378 enable_buffering();
01379 ht_view::enable();
01380 dirtyview();
01381 }
01382
01383 void ht_scrollbar::disable()
01384 {
01385 disable_buffering();
01386 ht_view::disable();
01387 dirtyview();
01388 }
01389
01390 void ht_scrollbar::draw()
01391 {
01392 if (enabled) {
01393 vcp color = getcolorv(gpal, palidx_generic_scrollbar);
01394
01395 if (isvertical) {
01396 fill(0, 1, size.w, size.h-2, color, ' ');
01397 int e, s;
01398 e=((size.h-2)*psize)/100;
01399 if (pstart+psize>=100) {
01400 s=size.h-2-e;
01401 } else {
01402 s=((size.h-2)*pstart)/100;
01403 }
01404 if (!e) {
01405 if (s==size.h-2) s--;
01406 e=1;
01407 }
01408 fill(0, s+1, 1, e, color, CHAR_FILLED_M);
01409 buf_printchar(0, 0, color, CHAR_ARROWBIG_UP);
01410 buf_printchar(0, size.h-1, color, CHAR_ARROWBIG_DOWN);
01411 } else {
01412 }
01413 }
01414 }
01415
01416 int ht_scrollbar::load(ht_object_stream *s)
01417 {
01418 return 1;
01419 }
01420
01421 OBJECT_ID ht_scrollbar::object_id() const
01422 {
01423 return ATOM_HT_SCROLLBAR;
01424 }
01425
01426 void ht_scrollbar::setpos(int ps, int pz)
01427 {
01428 pstart=ps;
01429 psize=pz;
01430 dirtyview();
01431 }
01432
01433 void ht_scrollbar::store(ht_object_stream *s)
01434 {
01435 }
01436
01437
01438
01439
01440
01441 void ht_frame::init(bounds *b, const char *desc, UINT s, UINT n)
01442 {
01443 ht_view::init(b, VO_RESIZE, desc);
01444 VIEW_DEBUG_NAME("ht_frame");
01445
01446 number = n;
01447 style = s;
01448 framestate = FST_UNFOCUSED;
01449
01450 growmode = MK_GM(GMH_FIT, GMV_FIT);
01451 }
01452
01453 void ht_frame::done()
01454 {
01455 ht_view::done();
01456 }
01457
01458 void ht_frame::draw()
01459 {
01460 int cornerul, cornerur, cornerll, cornerlr;
01461 int lineh, linev;
01462 ht_window *w=(ht_window*)group;
01463 if ((framestate!=FST_MOVE) && (framestate!=FST_RESIZE)) {
01464 if (w->focused) setframestate(FST_FOCUSED); else
01465 setframestate(FST_UNFOCUSED);
01466 }
01467 if (style & FS_THICK) {
01468 cornerul=CHAR_CORNERUL_DBL;
01469 cornerur=CHAR_CORNERUR_DBL;
01470 cornerll=CHAR_CORNERLL_DBL;
01471 cornerlr=CHAR_CORNERLR_DBL;
01472 lineh=CHAR_LINEH_DBL;
01473 linev=CHAR_LINEV_DBL;
01474 } else {
01475 cornerul=CHAR_CORNERUL;
01476 cornerur=CHAR_CORNERUR;
01477 cornerll=CHAR_CORNERLL;
01478 cornerlr=CHAR_CORNERLR;
01479 lineh=CHAR_LINEH;
01480 linev=CHAR_LINEV;
01481 }
01482
01483 vcp c=getcurcol_normal();
01484
01485 buf_printchar(0, 0, c, cornerul);
01486 for (int i=1; i<size.w-1; i++) buf_printchar(i, 0, c, lineh);
01487 buf_printchar(0+size.w-1, 0, c, cornerur);
01488
01489 buf_printchar(0, size.h-1, c, cornerll);
01490 for (int i=1; i<size.w-1; i++) buf_printchar(i, size.h-1, c, lineh);
01491
01492
01493
01494 buf_printchar(size.w-1, size.h-1, c, cornerlr);
01495
01496
01497 for (int i=1; i<size.h-1; i++) {
01498 buf_printchar(0, i, c, linev);
01499 buf_printchar(size.w-1, i, c, linev);
01500 }
01501
01502 if (style & FS_KILLER) {
01503 buf_print(2, 0, c, "[ ]");
01504 buf_printchar(3, 0, getcurcol_killer(), CHAR_QUAD_SMALL);
01505 }
01506
01507 int ns=0;
01508 if (style & FS_NUMBER) {
01509 int l=number;
01510 do {
01511 l=l/10;
01512 ns++;
01513 } while (l);
01514 buf_printf(size.w-4-ns, 0, c, "%d", number);
01515 ns+=4;
01516 }
01517
01518 char *d;
01519 switch (framestate) {
01520 case FST_MOVE:
01521 d = (char*)((style & FS_RESIZE) ? "(moving) - hit space to resize" : "(moving)");
01522 break;
01523 case FST_RESIZE:
01524 d = (char*)((style & FS_MOVE) ? "(resizing) - hit space to move" : "(resizing)");
01525 break;
01526 default:
01527 d = desc;
01528 }
01529 int ks = (style & FS_KILLER) ? 4 : 0;
01530 ns++;
01531 if ((d) && (style & FS_TITLE)) {
01532 int l = strlen(d), k = 0;
01533 if (l > size.w-(5+ks+ns)) {
01534 k = l-(size.w-(6+ks+ns+2));
01535 if (size.w > 6+ks+ns+2) {
01536 d+=k;
01537 } else d="";
01538 buf_printf(2+ks, 0, c, " ...%s ", d);
01539 } else {
01540 buf_printf((size.w-l-2)/2, 0, c, " %s ", d);
01541 }
01542 }
01543 }
01544
01545 vcp ht_frame::getcurcol_normal()
01546 {
01547 switch (framestate) {
01548 case FST_FOCUSED:
01549 return getcolor(palidx_generic_frame_focused);
01550 case FST_UNFOCUSED:
01551 return getcolor(palidx_generic_frame_unfocused);
01552 case FST_MOVE:
01553 case FST_RESIZE:
01554 return getcolor(palidx_generic_frame_move_resize);
01555 }
01556 return 0;
01557 }
01558
01559 vcp ht_frame::getcurcol_killer()
01560 {
01561 return getcolor(palidx_generic_frame_killer);
01562 }
01563
01564 UINT ht_frame::getnumber()
01565 {
01566 return number;
01567 }
01568
01569 UINT ht_frame::getstyle()
01570 {
01571 return style;
01572 }
01573
01574 int ht_frame::load(ht_object_stream *s)
01575 {
01576 return ht_view::load(s);
01577 }
01578
01579 OBJECT_ID ht_frame::object_id() const
01580 {
01581 return ATOM_HT_FRAME;
01582 }
01583
01584 void ht_frame::setframestate(UINT _framestate)
01585 {
01586 framestate=_framestate;
01587 dirtyview();
01588 }
01589
01590 void ht_frame::setnumber(UINT _number)
01591 {
01592 number=_number;
01593 dirtyview();
01594 }
01595
01596 void ht_frame::setstyle(UINT s)
01597 {
01598 style=s;
01599 }
01600
01601 void ht_frame::settext(const char *text)
01602 {
01603 if (desc) free(desc);
01604 desc = ht_strdup(text);
01605 dirtyview();
01606 }
01607
01608 void ht_frame::store(ht_object_stream *s)
01609 {
01610 ht_view::store(s);
01611 }
01612
01613
01614
01615
01616
01617 void ht_window::init(bounds *b, const char *desc, UINT framestyle, UINT num)
01618 {
01619 ht_group::init(b, VO_SELECTABLE | VO_SELBOUND | VO_BROWSABLE, desc);
01620 VIEW_DEBUG_NAME("ht_window");
01621 number=num;
01622 hscrollbar=NULL;
01623 vscrollbar=NULL;
01624 pindicator=NULL;
01625 bounds c=*b;
01626 c.x=0;
01627 c.y=0;
01628 frame=0;
01629 action_state=WAC_NORMAL;
01630 ht_frame *f=new ht_frame();
01631 f->init(&c, desc, framestyle, number);
01632 setframe(f);
01633 }
01634
01635 void ht_window::done()
01636 {
01637 pindicator=NULL;
01638 hscrollbar=NULL;
01639 vscrollbar=NULL;
01640 ht_group::done();
01641 }
01642
01643 void ht_window::draw()
01644 {
01645 vcp c=getcolor(palidx_generic_body);
01646 clear(c);
01647 }
01648
01649 void ht_window::getclientarea(bounds *b)
01650 {
01651 getbounds(b);
01652 if (frame) {
01653 b->x++;
01654 b->y++;
01655 b->w-=2;
01656 b->h-=2;
01657 }
01658 }
01659
01660 UINT ht_window::getnumber()
01661 {
01662 return number;
01663 }
01664
01665 ht_frame *ht_window::getframe()
01666 {
01667 return frame;
01668 }
01669
01670 void ht_window::handlemsg(htmsg *msg)
01671 {
01672 switch (msg->msg) {
01673 case msg_keypressed:
01674 if (action_state==WAC_MOVE) {
01675 if (options & VO_MOVE) {
01676 switch (msg->data1.integer) {
01677 case K_Up:
01678 if (size.y>group->size.y) move(0, -1);
01679 break;
01680 case K_Down:
01681 if (size.y<group->size.y+group->size.h-1) move(0, 1);
01682 break;
01683 case K_Left:
01684 if (size.x+size.w>group->size.x+1) move(-1, 0);
01685 break;
01686 case K_Right:
01687 if (size.x<group->size.x+group->size.w-1) move(1, 0);
01688 break;
01689 case K_Control_Up:
01690 if (size.y>group->size.y+5-1) move(0, -5); else
01691 move(0, group->size.y-size.y);
01692 break;
01693 case K_Control_Down:
01694 if (size.y<group->size.y+group->size.h-5) move(0, 5); else
01695 move(0, group->size.y+group->size.h-size.y-1);
01696 break;
01697 case K_Control_Left:
01698 if (size.x+size.w>group->size.x+5) move(-5, 0); else
01699 move(-(size.x+size.w)+group->size.x+1, 0);
01700 break;
01701 case K_Control_Right:
01702 if (size.x<group->size.x+group->size.w-5) move(5, 0); else
01703 move(group->size.x+group->size.w-size.x-1, 0);
01704 break;
01705 }
01706 }
01707 } else if (action_state==WAC_RESIZE) {
01708 if (options & VO_RESIZE) {
01709 int min_width, min_height;
01710 getminbounds(&min_width, &min_height);
01711 switch (msg->data1.integer) {
01712 case K_Up:
01713 if (size.h > min_height) resize(0, -1);
01714 break;
01715 case K_Down:
01716 if (size.h < group->size.h) resize(0, 1);
01717 break;
01718 case K_Left:
01719 if ((size.x+size.w>1) && (size.w > min_width)) resize(-1, 0);
01720 break;
01721 case K_Right:
01722 if (size.w<group->size.w) resize(1, 0);
01723 break;
01724 }
01725 }
01726 } else {
01727 if ((msg->data1.integer == K_Control_F5) ||
01728 (msg->data1.integer == K_Control_R)) {
01729 sendmsg(cmd_window_resizemove);
01730 }
01731 break;
01732 }
01733 switch (msg->data1.integer) {
01734 case K_Escape:
01735 case K_Return:
01736 sendmsg(cmd_window_resizemove);
01737 break;
01738 case K_Space:
01739 case K_Control_F5:
01740 sendmsg(cmd_window_switch_resizemove);
01741 break;
01742 }
01743 app->sendmsg(msg_dirtyview, 0);
01744 clearmsg(msg);
01745 return;
01746 case cmd_window_resizemove: {
01747 bool b = (action_state == WAC_NORMAL);
01748 do {
01749 if (!next_action_state()) break;
01750 } while (b == (action_state == WAC_NORMAL));
01751 dirtyview();
01752 clearmsg(msg);
01753 return;
01754 }
01755 case cmd_window_switch_resizemove:
01756 do {
01757 if (!next_action_state()) break;
01758 } while (action_state == WAC_NORMAL);
01759 dirtyview();
01760 clearmsg(msg);
01761 return;
01762 }
01763 ht_group::handlemsg(msg);
01764 }
01765
01766 void ht_window::insert(ht_view *view)
01767 {
01768 if (frame) view->move(1, 1);
01769 ht_group::insert(view);
01770 }
01771
01772 int ht_window::load(ht_object_stream *s)
01773 {
01774 if (ht_group::load(s)!=0) return 1;
01775 return s->get_error();
01776 }
01777
01778 bool ht_window::next_action_state()
01779 {
01780 #define wstate_count 3
01781 int ass[wstate_count] = { WAC_NORMAL, WAC_MOVE, WAC_RESIZE };
01782 int fss[wstate_count] = { FST_FOCUSED, FST_MOVE, FST_RESIZE };
01783 for (int i=0; i < wstate_count; i++) {
01784 if (action_state == ass[i]) {
01785 int p = i;
01786 while (++p != i) {
01787 if (p > wstate_count-1) p = 0;
01788 bool allowed = true;
01789 switch (ass[p]) {
01790 case WAC_MOVE: allowed = ((options & VO_MOVE) != 0); break;
01791 case WAC_RESIZE: allowed = ((options & VO_RESIZE) != 0); break;
01792 }
01793 if (allowed) {
01794 action_state = ass[p];
01795 if (frame) frame->setframestate(fss[p]);
01796 return (p != i);
01797 }
01798 }
01799 return false;
01800 }
01801 }
01802 return false;
01803 }
01804
01805 OBJECT_ID ht_window::object_id() const
01806 {
01807 return ATOM_HT_WINDOW;
01808 }
01809
01810 void ht_window::receivefocus()
01811 {
01812 htmsg m;
01813 m.msg = msg_contextmenuquery;
01814 m.type = mt_empty;
01815 sendmsg(&m);
01816 ht_menu *q = (ht_menu*)((ht_app*)app)->menu;
01817 if (m.msg == msg_retval) {
01818 ht_context_menu *n = (ht_context_menu*)m.data1.ptr;
01819 if (q) {
01820 if (!q->set_local_menu(n)) {
01821 n->done();
01822 delete n;
01823 }
01824 q->sendmsg(msg_dirtyview);
01825 } else {
01826 n->done();
01827 delete n;
01828 }
01829 }
01830
01831 ht_group::receivefocus();
01832 if (frame) frame->setstyle(frame->getstyle() | FS_THICK);
01833 }
01834
01835 void ht_window::redraw()
01836 {
01837 htmsg m;
01838
01839 char buf[256];
01840 buf[0]=0;
01841
01842 m.msg = msg_get_scrollinfo;
01843 m.type = mt_empty;
01844 m.data1.integer = gsi_pindicator;
01845 m.data2.ptr = buf;
01846 sendmsg(&m);
01847
01848 if (pindicator) pindicator->settext(buf);
01849
01850 gsi_scrollbar_t p;
01851
01852 p.pstart = 0;
01853 p.psize = 200;
01854 m.msg = msg_get_scrollinfo;
01855 m.type = mt_empty;
01856 m.data1.integer = gsi_hscrollbar;
01857 m.data2.ptr = &p;
01858 sendmsg(&m);
01859
01860 if (hscrollbar) {
01861 if (p.psize>=100) {
01862 hscrollbar->disable();
01863 } else {
01864 hscrollbar->enable();
01865 hscrollbar->setpos(p.pstart, p.psize);
01866 }
01867 }
01868
01869 p.pstart = 0;
01870 p.psize = 200;
01871 m.msg = msg_get_scrollinfo;
01872 m.type = mt_empty;
01873 m.data1.integer = gsi_vscrollbar;
01874 m.data2.ptr = &p;
01875 sendmsg(&m);
01876
01877 if (vscrollbar) {
01878 if (p.psize>=100) {
01879 vscrollbar->disable();
01880 } else {
01881 vscrollbar->enable();
01882 vscrollbar->setpos(p.pstart, p.psize);
01883 }
01884 }
01885
01886 ht_group::redraw();
01887 }
01888
01889 void ht_window::releasefocus()
01890 {
01891 ht_menu *q = (ht_menu*)((ht_app*)app)->menu;
01892 if (q) {
01893 q->delete_local_menu();
01894 q->sendmsg(msg_dirtyview);
01895 }
01896
01897 if (frame) frame->setstyle(frame->getstyle() & (~FS_THICK));
01898 ht_group::releasefocus();
01899 }
01900
01901 void ht_window::resize(int rw, int rh)
01902 {
01903 ht_group::resize(rw, rh);
01904 }
01905
01906 void ht_window::setframe(ht_frame *newframe)
01907 {
01908 if (frame) {
01909 ht_group::remove(frame);
01910 frame->done();
01911 delete frame;
01912 frame=NULL;
01913 }
01914 if (newframe) {
01915 UINT style=newframe->getstyle();
01916 if (style & FS_MOVE) options|=VO_MOVE; else options&=~VO_MOVE;
01917 if (style & FS_RESIZE) options|=VO_RESIZE; else options&=~VO_RESIZE;
01918 insert(newframe);
01919 } else {
01920 options&=~VO_MOVE;
01921 options&=~VO_RESIZE;
01922 }
01923 frame=newframe;
01924 }
01925
01926 void ht_window::setnumber(UINT _number)
01927 {
01928 if (frame) frame->setnumber(_number);
01929 number=_number;
01930 dirtyview();
01931 }
01932
01933 void ht_window::sethscrollbar(ht_scrollbar *s)
01934 {
01935 if (hscrollbar) remove(hscrollbar);
01936 hscrollbar=s;
01937 insert(hscrollbar);
01938 putontop(hscrollbar);
01939 }
01940
01941 void ht_window::setpindicator(ht_text *p)
01942 {
01943 if (pindicator) remove(pindicator);
01944 pindicator=p;
01945 insert(pindicator);
01946 putontop(pindicator);
01947 }
01948
01949 void ht_window::settitle(char *title)
01950 {
01951 if (desc) free(desc);
01952 desc=ht_strdup(title);
01953 if (frame) frame->settext(title);
01954 }
01955
01956 void ht_window::setvscrollbar(ht_scrollbar *s)
01957 {
01958 if (vscrollbar) remove(vscrollbar);
01959 vscrollbar=s;
01960 insert(vscrollbar);
01961 putontop(vscrollbar);
01962 }
01963
01964 void ht_window::store(ht_object_stream *s)
01965 {
01966 ht_group::store(s);
01967 }
01968
01969
01970
01971
01972
01973 void ht_vbar::draw()
01974 {
01975 fill(0, 0, 1, size.h, getcolor(palidx_generic_body), CHAR_LINEV);
01976 }
01977
01978
01979
01980
01981
01982 void ht_hbar::draw()
01983 {
01984 fill(0, 0, size.w, 1, getcolor(palidx_generic_body), CHAR_LINEH);
01985 }
01986
01987
01988 BUILDER(ATOM_HT_VIEW, ht_view);
01989 BUILDER(ATOM_HT_GROUP, ht_group);
01990 BUILDER(ATOM_HT_XGROUP, ht_xgroup);
01991 BUILDER(ATOM_HT_WINDOW, ht_window);
01992 BUILDER(ATOM_HT_FRAME, ht_frame);
01993 BUILDER(ATOM_HT_SCROLLBAR, ht_scrollbar);
01994
01995
01996
01997
01998
01999 bool init_obj()
02000 {
02001 REGISTER(ATOM_HT_VIEW, ht_view);
02002 REGISTER(ATOM_HT_GROUP, ht_group);
02003 REGISTER(ATOM_HT_XGROUP, ht_xgroup);
02004 REGISTER(ATOM_HT_WINDOW, ht_window);
02005 REGISTER(ATOM_HT_FRAME, ht_frame);
02006 REGISTER(ATOM_HT_SCROLLBAR, ht_scrollbar);
02007 return true;
02008 }
02009
02010
02011
02012
02013
02014 void done_obj()
02015 {
02016 UNREGISTER(ATOM_HT_VIEW, ht_view);
02017 UNREGISTER(ATOM_HT_GROUP, ht_group);
02018 UNREGISTER(ATOM_HT_XGROUP, ht_xgroup);
02019 UNREGISTER(ATOM_HT_WINDOW, ht_window);
02020 UNREGISTER(ATOM_HT_FRAME, ht_frame);
02021 UNREGISTER(ATOM_HT_SCROLLBAR, ht_scrollbar);
02022 }
02023