Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htobj.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      htobj.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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  *      CLASS ht_text
00082  */
00083 
00084 void ht_text::settext(const char *text)
00085 {
00086 }
00087 
00088 /*
00089  *      CLASS ht_view
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];  /* secure */
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 //              clearmsg(msg);
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 /*     s->get_bool(enabled, NULL);
00546         s->get_bool(focused, NULL);
00547         s->get_int_dec(options, 4, NULL);
00548         s->get_int_dec(browse_idx, 4, NULL);
00549         s->get_string(desc, NULL);
00550         get_bounds(s, &size);
00551         get_bounds(s, &vsize);
00552         s->get_string(pal_class, NULL);
00553         s->get_string(pal_name, NULL);
00554         s->get_int_dec(growmode, 4, NULL);*/
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 /*      s->putBool(enabled, NULL);
00752         s->putBool(focused, NULL);
00753         s->putIntDec(options, 4, NULL);
00754         s->putIntDec(browse_idx, 4, NULL);
00755         s->putString(desc, NULL);
00756         put_bounds(s, &size);
00757         put_bounds(s, &vsize);
00758         s->putString(pal_class, NULL);
00759         s->putString(pal_name, NULL);
00760         s->putIntDec(growmode, 4, NULL);*/
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  *      CLASS ht_group
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                         /* do nothing */
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                         /* do nothing */
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  *      CLASS ht_xgroup
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 /* no broadcasts. */
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  *      CLASS ht_scrollbar
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();       // enabled by default
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 //          vcp color2 = VCP(VCP_BACKGROUND(color), VCP_FOREGROUND(color));
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  *      CLASS ht_frame
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 /*      if (style & FS_RESIZE) {
01492                 buf_printchar(size.w-1, size.h-1, getcurcol_killer(), CHAR_CORNERLR);
01493         } else {*/
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 /* "[x]" */
01502         if (style & FS_KILLER) {
01503                 buf_print(2, 0, c, "[ ]");
01504                 buf_printchar(3, 0, getcurcol_killer(), CHAR_QUAD_SMALL);
01505         }
01506 /* e.g. "1" */
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 /* <title> */
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  *      CLASS ht_window
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  *      CLASS ht_vbar
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  *      CLASS ht_hbar
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  *      INIT
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  *      DONE
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 

Generated on Fri May 7 21:15:36 2004 by doxygen 1.3.5