⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 option_dialog.hpp

📁 本程序是主要是扫雷
💻 HPP
字号:
/*     Copyright(c) Ben Bear 2004  *///  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 (at your option) any later version.//  //  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., 59 Temple Place - Suite 330, Boston, MA//  02111-1307, USA.#ifndef __option_dialog_hpp#define __option_dialog_hpp#include <stdio.h>#include <string.h>#include <curses.h>class option_dialog{public:  enum OPTION_TYPE  {    OPTION_RADIO,    OPTION_CHECK  };  private:  struct OPTION  {    OPTION_TYPE type;        const char *name;    int name_len;        const char **item;    int item_h, item_w;    int cur_item;    int *value;    int *tmp_val;        WINDOW *box;    int box_h, box_w;    int box_y, box_x;  };    static const int MAX_OPTIONS = 9;  static const int MAX_PER_LINE = 3;    static const int BOX_MIN_WIDTH = 20;  static const int BOX_PRE_WIDTH = 5;    static const int CHAR_RADIO = '*';  static const int CHAR_CHECK = 'x';    static const int BUTTON_OK = -1;  static const int BUTTON_CANCEL = -2;private:  WINDOW *dialog;  int dlg_h, dlg_w;    int scr_h, scr_w;    const char *dlg_name;    OPTION opt[MAX_OPTIONS];  int opt_num;    int cur_opt;    WINDOW *win_ok;  WINDOW *win_cancel;public:  option_dialog (const char* name)    : dialog(0), dlg_name(name), opt_num(0)  {    getmaxyx (stdscr, scr_h, scr_w);  }  bool add (OPTION_TYPE type, const char* name,	    const char **item, int *value);    bool show ();  private:  bool get_dialog_size ();  bool new_dialog ();  void new_option (int i);  void del_dialog ();  void show_item (bool on, int c_opt);  void brower_item (int key);  void select_item ();  void get_value ();  void set_value (bool set);};booloption_dialog::add (option_dialog::OPTION_TYPE type, const char* name,		    const char **item, int *value){  if ((opt_num >= MAX_OPTIONS) || ((type != OPTION_RADIO)      && (type != OPTION_CHECK)))    return false;  OPTION& option = opt[opt_num++];  option.type = type;  option.name = name;  option.name_len = strlen (name);  option.item = item;  option.item_h = 0;  option.item_w = 0;  option.cur_item = 0;  for (; *item != 0; ++item)    {      ++option.item_h;      int len = strlen (*item);      if (option.item_w < len)	option.item_w = len;    }  option.value = value;  option.tmp_val = 0;    option.box = 0;  option.box_h = option.item_h + 2; // two borders  option.box_w = option.item_w + 2 + BOX_PRE_WIDTH;  if (option.box_w < BOX_MIN_WIDTH)    option.box_w = BOX_MIN_WIDTH;  if (option.box_w < option.name_len + 4)    option.box_w = option.name_len + 4;  option.box_y = 0;  option.box_x = 0;  return true;}booloption_dialog::show (){  if (opt_num == 0)    return false;  get_value ();  if (!new_dialog ())    {      set_value (false);      return false;    }  cur_opt = 0;  for (int i = 0; i < opt_num; ++i)    opt[i].cur_item = 0;  show_item (true, cur_opt);  int ch;  do    {      ch = wgetch (dialog);      switch (ch)	{	case KEY_UP:	case KEY_DOWN:	case KEY_LEFT:	case KEY_RIGHT:	case '\t':	  brower_item (ch);	  break;	case ' ':	  select_item ();	  break;	}      if ((ch == '\n') && ((cur_opt == BUTTON_OK)			   || (cur_opt == BUTTON_CANCEL)))	break;    }  while (true);  del_dialog ();  if (cur_opt == BUTTON_OK)    {      set_value (true);      return true;    }  else    {      set_value (false);      return false;    }}booloption_dialog::new_dialog (){  int dlg_y, dlg_x;  if (get_dialog_size() == false)    return false;    dlg_y = (scr_h - dlg_h) / 2;  dlg_x = (scr_w - dlg_w) / 2;  dialog = newwin (dlg_h, dlg_w, dlg_y, dlg_x);  keypad (dialog, TRUE);  box (dialog, 0, 0);  mvwprintw (dialog, 0, (dlg_w - strlen(dlg_name)) / 2, 	     " %s ", dlg_name);    for (int i = 0; i < opt_num; ++i)    new_option (i);  win_ok = derwin (dialog, 1, 6, dlg_h-2, dlg_w/3-3);  keypad (win_ok, TRUE);  win_cancel = derwin (dialog, 1, 10, dlg_h-2, dlg_w/3*2-5);  keypad (win_cancel, TRUE);  mvwprintw (win_ok, 0, 0, "< OK >");  mvwprintw (win_cancel, 0, 0, "< Cancel >");  touchwin (dialog);  wrefresh (dialog);  return true;}booloption_dialog::get_dialog_size (){  int max_h, max_w;  int cur_y, cur_x;  int per_line = MAX_PER_LINE;  if (opt_num == 4)    per_line = 2;  max_h = scr_h - 3;  max_w = scr_w - 2;  dlg_h = 0;  dlg_w = 0;  cur_y = 1;  for (int i = 0; i < opt_num;)    {      int j = i;      i += per_line;      if (i > opt_num)	i = opt_num;      int max_line_h = 0;      cur_x = 1;      for (; j < i; ++j)	{	  if (cur_x-1 + opt[j].box_w > max_w)	    {	      if (cur_x == 1)		{		  opt[j].box_w = max_w;		}	      else		{		  // width overflow, new line		  i = j;		  break;		}	    }	  opt[j].box_y = cur_y;	  opt[j].box_x = cur_x;	  cur_x += opt[j].box_w;	  if (max_line_h < opt[j].box_h)	    max_line_h = opt[j].box_h;	}      cur_y += max_line_h;      if (dlg_w < cur_x-1)	dlg_w = cur_x-1;    }  dlg_h = cur_y-1;  dlg_h += 3;  dlg_w += 2;  if (dlg_w < 40)    dlg_w = 40;  if ((dlg_h <= max_h) && (dlg_w <= max_w))    return true;  else    return false;}voidoption_dialog::new_option (int i){  WINDOW *win = derwin (dialog, opt[i].box_h, opt[i].box_w, 			opt[i].box_y, opt[i].box_x);  opt[i].box = win;  keypad (win, TRUE);  box (win, 0, 0);  mvwprintw (win, 0, 1, " %s ", opt[i].name);  char tmp[12];  sprintf (tmp, "%%-%ds", opt[i].box_w - 2 - BOX_PRE_WIDTH);  for (int j = 0; j < opt[i].item_h; ++j)    {      mvwprintw (win, j+1, BOX_PRE_WIDTH+1, tmp, opt[i].item[j]);      if (opt[i].type == OPTION_RADIO)	{	  mvwprintw (win, j+1, 1, " ( ) ");	  if (*(opt[i].tmp_val) == j)	    mvwaddch (win, j+1, 3, CHAR_RADIO);	}      else if (opt[i].type == OPTION_CHECK)	{	  mvwprintw (win, j+1, 1, "%s", " [ ] ");	  if ((opt[i].tmp_val)[j] == 1)	    mvwaddch (win, j+1, 3, CHAR_CHECK);	}    }  touchwin (dialog);  wrefresh (dialog);}voidoption_dialog::show_item (bool on, int c_opt){  WINDOW *win;  int cur_y, cur_x, len;  if (cur_opt >= 0)    {      win = opt[c_opt].box;      cur_y = opt[c_opt].cur_item + 1;      cur_x = BOX_PRE_WIDTH + 1;      len = opt[c_opt].box_w - BOX_PRE_WIDTH - 2;      mvwaddch (win, cur_y, cur_x-1, ' ');      int type = on ? A_REVERSE : A_NORMAL;      wchgat (win, len, type, 0, NULL);      if (on)	wmove (dialog, cur_y + opt[c_opt].box_y, opt[c_opt].box_x + 3);    }  else    {      cur_y = dlg_h-2;      if (cur_opt == BUTTON_OK)	{	  win = win_ok;	  cur_x = dlg_w/3-3;	  len = 6;	}      else	{	  win = win_cancel;	  cur_x = dlg_w/3*2-5;	  len = 10;	}      int type = on ? A_REVERSE : A_NORMAL;      wmove (win, 0, 0);      wchgat (win, len, type, 0, NULL);      if (on)	wmove (dialog, cur_y, cur_x + 2);    }  touchwin (dialog);  wrefresh (dialog);}voidoption_dialog::brower_item (int key){  show_item (false, cur_opt);  if (cur_opt < 0)    {      if (key != '\t')	{	  if (cur_opt == BUTTON_OK)	    cur_opt = BUTTON_CANCEL;	  else	    cur_opt = BUTTON_OK;	}      else	{	  if (cur_opt == BUTTON_CANCEL)	    cur_opt = 0;	  else	    cur_opt = BUTTON_CANCEL;	}    }  else    {      OPTION& op = opt[cur_opt];      switch (key)	{	case KEY_UP:	  if (op.cur_item > 0)	    --op.cur_item;	  else	    op.cur_item = op.item_h-1;	  break;	  	case KEY_DOWN:	  if (op.cur_item < op.item_h-1)	    ++op.cur_item;	  else	    op.cur_item = 0;	  break;	  	case KEY_LEFT:	  if (cur_opt == 0)	    cur_opt = opt_num-1;	  else	    --cur_opt;	  break;	case KEY_RIGHT:	  if (cur_opt == opt_num-1)	    cur_opt = 0;	  else	    ++cur_opt;	  break;	case '\t':	  if (cur_opt == opt_num-1)	    cur_opt = BUTTON_OK;	  else	    ++cur_opt;	  break;	}    }  show_item (true, cur_opt);}voidoption_dialog::select_item (){  if (cur_opt < 0)    return;  WINDOW *win = opt[cur_opt].box;  int cur_item = opt[cur_opt].cur_item;  if (opt[cur_opt].type == OPTION_RADIO)    {      if (*opt[cur_opt].tmp_val == cur_item)	return;      mvwaddch (win, *opt[cur_opt].tmp_val+1, 3, ' ');      *opt[cur_opt].tmp_val = cur_item;      mvwaddch (win, cur_item+1, 3, CHAR_RADIO);    }  else if (opt[cur_opt].type == OPTION_CHECK)    {      opt[cur_opt].tmp_val[cur_item] = !opt[cur_opt].tmp_val[cur_item];      mvwaddch (win, cur_item+1, 3,		opt[cur_opt].tmp_val[cur_item] ? CHAR_CHECK : ' ');    }  wmove (win, cur_item+1, 3);  touchwin (dialog);  wrefresh (dialog);}voidoption_dialog::del_dialog (){  for (int i = 0; i < opt_num; ++i)    delwin (opt[i].box);  delwin (win_ok);  delwin (win_cancel);  wclear (dialog);  wrefresh (dialog);  delwin (dialog);  dialog = 0;}voidoption_dialog::get_value (){  for (int i = 0; i < opt_num; ++i)    {      int len;      if (opt[i].type == OPTION_RADIO)	len = 1;      else if (opt[i].type == OPTION_CHECK)	len = opt[i].item_h;      opt[i].tmp_val = new int[len];      for (int j = 0; j < len; ++j)	opt[i].tmp_val[j] = opt[i].value[j];    }}voidoption_dialog::set_value (bool set){  for (int i = 0; i < opt_num; ++i)    {      int len;      if (opt[i].type == OPTION_RADIO)	len = 1;      else if (opt[i].type == OPTION_CHECK)	len = opt[i].item_h;            if (set)	for (int j = 0; j < len; ++j)	  opt[i].value[j] = opt[i].tmp_val[j];      delete[] opt[i].tmp_val;      opt[i].tmp_val = 0;    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -