📄 htdialog.cc
字号:
/* * HT Editor * htdialog.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 <ctype.h>#include <stdarg.h>#include <stdlib.h>#include <string.h>#include "htclipboard.h"#include "htctrl.h"#include "htdialog.h"#include "hthist.h"#include "htidle.h"#include "keyb.h"#include "htpal.h"#include "snprintf.h"#include "strtools.h"#include "tools.h"ht_queued_msg::ht_queued_msg(ht_view *aTarget, htmsg &aMsg){ target = aTarget; msg = aMsg;}void ht_dialog_widget::getminbounds(int *width, int *height){ *width = 1; *height = 1;}/* * CLASS ht_dialog */void ht_dialog::init(Bounds *b, const char *desc, uint framestyle){ ht_window::init(b, desc, framestyle); VIEW_DEBUG_NAME("ht_dialog"); options &= ~VO_SELBOUND; msgqueue = new Queue(true);}void ht_dialog::done(){ delete msgqueue; ht_window::done();}int ht_dialog::aclone(){ return 1;}const char *ht_dialog::defaultpalette(){ return palkey_generic_dialog_default;}ht_queued_msg *ht_dialog::dequeuemsg(){ return (ht_queued_msg*)msgqueue->deQueue();}void ht_dialog::draw(){ clear(getcolor(palidx_generic_body)); ht_group::draw();}int ht_dialog::getstate(int *aReturn_val){ if (aReturn_val) *aReturn_val = return_val; return state;}void ht_dialog::handlemsg(htmsg *msg){ if (msg->msg == msg_button_pressed) { switch (msg->data1.integer) { case button_cancel: setstate(ds_term_cancel, msg->data1.integer); clearmsg(msg); return; default: setstate(ds_term_ok, msg->data1.integer); clearmsg(msg); return; } } ht_window::handlemsg(msg); if (msg->msg == msg_keypressed) { switch (msg->data1.integer) { case K_Escape: setstate(ds_term_cancel, msg->data1.integer); clearmsg(msg); return; case K_Return: sendmsg(msg_button_pressed, button_ok); clearmsg(msg); return; case K_Control_O: { } } }}void do_modal_resize();int ht_dialog::run(bool modal){ ht_view *orig_focused=app->getselected(), *orig_baseview=baseview; int oldx, oldy; ht_view *drawer=modal ? this : app; screen->getCursor(oldx, oldy); setstate(ds_normal, 0); ((ht_group*)app)->insert(this); ((ht_group*)app)->focus(this); baseview = this; drawer->sendmsg(msg_draw, 0); screen->show(); while (getstate(0) == ds_normal) { if (keyb_keypressed()) { ht_key k = keyb_getkey(); sendmsg(msg_keypressed, k); drawer->sendmsg(msg_draw, 0); screen->show(); } if (sys_get_winch_flag()) { do_modal_resize(); } ht_queued_msg *q; while ((q = dequeuemsg())) { htmsg m = q->msg; q->target->sendmsg(&m); sendmsg(msg_draw); delete q; } if (!modal) do_idle(); } int return_val; int state = getstate(&return_val); screen->setCursor(oldx, oldy); ((ht_group*)app)->remove(this); app->focus(orig_focused); baseview = orig_baseview; if (state != ds_term_cancel) { return return_val; } else { return 0; }}void ht_dialog::queuemsg(ht_view *target, htmsg &msg){ msgqueue->enQueue(new ht_queued_msg(target, msg));}void ht_dialog::setstate(int st, int retval){ state = st; return_val = retval;}/* * CLASS ht_cluster */void ht_cluster::init(Bounds *b, ht_string_list *_strings){ ht_view::init(b, VO_SELECTABLE | VO_OWNBUFFER | VO_POSTPROCESS, 0); VIEW_DEBUG_NAME("ht_cluster"); strings=_strings; scount=strings->count(); if (scount>32) scount=32; /* cant use more than 32... */ sel=0; for (int i=0; i<scount; i++) { const char *s = strings->get_string(i); s = strchr(s, '~'); if (s) { shortcuts[i] = keyb_metakey((ht_key)*(s+1)); } else shortcuts[i] = K_INVALID; }}void ht_cluster::done(){ delete strings; ht_view::done();}const char *ht_cluster::defaultpalette(){ return palkey_generic_dialog_default;}/* * CLASS ht_checkboxes */void ht_checkboxes::init(Bounds *b, ht_string_list *strings){ ht_cluster::init(b, strings); VIEW_DEBUG_NAME("ht_checkboxes"); state=0;}void ht_checkboxes::done(){ ht_cluster::done();}int ht_checkboxes::datasize(){ return sizeof (ht_checkboxes_data);}void ht_checkboxes::draw(){ clear(getcolor(focused ? palidx_generic_cluster_focused : palidx_generic_cluster_unfocused)); int i=0; int vx=0, vy=0; int maxcolstrlen=0; while (i<scount) { int c=getcolor(palidx_generic_cluster_unfocused); if ((focused) && (sel==i)) c=getcolor(palidx_generic_cluster_focused); const char *s = strings->get_string(i); int slen = strlen(s); if (slen > maxcolstrlen) maxcolstrlen = slen; if ((1 << i) & state) { buf->print(vx, vy, c, "[X]"); } else { buf->print(vx, vy, c, "[ ]"); } int k=0, oc=c; for (int q=0; q < size.w-4; q++) { if (!*(s+q)) break; if (*(s+q)=='~') { c = getcolor(palidx_generic_cluster_shortcut); continue; } else { buf->printChar(vx+k+4, vy, c, *(s+q)); k++; } c=oc; } i++; vy++; if (vy>=size.h) { vx+=maxcolstrlen+5; vy=0; maxcolstrlen=0; } }}void ht_checkboxes::getdata(ObjectStream &s){ PUT_INT32D(s, state);}void ht_checkboxes::handlemsg(htmsg *msg){ if (msg->type==mt_postprocess) { if (msg->msg==msg_keypressed) { for (int i=0; i<scount; i++) { if (shortcuts[i] != -1 && msg->data1.integer == shortcuts[i]) { sel = i; state = state ^ (1<<sel); app->focus(this); dirtyview(); clearmsg(msg); return; } } } } else { if (msg->msg==msg_keypressed) { switch (msg->data1.integer) { case K_Left: sel -= size.h; if (sel < 0) sel=0; dirtyview(); clearmsg(msg); return; case K_Right: sel += size.h; if (sel >= scount) sel = scount-1; dirtyview(); clearmsg(msg); return; case K_Up: sel--; if (sel < 0) sel = 0; dirtyview(); clearmsg(msg); return; case K_Down: sel++; if (sel >= scount) sel = scount-1; dirtyview(); clearmsg(msg); return; case K_Space: state = state ^ (1<<sel); dirtyview(); clearmsg(msg); return; } } } ht_cluster::handlemsg(msg);}void ht_checkboxes::setdata(ObjectStream &s){ GET_INT32D(s, state); dirtyview();}/* * CLASS ht_radioboxes */void ht_radioboxes::init(Bounds *b, ht_string_list *strings){ ht_cluster::init(b, strings); VIEW_DEBUG_NAME("ht_radioboxes");}void ht_radioboxes::done(){ ht_cluster::done();}int ht_radioboxes::datasize(){ return sizeof (ht_radioboxes_data);}void ht_radioboxes::draw(){ clear(getcolor(focused ? palidx_generic_cluster_focused : palidx_generic_cluster_unfocused)); int i=0; int vx=0, vy=0; int maxcolstrlen=0; while (i<scount) { int c=getcolor(palidx_generic_cluster_unfocused); if ((focused) && (sel==i)) c=getcolor(palidx_generic_cluster_focused); const char *s=strings->get_string(i); int slen=strlen(s); if (slen>maxcolstrlen) maxcolstrlen=slen; buf->print(vx, vy, c, "( )"); if (i==sel) { buf->printChar(vx+1, vy, c, GC_FILLED_CIRCLE, CP_GRAPHICAL); } buf->print(vx+4, vy, c, s); i++; vy++; if (vy>=size.h) { vx+=maxcolstrlen+5; vy=0; maxcolstrlen=0; } }}void ht_radioboxes::getdata(ObjectStream &s){ PUT_INT32D(s, sel);}void ht_radioboxes::handlemsg(htmsg *msg){ if (msg->msg==msg_keypressed) { switch (msg->data1.integer) { case K_Left: sel-=size.h; if (sel<0) sel=0; dirtyview(); clearmsg(msg); return; case K_Right: sel+=size.h; if (sel>=scount) sel=scount-1; dirtyview(); clearmsg(msg); return; case K_Up: sel--; if (sel<0) sel=0; dirtyview(); clearmsg(msg); return; case K_Down: sel++; if (sel>=scount) sel=scount-1; dirtyview(); clearmsg(msg); return;/* case K_Space: state=state^(1<<sel); dirtyview(); clearmsg(msg); break;*/ } } ht_cluster::handlemsg(msg);}void ht_radioboxes::setdata(ObjectStream &s){ GET_INT32D(s, sel);}/* * CLASS ht_history_listbox */void ht_history_listbox::init(Bounds *b, List *hist){ history = hist; ht_listbox::init(b);}int ht_history_listbox::calcCount(){ return history->count();}void *ht_history_listbox::getFirst(){ if (history->count()) { return (void*)1; } else { return NULL; }}void *ht_history_listbox::getLast(){ if (history->count()) { return (void*)(history->count()); } else { return NULL; }}void *ht_history_listbox::getNext(void *entry){ unsigned long e=(unsigned long)entry; if (!e) return NULL; if (e < history->count()) { return (void*)(e+1); } else { return NULL; }}void *ht_history_listbox::getPrev(void *entry){ unsigned long e=(unsigned long)entry; if (e > 1) { return (void*)(e-1); } else { return NULL; }}const char *ht_history_listbox::getStr(int col, void *entry){ return ((ht_history_entry*)(*history)[(long)entry-1])->desc;}void ht_history_listbox::handlemsg(htmsg *msg){ switch (msg->msg) { case msg_keypressed: switch (msg->data1.integer) { case K_Delete: { int p = pos; cursorUp(1); history->del(history->findByIdx(p)); update(); if (p) cursorDown(1); dirtyview(); clearmsg(msg); break; } } break; } ht_listbox::handlemsg(msg);}void *ht_history_listbox::quickfind(const char *s){ void *item = getFirst(); int slen = strlen(s); while (item && (ht_strncmp(getStr(0, item), s, slen)!=0)) { item = getNext(item); } return item;}char *ht_history_listbox::quickfindCompletition(const char *s){ void *item = getFirst(); char *res = NULL; int slen = strlen(s); while (item) { if (ht_strncmp(getStr(0, item), s, slen)==0) { if (!res) { res = ht_strdup(getStr(0, item)); } else { int a = ht_strccomm(res, getStr(0, item)); res[a] = 0; } } item = getNext(item); } return res;}/* * CLASS ht_history_popup_dialog */void ht_history_popup_dialog::init(Bounds *b, List *hist){ history = hist; ht_listpopup_dialog::init(b, "history");}void ht_history_popup_dialog::getdata(ObjectStream &s){ // FIXME: public member needed: PUTX_INT32D(s, listbox->pos, NULL); if (history->count()) { PUTX_STRING(s, ((ht_history_entry*)(*history)[listbox->pos])->desc, NULL); } else { PUTX_STRING(s, NULL, NULL); }}void ht_history_popup_dialog::init_text_listbox(Bounds *b){ listbox = new ht_history_listbox(); ((ht_history_listbox *)listbox)->init(b, history); insert(listbox);}void ht_history_popup_dialog::setdata(ObjectStream &s){}/* * CLASS ht_inputfield */void ht_inputfield::init(Bounds *b, int Maxtextlen, List *hist){ ht_view::init(b, VO_SELECTABLE | VO_RESIZE, "some inputfield"); VIEW_DEBUG_NAME("ht_inputfield"); history = hist; maxtextlenv = Maxtextlen; growmode = MK_GM(GMH_FIT, GMV_TOP); textv = ht_malloc(maxtextlenv+1); curcharv = textv; textlenv = 0; selstartv = 0; selendv = 0; text = &textv; curchar = &curcharv; textlen = &textlenv; maxtextlen = &maxtextlenv; selstart = &selstartv; selend = &selendv; insert = 1; ofs = 0; attachedto = 0;}void ht_inputfield::done(){ freebuf(); ht_view::done();}void ht_inputfield::attach(ht_inputfield *inputfield){ freebuf(); inputfield->query(&curchar, &text, &selstart, &selend, &textlen, &maxtextlen); attachedto=inputfield; ofs=0; insert=1;}int ht_inputfield::datasize(){ return sizeof (ht_inputfield_data);}const char *ht_inputfield::defaultpalette(){ return palkey_generic_dialog_default;}void ht_inputfield::freebuf(){ if (!attachedto && text) free(*text);}void ht_inputfield::getdata(ObjectStream &s){ if (!attachedto) { PUTX_INT32D(s, *textlen, NULL); PUTX_BINARY(s, *text, *textlen, NULL); }/* FIXPORT uint h = s->recordStart(datasize()); if (!attachedto) { s->putIntDec(*textlen, 4, NULL); s->putBinary(*text, *textlen, NULL); } s->recordEnd(h);*/}int ht_inputfield::insertbyte(byte *pos, byte b){ if (*textlen<*maxtextlen) { if (*selstart) { if (pos<*selstart) { (*selstart)++; (*selend)++; } else if (pos<*selend) { (*selend)++; } } memmove(pos+1, pos, *textlen-(pos-*text)); *pos=b; (*textlen)++; dirtyview(); return 1; } return 0;}void ht_inputfield::isetcursor(uint pos){ if (pos < (uint)*textlen) *curchar = *text + pos;}void ht_inputfield::query(byte ***c, byte ***t, byte ***ss, byte ***se, int **tl, int **mtl){ *c=curchar; *t=text; *ss=selstart; *se=selend; *tl=textlen; *mtl=maxtextlen;}void ht_inputfield::select_add(byte *start, byte *end){ if (end<start) { byte *temp=start; start=end; end=temp; } if (end==*selstart) { *selstart=start; } else if (start==*selend) { *selend=end; } else if (start==*selstart) { *selstart=end; } else if (end==*selend) { *selend=start; } else { *selstart=start; *selend=end; } if (*selstart>*selend) { byte *temp=*selstart; *selstart=*selend; *selend=temp; }}void ht_inputfield::setdata(ObjectStream &s){// FIXPORT uint h=s->recordStart(datasize()); if (!attachedto) { textlen=&textlenv; GET_INT32D(s, *textlen); if (*textlen > *maxtextlen) *textlen = *maxtextlen; GET_BINARY(s, *text, *textlen); curchar = &curcharv; *curchar = *text + *textlen; if (*textlen) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -