home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Module :DIALOG.CPP
- ** Abstract :Simple Text UI
- **
- ** Copyright (C) Sergey I. Yevtushenko
- **
- ** Log: Fri 07/11/1997 Created
- */
-
- #include <string.h>
-
- #include <dialog.h>
- #include <keynames.h>
- #include <version.h>
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
- Control::Control(int r, int c, int nr, int nc)
- {
- row = r;
- col = c;
- rows = nr;
- cols = nc;
- active = hotkey = 0;
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
-
- Dialog::Dialog(int r, int c, int nr, int nc)
- :Control(r, c, nr, nc),
- savebuff(0),
- current(-1)
- {
- }
-
- void Dialog::draw()
- {
- int i;
-
- vio_cursor_type(NoCursor);
-
- if(!savebuff)
- savebuff = vio_save_box(row, col, rows + 1, cols + 1);
-
- vio_box(row, col, rows, cols, 0, mk_clr(CL_DEFAULT));
-
- for(i = 1; i < rows - 1; i++)
- vio_hdraw(row + i, col + 1, ' ', cols - 2, mk_clr(CL_BORDER));
-
- for(i = 0; i < Count(); i++)
- {
- Control* ctrl = (Control*)Get(i);
-
- if(ctrl)
- ctrl->draw();
- }
-
- for(i = 0; i < rows; i++)
- vio_show_str(row + i, col, cols);
- }
-
- Dialog::~Dialog()
- {
- if(savebuff)
- vio_restore_box(savebuff);
-
- RemoveAll();
- }
-
- void Dialog::Free(Ptr p)
- {
- delete (Control *)p;
- }
-
- void Dialog::do_key(KeyInfo& k)
- {
- switch(k.skey & 0x00FF)
- {
- case kbTab:
- if(k.skey & shShift)
- prev();
- else
- next();
- return;
-
- case kbEnter:
- next();
- return;
- }
-
- PControl ctl = in_focus();
-
- if(ctl)
- ctl->do_key(k);
- }
-
- void Dialog::next()
- {
- int i;
-
- //1: from current to end
- for(i = current+1; i < Count(); i++)
- {
- if(control(i)->select(1))
- {
- control(current)->select(0);
- current = i;
- return;
- }
- }
-
- //2: from start to current
- for(i = 0; i < current; i++)
- {
- if(control(i)->select(1))
- {
- control(current)->select(0);
- current = i;
- return;
- }
- }
- }
-
- void Dialog::prev()
- {
- int i;
-
- //1: from current to start
- for(i = current-1; i >= 0; i--)
- {
- if(control(i)->select(1))
- {
- control(current)->select(0);
- current = i;
- return;
- }
- }
-
- //2: from end to current
- for(i = Count()- 1; i > current ; i--)
- {
- if(control(i)->select(1))
- {
- control(current)->select(0);
- current = i;
- return;
- }
- }
- }
-
- void Dialog::Ins(Control* ctrl)
- {
- ctrl->move(ctrl->row + row, ctrl->col + col);
-
- Collection::Add(ctrl);
-
- if(current < 0 && ctrl->select(1))
- current = Count()-1;
- }
-
- void Dialog::move(int r, int c)
- {
- int off_r = r - row;
- int off_c = c - col;
-
- for(int i = 0; i < Count(); i++)
- {
- Control* ctrl = (Control*)Get(i);
-
- if(ctrl)
- ctrl->move(ctrl->row + off_r, ctrl->col + off_c);
- }
- Control::move(r,c);
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
-
- StaticText::StaticText(int r, int c, int nr, int nc, char *aText)
- :Control(r,c,nr,nc)
- {
- text = 0;
- set_text(aText);
- }
-
- void StaticText::draw()
- {
- vio_printh(row, col, text, cols, mk_clr(CL_DEFAULT), mk_clr(CL_HILITE));
- }
-
- StaticText::~StaticText()
- {
- delete text;
- }
-
- void StaticText::set_text(char *aText)
- {
- delete text;
- text = new char[strlen(aText)+1];
- strcpy(text, aText);
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
- void ListBoxItem::set_text(char *aText)
- {
- if(text)
- {
- delete text;
- text = 0;
- len = 0;
- }
- if(aText)
- {
- len = strlen(aText);
- text = new char[len + 1];
- strcpy(text, aText);
- }
- }
-
- ListBoxItem::~ListBoxItem()
- {
- set_text(0);
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
- ListBox::ListBox(int r, int c, int nr, int nc, int opt)
- :Control(r,c,nr,nc),Collection(128,128),flags(opt)
- {
- start_row = cur_row = 0;
- start_x = 0;
- index_ptr = -1;
- last_sel_was_key = 0;
-
- if(opt & lbMultiSel)
- flags &= ~lbWrap;
- }
-
- void ListBox::draw()
- {
- if(flags & lbHilite)
- {
- for(int i = 0; i < rows; i++)
- {
- int color1 = (cur_row == i) ? CL_CURRENT:CL_DEFAULT;
- int color2 = (cur_row == i) ? CL_CURRSEL:CL_SELECTION;
-
- char *txt = get_item_text(start_row + i);
-
- if(!txt)
- txt = "";
-
- if(start_x > cstrlen(txt))
- txt = "";
- else
- txt = &txt[start_x];
-
- vio_printh(row+i, col, txt, cols, mk_clr(color1), mk_clr(color2));
- }
- }
- else
- {
- for(int i = 0; i < rows; i++)
- {
- int color = (cur_row == i) ? CL_CURRENT:CL_DEFAULT;
- if(item(start_row + i))
- if(item(start_row + i)->flags & ListBoxItem::lbiSelected)
- color = (cur_row == i) ? CL_CURRSEL:CL_SELECTION;
-
- char *txt = get_item_text(start_row + i);
-
- if(!txt)
- txt = "";
-
- if(start_x > strlen(txt))
- txt = "";
- else
- txt = &txt[start_x];
-
- vio_print(row+i, col, txt, cols, mk_clr(color));
- }
- }
- }
-
- int ListBox::first_selected()
- {
- if(!(flags & lbMultiSel))
- return abs_row();
- for(index_ptr = 0; index_ptr < Count(); index_ptr++)
- {
- if(item(index_ptr)->flags & ListBoxItem::lbiSelected)
- return index_ptr;
- }
- return (index_ptr = -1);
- }
-
- int ListBox::next_selected()
- {
- if(index_ptr < 0)
- return -1;
-
- for(++index_ptr; index_ptr < Count(); index_ptr++)
- {
- if(item(index_ptr)->flags & ListBoxItem::lbiSelected)
- return index_ptr;
- }
- return (index_ptr = -1);
- }
-
- char* ListBox::get_item_text(int ndx)
- {
- PListBoxItem p = item(ndx);
-
- if(p)
- return p->get_text();
- return 0;
- }
-
- void ListBox::set_item_text(int ndx, char* text)
- {
- PListBoxItem p = item(ndx);
-
- if(p)
- p->set_text(text);
- }
-
- unsigned ListBox::get_item_key(int ndx)
- {
- PListBoxItem p = item(ndx);
-
- if(p)
- return p->userdata;
- return 0;
- }
-
- void ListBox::set_item_key(int ndx, unsigned int key)
- {
- PListBoxItem p = item(ndx);
-
- if(p)
- p->userdata = key;
- }
-
- void ListBox::add_item(char *text, int pos)
- {
- if(pos < 0 || pos > Count())
- return;
-
- At(new ListBoxItem(text), pos);
- }
-
- void ListBox::del_item(int index)
- {
- Free(Remove(index));
- }
-
- void ListBox::go_item(int index)
- {
- if(index < 0 || index > Count())
- return;
- while(index < abs_row())
- prev();
- while(index > abs_row())
- next();
- }
-
-
- void ListBox::Free(Ptr p)
- {
- delete PListBoxItem(p);
- }
- void ListBox::prev()
- {
-
- if((flags & lbWrap) && abs_row() == 0)
- {
- while(abs_row() < Count() - 1)
- {
- cur_row++;
- if(cur_row + start_row >= Count())
- cur_row = Count() - start_row - 1;
-
- if(cur_row >= rows)
- {
- start_row += cur_row - rows + 1;
- cur_row = rows-1;
- }
- }
- return;
- }
-
-
- if(!(flags & lbMultiSel))
- item(abs_row())->flags &= ~ListBoxItem::lbiSelected;
-
-
- cur_row--;
- if(cur_row < 0)
- {
- start_row += cur_row;
- cur_row = 0;
- }
- if(start_row <0)
- start_row = 0;
-
- if(!(flags & lbMultiSel))
- item(abs_row())->flags |= ListBoxItem::lbiSelected;
- }
-
- void ListBox::next()
- {
-
- if((flags & lbWrap) && abs_row() == (Count() - 1))
- {
- cur_row = start_row = 0;
- return;
- }
-
-
- if(!(flags & lbMultiSel))
- item(abs_row())->flags &= ~ListBoxItem::lbiSelected;
-
- cur_row++;
-
- if(cur_row + start_row >= Count())
- cur_row = Count() - start_row - 1;
-
- if(cur_row >= rows)
- {
- if(flags & lbCanScroll)
- {
- start_row += cur_row - rows + 1;
- cur_row = rows-1;
- }
- else
- cur_row = rows-1;
- }
-
- if(!(flags & lbMultiSel))
- item(abs_row())->flags |= ListBoxItem::lbiSelected;
- }
-
- void ListBox::sel(KeyInfo& k)
- {
- if(flags & lbMultiSel)
- {
- if((k.skey & shCtrl) == shCtrl)
- item(abs_row())->flags |= ListBoxItem::lbiSelected;
- if((k.skey & shShift) == shShift)
- item(abs_row())->flags &= ~ListBoxItem::lbiSelected;
- if((k.skey & shAlt) == shAlt)
- item(abs_row())->flags ^= ListBoxItem::lbiSelected;
- }
- }
-
- void ListBox::do_key(KeyInfo& k)
- {
- int i;
-
- last_sel_was_key = 0;
-
- switch(k.skey & 0x00FF)
- {
- case kbLeft:
- if(flags & lbXScroll)
- {
- if(start_x > 0)
- start_x--;
- }
- break;
-
- case kbRight:
- if(flags & lbXScroll)
- {
- start_x++;
- }
- break;
-
- case kbUp:
- sel(k);
- prev();
- break;
-
- case kbDown:
- sel(k);
- next();
- break;
-
- case kbPgUp:
-
- for(i = 0; i < rows; i++)
- {
- sel(k);
- prev();
- }
- break;
-
- case kbPgDown:
-
- for(i = 0; i < rows; i++)
- {
- sel(k);
- next();
- }
- break;
-
- case kbEnd:
-
- if(!(k.skey & shCtrl) || !(flags & lbXScroll))
- {
- while(abs_row() < (Count() - 1))
- {
- sel(k);
- next();
- }
- }
- else
- {
- if(flags & lbXScroll)
- {
- //start_x = ;
- char *s = item(abs_row())->text;
- int i = cstrlen(s);
-
- while(start_x < (i - cols))
- start_x++;
- }
- }
-
- break;
-
- case kbHome:
-
- if(!(k.skey & shCtrl) || !(flags & lbXScroll))
- {
- while(abs_row())
- {
- //i = abs_row();
- sel(k);
- prev();
- }
-
- }
- else
- if(flags & lbXScroll)
- start_x = 0;
-
- break;
-
- case kbSpace:
- if(flags & lbMultiSel)
- item(abs_row())->flags ^= ListBoxItem::lbiSelected;
- break;
-
- default:
- if(!(k.skey & shIsCtrl)) //Usual key
- {
- //Search forward
- int i;
-
- for(i = abs_row() + 1; i < Count(); i++)
- {
- if(item_char(i) == __to_upper((char)k.key))
- break;
- }
-
- if(i < Count())
- {
- go_item(i);
- last_sel_was_key = 1;
- break;
- }
-
- for(i = 0; i < abs_row(); i++)
- {
- if(item_char(i) == __to_upper((char)k.key))
- break;
- }
-
- if(i < abs_row())
- {
- last_sel_was_key = 1;
- go_item(i);
- break;
- }
-
- if(item_char(abs_row()) == __to_upper((char)k.key))
- last_sel_was_key = 1;
-
- break;
- }
- }
- }
-
- char ListBox::item_char(int ndx)
- {
- if(ndx < 0 || ndx >= Count())
- return 0;
-
- char* s = item(ndx)->text;
-
- if(flags & lbHilite)
- {
- while(*s && *s != SWITCH_CHAR)
- s++;
-
- if(*s)
- s++;
- }
- else
- {
- while(*s && __issp(*s))
- s++;
- }
-
- return __to_upper(*s);
- }
-
- char ListBox::mk_clr(int index)
- {
- return app_pal[(active ? CL_LISTBOX_ACTIVE:CL_LISTBOX_INACTIVE) + index];
- }
-
- ListBox::~ListBox()
- {
- RemoveAll();
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
-
- Menu::Menu(int r, int c, char **itemlist)
- :ListBox(r,c,0,1,ListBox::lbHilite | ListBox::lbWrap)
- {
- int i;
-
- if(itemlist)
- for(i = 0; itemlist[i]; i++)
- add_menu(itemlist[i]);
- }
-
- void Menu::add_menu(char* item)
- {
- int len = cstrlen(item);
-
- if(len > cols)
- cols = len;
-
- add_at_end(item);
- rows++;
- }
-
- char Menu::mk_clr(int index)
- {
- return app_pal[CL_MENU+index];
- }
-
- //----------------------------------------------------------------------
- //
- //----------------------------------------------------------------------
-
- JumpEntryHolder::JumpEntryHolder(int arow, int acol, char *name, char *file):
- row(arow), col(acol)
- {
- if(name)
- {
- hdr = new char[strlen(name)+1];
- strcpy(hdr, name);
- }
- else
- {
- hdr = new char[1];
- hdr[0] = 0;
- }
-
- if(file)
- {
- text = new char[strlen(file)+1];
- strcpy(text, file);
- }
- else
- {
- text = new char[1];
- text[0] = 0;
- }
- }
-
- JumpEntryHolder::~JumpEntryHolder()
- {
- delete text;
- delete hdr;
- }
-
- JumpList::~JumpList()
- {
- RemoveAll();
- }
-
- void JumpList::add_entry(int row, int col, char *name, char *file)
- {
- Add(new JumpEntryHolder(row, col, name, file));
- }
-