📄 interface.cpp
字号:
/* * $File: interface.cpp * $Author: Jiakai -- gy_jk@126.com * $Date: Thu Mar 26 19:51:15 2009*//*Copyright (C) (2008) (Jiakai) <gy_jk@126.com>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "interface.h"#include "../common.h"#include <ncurses.h>#include <menu.h>#include <panel.h>#include <stdarg.h>#include <vector>#include <string>#include <cstring>using namespace std;//--------------------------------Function Statements---------------------------------static void destroy_win(WINDOW *win);static bool move_current_item(int key, MENU *menu, bool multiple_cols);//------------------------------------------------------------------------------------typedef vector<string> Str_array;typedef vector<void*> Pvoid_array;static Pvoid_array win_exists;void ncurses::init(){ if (win_exists.size() > 0) throw Error("Initalized twice.", __PRETTY_FUNCTION__, __LINE__); initscr(); start_color(); if (has_colors()) { init_pair(NCOLOR_BLACK, COLOR_BLACK, COLOR_WHITE); init_pair(NCOLOR_RED, COLOR_RED, COLOR_BLACK); init_pair(NCOLOR_GREEN, COLOR_GREEN, COLOR_BLACK); init_pair(NCOLOR_YELLOW, COLOR_GREEN, COLOR_BLACK); init_pair(NCOLOR_BLUE, COLOR_BLUE, COLOR_BLACK); init_pair(NCOLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); init_pair(NCOLOR_CYAN, COLOR_CYAN, COLOR_BLACK); init_pair(NCOLOR_WHITE, COLOR_WHITE, COLOR_BLACK); } clear(); curs_set(0); raw(); keypad(stdscr, TRUE); noecho();}void ncurses::end(){ while (win_exists.size() > 0) ((Window*)win_exists[0])->free(); clear(); endwin();}void ncurses::update(){ update_panels(); doupdate();}int ncurses::get_str_nlines(const char *str, int cols){ if (cols <= 0) cols = COLS; int ret = 0, len = strlen(str); int curlen = 0; for (int i = 0; i < len; i ++) if (str[i] == '\n') { ret += (curlen % cols ? curlen / cols + 1 : curlen / cols); curlen = 0; } else curlen ++; ret += (curlen % cols ? curlen / cols + 1 : curlen / cols); return ret;}void ncurses::report_err(const char *msg_, const char *func, int line){ char msg[STRING_MAX_LEN * 3]; sprintf(msg, "An error occurred: %s : %d \n%s", func, line, msg_); message_box(msg, "ERROR");}void ncurses::read_input(const char *msg, char *data, const char *def, const char *start_val, int maxlen){ int WIN_INPUT_WIDTH = COLS - 6; char msg1[STRING_MAX_LEN]; if (def != NULL) sprintf(msg1, "%s [default: %s] ", msg, def); else strcpy(msg1, msg); msg = msg1; int nlines = get_str_nlines(msg, WIN_INPUT_WIDTH - 2); Window win_input(nlines + 3, WIN_INPUT_WIDTH, (LINES - nlines - 3) / 2, (COLS - WIN_INPUT_WIDTH) / 2); win_input.printf("%s", msg); if (maxlen <= 0) maxlen = STRING_MAX_LEN; if (start_val == 0) strcpy(data, ""); else strcpy(data, start_val); win_input.get_str(data, nlines, maxlen); if (def != NULL && data[0] == '\0') strcpy(data, def);}int ncurses::message_box(const char *msg, const char *title){ int win_width = COLS - 10, len = strlen(msg); if (win_width > len) win_width = len + 5; if (win_width < 15) win_width = 15; int nlines = get_str_nlines(msg, win_width); if (nlines + 5 > LINES) nlines = LINES - 5; Window win_msg(nlines + 2, win_width); if (title != NULL) win_msg.set_title(title); else win_msg.set_title("Message"); return win_msg.print_longmsg(msg);}int ncurses::get_ncols(){return COLS;}int ncurses::get_nlines(){return LINES;}int ncurses::get_key(){return getch();}struct ncurses::Window::Vars{ WINDOW *win, *win_border; PANEL *win_panel, *win_border_panel; bool freed;};void ncurses::Window::init(int height, int width, int starty, int startx, bool border){ v = new Vars; if (border) { v->win_border = newwin(height, width, starty, startx); box(v->win_border, 0, 0); v->win_border_panel = new_panel(v->win_border); v->win = newwin(height - 2, width - 2, starty + 1, startx + 1); v->win_panel = new_panel(v->win); } else { v->win = newwin(height, width, starty, startx); v->win_panel = new_panel(v->win); v->win_border = NULL; v->win_border_panel = NULL; } v->freed = false; win_exists.push_back(this);}ncurses::Window::Window(int h, int w, int sy, int sx, bool b){ if (h <= 0 || h > LINES) h = LINES; if (w <= 0 || w > COLS) w = COLS; if (sy == -1) sy = (LINES - h) / 2; if (sx == -1) sx = (COLS - w) / 2; if (sy + h > LINES) sy = LINES - h; if (sx + w > COLS) sx = COLS - w; init(h, w, sy, sx, b);}ncurses::Window::Window(const Window &win, int height, int width, int starty, int startx, bool border){ if (height <= 0 || height > win.get_nlines()) height = win.get_nlines(); if (width <= 0 || width > win.get_ncols()) width = win.get_ncols(); if (starty == -1) starty = (win.get_nlines() - height) / 2; if (startx == -1) startx = (win.get_ncols() - width) / 2; if (starty + height > win.get_nlines()) starty = win.get_nlines() - height; if (startx + width > win.get_ncols()) startx = win.get_ncols() - width; init(height, width, starty + getbegy(win.v->win), startx + getbegx(win.v->win), border);}ncurses::Window::Window(){ init(0, 0, 0, 0, false);}ncurses::Window::~Window(){ free(); delete v;}int ncurses::Window::get_nlines() const{ return getmaxy(v->win);}int ncurses::Window::get_ncols() const{ return getmaxx(v->win);}void ncurses::Window::free(){ if (v->freed) return; v->freed = true; del_panel(v->win_panel); destroy_win(v->win); if (v->win_border != NULL) { del_panel(v->win_border_panel); destroy_win(v->win_border); } for (Pvoid_array::iterator i = win_exists.begin(); i != win_exists.end(); i ++) if (*i == this) { win_exists.erase(i); return; } throw Error("Something required not found.", __PRETTY_FUNCTION__, __LINE__);}void ncurses::Window::printf(const char *fmt, ...){ va_list args; va_start(args, fmt); vw_printw(v->win, fmt, args); va_end(args);}void ncurses::Window::printf_color(Ncurses_color color, const char *fmt, ...){ if (has_colors()) wattron(v->win, COLOR_PAIR((int)color)); va_list args; va_start(args, fmt); vw_printw(v->win, fmt, args); va_end(args); if (has_colors()) wattroff(v->win, COLOR_PAIR(1));}void ncurses::Window::mvprintf(int y, int x, const char *fmt, ...){ char tmp[STRING_MAX_LEN]; va_list args; va_start(args, fmt); vsprintf(tmp, fmt, args); va_end(args); mvwprintw(v->win, y, x, tmp);}void ncurses::Window::clean(){ werase(v->win);}void ncurses::Window::get_str(char *data, int pos_y, int maxlen){ curs_set(1); string str(data); if (str.length() > (int)maxlen) str.erase(maxlen); string::size_type str_pos = str.length(); // the position of the cursor in @str int cursor = str_pos; // the position of the cursor in the window int win_width = getmaxx(v->win); if (cursor >= win_width) cursor = win_width; mvwprintw(v->win, pos_y, 0, "%s", string(win_width, ' ').c_str());#define PRINT_STR \ do \ { \ mvwprintw(v->win, pos_y, 0, "%s ", str.substr(str_pos - cursor, win_width - 1).c_str()); \ mvwprintw(v->win, pos_y, cursor, ""); \ } \ while (0) PRINT_STR; while (true) { update(); int ch = getch(); if (ch == ENTER) break; if (ch == KEY_LEFT) { if (str_pos == 0) continue; str_pos --; cursor --; if (cursor < 0) { cursor = 0; PRINT_STR; } else mvwprintw(v->win, pos_y, cursor, ""); } else if (ch == KEY_RIGHT) { if (str_pos == str.length()) continue; str_pos ++; cursor ++; if (cursor == win_width) { cursor --; PRINT_STR; } else mvwprintw(v->win, pos_y, cursor, ""); } else if (ch == KEY_HOME) { str_pos = 0; cursor = 0; PRINT_STR; } else if (ch == KEY_END) { str_pos = str.length(); cursor = str_pos; if (cursor >= win_width) cursor = win_width - 1; PRINT_STR; } else if (ch == KEY_BACKSPACE) { if (str_pos == 0) continue; str_pos --; str.erase(str_pos, 1); cursor --; if (cursor < 0) cursor = 0; PRINT_STR; } else if (ch == KEY_DC) { if (str_pos == str.length()) continue; str.erase(str_pos, 1); PRINT_STR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -