?? htmenu.cc
字號:
/* * HT Editor * htmenu.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 <cstring>#include "htapp.h" // for queuemsg#include "htctrl.h"#include "keyb.h"#include "htmenu.h"#include "htpal.h"#include "htreg.h"#include "strtools.h"#include "stream.h"#include "tools.h"#define button_left 100#define button_right 101char *shortcut_str(char *str){ while (*str) { if (*str=='~') { memmove(str, str+1, strlen(str)); return str; } str++; } return NULL;}bool execute_submenu(int x, int y, ht_context_menu *m){ int curentry=0; bool term=false; Bounds scr; app->getbounds(&scr); do { Bounds b; b.x=x+m->xpos-1; b.y=y; b.w=m->width+4; b.h=m->count()+2; if (b.y+b.h > scr.h) { if (scr.h > b.h) { b.y = scr.h - b.h; if (b.y >= 2) b.y -= 2; } else { b.y = 0; } } ht_menu_window *d = new ht_menu_window(); d->init(&b, m); ht_menu_window_data a; a.selected = curentry; d->databuf_set(&a, sizeof a); b.x = 0; b.y = 0; ht_frame *frame = new ht_menu_frame(); frame->init(&b, 0, FS_MOVE/*just for fun*/); d->setframe(frame); d->setpalette(palkey_generic_menu_default); int r = d->run(false); d->done(); delete d; switch (r) { case button_ok: { return true; } default: term = true; } } while (!term); return false;}/* * CLASS ht_context_menu */void ht_context_menu::init(const char *Name){ name = ht_strdup(Name); shortcut = shortcut_str(name); width = 0;}void ht_context_menu::done(){ free(name);}int ht_context_menu::count(){ return 0;}ht_context_menu_entry *ht_context_menu::enum_entry_first(){ return NULL;}ht_context_menu_entry *ht_context_menu::enum_entry_next(){ return NULL;}ht_context_menu_entry *ht_context_menu::get_entry(int n){ ht_context_menu_entry *e=enum_entry_first(); while (n-- && e) { e = enum_entry_next(); } return e;}const char *ht_context_menu::get_name(){ return name;}const char *ht_context_menu::get_shortcut(){ return shortcut;}/* * CLASS ht_static_context_menu */void ht_static_context_menu::init(const char *name){ ht_context_menu::init(name); context_menu_entry = new Array(true);}void ht_static_context_menu::done(){ delete context_menu_entry; ht_context_menu::done();}int ht_static_context_menu::count(){ return context_menu_entry->count();}ht_context_menu_entry *ht_static_context_menu::enum_entry_first(){ enum_idx = 0; ht_context_menu_entry *e = (ht_context_menu_entry*)(*context_menu_entry)[enum_idx]; return e;}ht_context_menu_entry *ht_static_context_menu::enum_entry_next(){ enum_idx++; ht_context_menu_entry *e = (ht_context_menu_entry*)(*context_menu_entry)[enum_idx]; return e;}void ht_static_context_menu::insert_entry(const char *Name, const char *Comment, int cmd, int k, bool a){ char *name = ht_strdup(Name); char *comment = ht_strdup(Comment); char *shortcut = shortcut_str(name); int l = strlen(name); int cl = comment ? strlen(comment)+2 : 0; width = MAX(width, l+cl); ht_context_menu_entry *e = new ht_context_menu_entry(); e->type = CME_ENTRY; e->entry.name = name; e->entry.shortcut = shortcut; e->entry.comment = comment; e->entry.command = cmd; e->entry.key = k; e->entry.active = a; context_menu_entry->insert(e);}void ht_static_context_menu::insert_separator(){ ht_context_menu_entry *entry = new ht_context_menu_entry(); entry->type = CME_SEPARATOR; context_menu_entry->insert(entry);}void ht_static_context_menu::insert_submenu(ht_context_menu *submenu){ ht_context_menu_entry *entry = new ht_context_menu_entry(); entry->type = CME_SUBMENU; entry->submenu = submenu; submenu->xpos = 0; context_menu_entry->insert(entry);}/* * CLASS ht_context_menu_entry */ht_context_menu_entry::~ht_context_menu_entry(){ switch (type) { case CME_ENTRY: free(entry.name); free(entry.comment); break; case CME_SUBMENU: submenu->done(); delete submenu; break; }}/* * CLASS ht_menu */void ht_menu::init(Bounds *b){ ht_view::init(b, VO_OWNBUFFER | VO_POSTPROCESS | VO_RESIZE, "menu"); VIEW_DEBUG_NAME("ht_menu"); growmode = MK_GM(GMH_FIT, GMV_TOP); menu = new Array(true); lastmenux = 1; curmenu = -1; localmenu = -1; context_menu_hack = NULL; last_context_menu_hack = NULL; context_menu_hack2 = false;}void ht_menu::done(){ delete menu; ht_view::done();}const char *ht_menu::defaultpalette(){ return palkey_generic_menu_default;}const char *ht_menu::defaultpaletteclass(){ return palclasskey_generic;}ht_context_menu *ht_menu::get_context_menu(int i){ ht_context_menu *q = (ht_context_menu*)(*menu)[i]; if (context_menu_hack && (i == localmenu) && !q) return context_menu_hack; return q;}void ht_menu::getminbounds(int *width, int *height){ *width = 1; *height = 1;}void ht_menu::draw(){ clear(getcolor(palidx_generic_body)); int c = count(); for (int i=0; i < c; i++) { ht_context_menu *c = get_context_menu(i); const char *n = c->get_name(); const char *s = c->get_shortcut(); if (i == curmenu) { buf->printChar(c->xpos-1, 0, getcolor(palidx_generic_text_selected), ' '); buf->print(c->xpos, 0, getcolor(palidx_generic_text_selected), n); buf->printChar(c->xpos+strlen(n), 0, getcolor(palidx_generic_text_selected), ' '); if (s) buf->printChar(c->xpos+(s - n), 0, getcolor(palidx_generic_text_shortcut_selected), *s); } else { buf->print(c->xpos, 0, getcolor(palidx_generic_text_focused), n); if (s) buf->printChar(c->xpos+(s - n), 0, getcolor(palidx_generic_text_shortcut), *s); } }}void ht_menu::execute_menu(int i){ curmenu = i; int curentry = 0; bool term = false; dirtyview(); do { ht_context_menu *m = get_context_menu(curmenu); Bounds b; b.x = m->xpos-1; b.y = 1; b.w = m->width + 4; b.h = m->count() + 2; ht_menu_window *d = new ht_menu_window(); d->init(&b, m); ht_menu_window_data a; a.selected = curentry; d->databuf_set(&a, sizeof a); b.x = 0; b.y = 0; ht_frame *frame = new ht_menu_frame(); frame->init(&b, 0, FS_MOVE); // just for fun d->setframe(frame); d->setpalette(palkey_generic_menu_default); int r = d->run(false); switch (r) { case button_left: curmenu--; if (curmenu < 0) curmenu = count() - 1; curentry=0; dirtyview(); break; case button_right: curmenu++; if (curmenu > (int)count()-1) curmenu = 0; curentry = 0; dirtyview(); break; case button_ok: {// return true; } default: term = true; } d->done(); delete d; } while (!term); curmenu = -1; dirtyview();}void ht_menu::handlemsg(htmsg *msg){ if (msg->type == mt_postprocess) { if (msg->msg == msg_keypressed) { /* shortcuts */ ht_key k = keyb_unmetakey((ht_key)msg->data1.integer); if (k != K_INVALID) { int c=count(); for (int i=0; i<c; i++) { ht_context_menu *m = get_context_menu(i); int s = *m->get_shortcut(); if (s >= 'A' && s <= 'Z') s += 'a'-'A'; if (s == k) { if (last_context_menu_hack) { last_context_menu_hack->done(); delete last_context_menu_hack; last_context_menu_hack = NULL; } if (localmenu != -1) { context_menu_hack = (ht_context_menu*)(*menu)[localmenu]; last_context_menu_hack = NULL; if (context_menu_hack) { menu->remove(menu->findByIdx(localmenu)); } } context_menu_hack2 = true; execute_menu(i); context_menu_hack2 = false; if (context_menu_hack) { context_menu_hack->done(); delete context_menu_hack; context_menu_hack = NULL; } if (last_context_menu_hack) { set_local_menu(last_context_menu_hack); last_context_menu_hack = NULL; } else { delete_local_menu(); } clearmsg(msg); return; } } } /* keys associated with menu entries */ int c = count(); for (int i=0; i<c; i++) { ht_context_menu *a = get_context_menu(i); if (handle_key_context_menu(a, msg->data1.integer)) { clearmsg(msg); return; } } } } ht_view::handlemsg(msg);}bool ht_menu::handle_key_context_menu(ht_context_menu *a, int k){ ht_context_menu_entry *e = a->enum_entry_first(); while (e) { if (e->type == CME_ENTRY && e->entry.name && e->entry.key && k == e->entry.key) { htmsg m; m.msg = e->entry.command; m.type = mt_empty;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -