?? htobj.cc
字號:
/* * HT Editor * htobj.cc * * Copyright (C) 1999-2002 Stefan Weyergraf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "atom.h"#include "cmds.h"#include "htapp.h"#include "htctrl.h"#include "htdebug.h"#include "keyb.h"#include "htmenu.h"#include "htobj.h"#include "htpal.h"#include "htreg.h"#include "strtools.h"#include "snprintf.h"#include "store.h"#include "tools.h"#include <stdarg.h>#include <stdlib.h>#include <string.h>#define ATOM_HT_VIEW MAGIC32("OBJ\0")#define ATOM_HT_GROUP MAGIC32("OBJ\1")#define ATOM_HT_XGROUP MAGIC32("OBJ\2")#define ATOM_HT_WINDOW MAGIC32("OBJ\3")#define ATOM_HT_FRAME MAGIC32("OBJ\4")#define ATOM_HT_SCROLLBAR MAGIC32("OBJ\5")#define DEFAULT_VIEW_MIN_WIDTH 25#define DEFAULT_VIEW_MIN_HEIGHT 6static void bounds_and(Bounds *a, Bounds *b){ if (b->x > a->x) { a->w -= b->x-a->x; a->x = b->x; } if (b->y > a->y) { a->h -= b->y-a->y; a->y = b->y; } if (a->x + a->w > b->x+b->w) a->w -= a->x + a->w - b->x - b->w; if (a->y + a->h > b->y+b->h) a->h -= a->y + a->h - b->y - b->h; if (a->w < 0) a->w = 0; if (a->h < 0) a->h = 0;}void clearmsg(htmsg *msg){ msg->msg = msg_empty; msg->type = mt_empty;}/* * CLASS ht_text */void ht_text::settext(const char *text){}/* * CLASS ht_view */void ht_view::init(Bounds *b, int o, const char *d){ Object::init(); VIEW_DEBUG_NAME("ht_view"); desc = ht_strdup(d); group = NULL; focused = false; browse_idx = 0; view_is_dirty = true; size = *b; prev = NULL; next = NULL; setoptions(o); buf = NULL; enabled = true; growmode = MK_GM(GMH_LEFT, GMV_TOP); // Bounds rel(0, 0, b->w, b->h); if (options & VO_OWNBUFFER) { buf = new BufferedRDisplay(size); } else { buf = new SystemRDisplay(screen, size); } g_hdist = 0; g_vdist = 0; setbounds(b); pal.data = NULL; pal.size = 0; pal_class = defaultpaletteclass(); pal_name = defaultpalette(); reloadpalette();}void ht_view::done(){ free(desc); free(pal.data); delete buf; Object::done();}int ht_view::aclone(){ return (group && group->isaclone(this));}#if 0int ht_view::buf_lprint(int aX, int aY, int c, int l, const char *text, Codepage cp){ if (y+aY >= vsize.y && y+aY < vsize.y+vsize.h) { if (x+aX+l > vsize.x+vsize.w) l = vsize.x+vsize.w-size.x-aX; if (x+aX-vsize.x < 0) { int kqx = -x-aX+vsize.x; for (int i=0; i < kqx; i++) { if (!*text) return 0; text++; aX++; l--; } } return (l > 0) ? buf->b_lprint(x+aX, y+aY, c, l, text) : 0; } return 0;}int ht_view::buf_lprintw(int aX, int aY, int c, int l, const AbstractChar *text, Codepage cp){ if (size.y+aY >= vsize.y && size.y+aY < vsize.y+vsize.h)) { if (x+aX+l > vsize.x+vsize.w) l=vsize.x+vsize.w-x-aX; if (x+aX-vsize.x < 0) { int kqx = -x-aX+vsize.x; for (int i=0; i < kqx; i++) { if (!*text) return 0; text++; x++; l--; } } return (l>0) ? buf->lprintw(size.x+x, size.y+y, c, l, text) : 0; } return 0;}int ht_view::buf_print(int x, int y, int c, const char *text, Codepage cp){ if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) { int l=vsize.x+vsize.w-x-size.x; if (size.x+x-vsize.x<0) { int kqx=-size.x-x+vsize.x; for (int i=0; i<kqx; i++) { if (!*text) return 0; text++; x++; l--; } } return (l>0) ? buf->b_lprint(size.x+x, size.y+y, c, l, text) : 0; } return 0;}void ht_view::buf_printchar(int x, int y, int c, int ch, Codepage cp){ if (pointvisible(size.x+x, size.y+y)) buf->b_printchar(size.x+x, size.y+y, c, ch, cp);}int ht_view::buf_printf(int x, int y, int c, CodePage cp, const char *format, ...){ char buf[256]; /* secure */ va_list arg; va_start(arg, format); ht_vsnprintf(buf, sizeof buf, format, arg); va_end(arg); return buf_print(x, y, c, buf, cp);}int ht_view::buf_printw(int x, int y, int c, const AbstractChar *text, Codepage cp){ if ((size.y+y>=vsize.y) && (size.y+y<vsize.y+vsize.h)) { int l=vsize.x+vsize.w-x-size.x; if (size.x+x-vsize.x<0) { int kqx=-size.x-x+vsize.x; for (int i=0; i<kqx; i++) { if (!*text) return 0; text++; x++; l--; } } return (l>0) ? buf->b_lprintw(size.x+x, size.y+y, c, l, text) : 0; } return 0;}#endifint ht_view::childcount() const{ return 1;}void ht_view::cleanview(){ view_is_dirty=0;}void ht_view::clear(int c){ buf->fill(0, 0, size.w, size.h, c, ' ');}void ht_view::clipbounds(Bounds *b){ Bounds c; getbounds(&c); bounds_and(b, &c); bounds_and(b, &vsize);}void ht_view::config_changed(){ reloadpalette(); dirtyview();}int ht_view::countselectables(){ return (options & VO_SELECTABLE) ? 1 : 0;}int ht_view::datasize(){ return 0;}const char *ht_view::defaultpalette(){ return palkey_generic_window_default;}const char *ht_view::defaultpaletteclass(){ return palclasskey_generic;}void ht_view::dirtyview(){ view_is_dirty=1;}void ht_view::disable(){ enabled=0;}void ht_view::disable_buffering(){ if (options & VO_OWNBUFFER) { delete buf;// Bounds rel(0, 0, size.w, size.h); buf = new SystemRDisplay(screen, size); setoptions(options & ~VO_OWNBUFFER); }}void ht_view::draw(){}void ht_view::enable(){ enabled=1;}void ht_view::enable_buffering(){ if (!(options & VO_OWNBUFFER)) { delete buf;// Bounds rel(0, 0, size.w, size.h); buf = new BufferedRDisplay(size); setoptions(options | VO_OWNBUFFER); }}static bool view_line_exposed(ht_view *v, int y, int x1, int x2){ ht_group *g=v->group; while (g) { if (y >= g->size.y && y < g->size.y+g->size.h) { if (x1 < g->size.x) x1 = g->size.x; if (x2 > g->size.x + g->size.w) x2 = g->size.x+g->size.w; ht_view *n = g->first; while (n && n!=v) n=n->next; if (n) { n=n->next; if (n) while (n) { if (!(n->options & VO_TRANSPARENT_CHARS)) { if ((y>=n->size.y) && (y<n->size.y+n->size.h)) { if (n->size.x<=x1) { if (n->size.x+n->size.w>=x2) { return 0; } else if (n->size.x+n->size.w>x1) { x1=n->size.x+n->size.w; } } else if (n->size.x<=x2) { if (n->size.x+n->size.w<x2) { if (!view_line_exposed(n, y, x1, n->size.x)) return 0; x1=n->size.x+n->size.w; } else { x2=n->size.x; } } } } n=n->next; } } } else break; v=g; g=g->group; } return 1;}int ht_view::enum_start(){ return 0;}ht_view *ht_view::enum_next(int *handle){ return 0;}bool ht_view::exposed(){#if 1 for (int y=0; y < size.h; y++) { if (view_line_exposed(this, size.y+y, size.x, size.x+size.w)) return 1; } return 0;#else return 1;#endif}void ht_view::fill(int x, int y, int w, int h, int c, char chr, Codepage cp){ Bounds b(x+size.x, y+size.y, w, h); bounds_and(&b, &vsize); buf->fill(b.x-size.x, b.y-size.y, b.w, b.h, c, chr, cp);}bool ht_view::focus(ht_view *view){ if (view == this) { if (!focused) receivefocus(); return true; } return false;}void ht_view::getbounds(Bounds *b){ *b = size;}vcp ht_view::getcolor(uint index){ return getcolorv(&pal, index);}void ht_view::getminbounds(int *width, int *height){ *width = DEFAULT_VIEW_MIN_WIDTH; *height = DEFAULT_VIEW_MIN_HEIGHT;}struct databufdup_s { MemMapFile *f; ObjectStreamNative *s;};void ht_view::databuf_free(void *handle){ databufdup_s *s = (databufdup_s*)handle; delete s->s; delete s->f; delete s;}void *ht_view::databuf_get(void *buf, int bufsize){ MemMapFile *f = new MemMapFile(buf, bufsize); ObjectStreamNative *s = new ObjectStreamNative(f, false, true); getdata(*s); databufdup_s *q = new databufdup_s; q->f = f; q->s = s; return q;}void ht_view::databuf_set(void *buf, int bufsize){ ConstMemMapFile f(buf, bufsize); ObjectStreamNative s(&f, false, true); setdata(s); }void ht_view::getdata(ObjectStream &s){}ht_view *ht_view::getfirstchild(){ return 0;}uint ht_view::getnumber(){ return 0;}const char *ht_view::getpalette(){ return pal_name;}ht_view *ht_view::getselected(){ return this;}void ht_view::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_draw: redraw(); return; case msg_dirtyview: dirtyview(); if ((msg->type & mt_broadcast) == 0) clearmsg(msg); return; case msg_config_changed: config_changed();// clearmsg(msg); return; }}void ht_view::hidecursor(){ buf->setCursorMode(CURSOR_OFF); screen->setCursorMode(CURSOR_OFF);}int ht_view::isaclone(ht_view *view){ return (view==this) && (countselectables()==1);}int ht_view::isviewdirty(){ return view_is_dirty;}void ht_view::load(ObjectStream &s){/* s->get_bool(enabled, NULL); s->get_bool(focused, NULL); s->get_int_dec(options, 4, NULL); s->get_int_dec(browse_idx, 4, NULL); s->get_string(desc, NULL); get_bounds(s, &size); get_bounds(s, &vsize); s->get_string(pal_class, NULL); s->get_string(pal_name, NULL); s->get_int_dec(growmode, 4, NULL);*/}void ht_view::move(int rx, int ry){ size.x += rx; size.y += ry; buf->move(rx, ry); vsize = size; if (group) group->clipbounds(&vsize); app->clipbounds(&vsize);}ObjectID ht_view::getObjectID() const{ return ATOM_HT_VIEW;}bool ht_view::pointvisible(int x, int y){ x += size.x; y += size.y; return (x >= vsize.x && y >= vsize.y && x < vsize.x+vsize.w && y < vsize.y+vsize.h);}void ht_view::receivefocus(){ dirtyview(); focused = true;}void ht_view::redraw(){ if (exposed()) { if (options & VO_OWNBUFFER) { if (isviewdirty()) { draw(); cleanview(); } screen->copyFromDisplay(*buf, size.x, size.y, vsize); } else { draw(); cleanview(); } }}void ht_view::resize(int sx, int sy){ if (options & VO_RESIZE) { int min_width, min_height; getminbounds(&min_width, &min_height); if (size.w+sx <= min_width) sx = min_width - size.w; if (size.h+sy <= min_height) sy = min_height - size.h; size.w += sx; size.h += sy; buf->resize(sx, sy); } vsize = size; if (group) group->clipbounds(&vsize); app->clipbounds(&vsize);}void ht_view::releasefocus(){ dirtyview(); hidecursor(); focused=0;}void ht_view::reloadpalette(){ if (pal.data) { free(pal.data); pal.data=0; } load_pal(pal_class, pal_name, &pal);}void ht_view::relocate_to(ht_view *view){ Bounds b; view->getbounds(&b); move(b.x, b.y);}int ht_view::select(ht_view *view){ return (view==this);}void ht_view::selectfirst(){}void ht_view::selectlast(){}void ht_view::sendmsg(htmsg *msg){ if (enabled) handlemsg(msg);}void ht_view::sendmsg(int msg, void *data1, void *data2){ htmsg m; m.msg=msg; m.type=mt_empty; m.data1.ptr=data1; m.data2.ptr=data2; sendmsg(&m);}void ht_view::sendmsg(int msg, int data1, int data2){ htmsg m; switch (msg) { case msg_empty: return; case msg_draw: case msg_dirtyview: m.msg = msg; m.type = mt_broadcast; m.data1.integer = data1; m.data2.integer = data2; break; default: m.msg = msg; m.type = mt_empty; m.data1.integer = data1; m.data2.integer = data2; break; } sendmsg(&m);}void ht_view::setbounds(Bounds *b){ size = *b; setvisualbounds(b);}void ht_view::setvisualbounds(Bounds *b){ vsize = *b;// Bounds rel(0, 0, b->w, b->h); buf->setBounds(*b);}void ht_view::setcursor(int x, int y, CursorMode c){ if (pointvisible(x, y)) { buf->setCursor(x, y, c); screen->setCursor(size.x+x, size.y+y, c);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -