home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
fed0217s.zip
/
source
/
dialog.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2001-02-20
|
15KB
|
711 lines
/*
** 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));
}