mirror of
https://github.com/KranX/Vangers.git
synced 2025-12-01 07:25:28 +07:00
555 lines
13 KiB
C++
555 lines
13 KiB
C++
/*
|
|
Simple-Quick Interface by K-Division::KranK
|
|
All Rights Reserved (C)1995
|
|
(Menu)
|
|
*/
|
|
|
|
#include "..\global.h"
|
|
#pragma hdrstop
|
|
|
|
#include "sqint.h"
|
|
|
|
/* ---------------------------- EXTERN SECTION ----------------------------- */
|
|
/* --------------------------- PROTOTYPE SECTION --------------------------- */
|
|
/* --------------------------- DEFINITION SECTION -------------------------- */
|
|
const int MAXSEEK = 32;
|
|
const int SEEKDELAY = 10;
|
|
|
|
sqMenuBar::sqMenuBar(unsigned char* s,sqPopupMenu* owner,int _status,int _value,int _rec)
|
|
{
|
|
int m = owner -> margin;
|
|
int sl = s?strlen((char*)s):0;
|
|
int l = sl + 2*m;
|
|
if(l > owner -> len) owner -> setlen(l);
|
|
else l = owner -> len;
|
|
data = new unsigned char[l + 1];
|
|
original_data = (unsigned char*)strdup((char*)s);
|
|
memset(data,' ',m);
|
|
if(s) memcpy(data + m,s,sl);
|
|
memset(data + m + sl,' ',l - sl - m);
|
|
data[l] = '\0';
|
|
if((status = _status) != 0) *data = 4;
|
|
value = _value;
|
|
rec = _rec;
|
|
}
|
|
|
|
void sqMenuBar::replace(sqPopupMenu* owner,unsigned char* s)
|
|
{
|
|
int m = owner -> margin;
|
|
int sl = s?strlen((char*)s):0;
|
|
int l = sl + 2*m;
|
|
if(l > owner -> len){
|
|
owner -> setlen(l);
|
|
delete data;
|
|
data = new unsigned char[l + 1];
|
|
}
|
|
else
|
|
l = owner -> len;
|
|
if(s) memcpy(data + m,s,sl);
|
|
memset(data + m + sl,' ',l - sl - m);
|
|
data[l] = '\0';
|
|
}
|
|
|
|
sqPopupMenu::sqPopupMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _len0,int _margin)
|
|
{
|
|
owner = _owner;
|
|
x = _x; y = _y;
|
|
sx = sy = 0;
|
|
visibars = _visibars;
|
|
margin = _margin;
|
|
font = _font;
|
|
len = len0 = _len0;
|
|
if(_len0) sx = _len0*_font -> sx, set();
|
|
maxbars = topbar = nbar = seekcounter = 0;
|
|
first = pointer = insert = NULL;
|
|
seeklen = 0;
|
|
seekbuf = new unsigned char[MAXSEEK + 1];
|
|
}
|
|
|
|
sqPopupMenu& sqPopupMenu::operator* (sqMenuBar* obj)
|
|
{
|
|
if(!first){
|
|
first = pointer = obj;
|
|
first -> next = first -> prev = NULL;
|
|
}
|
|
else {
|
|
obj -> prev = insert;
|
|
if(insert){
|
|
obj -> next = insert -> next;
|
|
if(insert -> next) insert -> next -> prev = obj;
|
|
insert -> next = obj;
|
|
}
|
|
else {
|
|
obj -> next = first;
|
|
first -> prev = obj;
|
|
first = obj;
|
|
}
|
|
}
|
|
insert = obj;
|
|
maxbars++;
|
|
sy = MIN(maxbars,visibars)*font -> sy; set(height);
|
|
return *this;
|
|
}
|
|
|
|
void sqPopupMenu::disconnect(sqMenuBar* obj,sqMenuBar** del)
|
|
{
|
|
if(obj == insert)
|
|
if(obj -> next) insert = obj -> next;
|
|
else insert = obj -> prev;
|
|
if(obj == first){
|
|
if(obj -> next) obj -> next -> prev = NULL;
|
|
first = obj -> next;
|
|
}
|
|
else {
|
|
obj -> prev -> next = obj -> next;
|
|
if(obj -> next) obj -> next -> prev = obj -> prev;
|
|
}
|
|
if(!del)
|
|
delete obj;
|
|
else {
|
|
obj -> next = *del;
|
|
*del = obj;
|
|
}
|
|
maxbars--;
|
|
sy = MIN(maxbars,visibars)*font -> sy; set(height);
|
|
}
|
|
|
|
void sqPopupMenu::setlen(int l)
|
|
{
|
|
sqMenuBar* p = first;
|
|
unsigned char* s;
|
|
if(l > len)
|
|
while(p){
|
|
s = new unsigned char[l + 1];
|
|
memcpy(s,p -> data,len);
|
|
memset(s + len,' ',l - len);
|
|
s[l] = '\0';
|
|
delete p -> data;
|
|
p -> data = s;
|
|
p = p -> next;
|
|
}
|
|
else
|
|
if(l < len)
|
|
while(p){
|
|
p -> data[l] = '\0';
|
|
p = p -> next;
|
|
}
|
|
len = l;
|
|
sx = len*font -> sx; set(height);
|
|
}
|
|
|
|
void sqPopupMenu::draw(int self)
|
|
{
|
|
nbar = getptr(pointer);
|
|
sqMenuBar* p = getbar(topbar);
|
|
int i = y,j = 0;
|
|
while(p && j < visibars){
|
|
if(p == pointer)
|
|
font -> draw(getX() + x,getY() + i,p -> data,SQ_SYSCOLOR,SQ_SYSCOLOR + 6 + (2 - height));
|
|
else
|
|
font -> draw(getX() + x,getY() + i,p -> data,SQ_SYSCOLOR,SQ_SYSCOLOR + 5);
|
|
i += font -> sy; j++;
|
|
p = p -> next;
|
|
}
|
|
sqElem::draw();
|
|
owner -> message(M_CHANGEOPTION);
|
|
}
|
|
|
|
sqMenuBar* sqPopupMenu::getbar(int n)
|
|
{
|
|
sqMenuBar* p = first;
|
|
while(p){
|
|
if(!n) return p;
|
|
p = p -> next;
|
|
n--;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int sqPopupMenu::getptr(sqMenuBar* b)
|
|
{
|
|
sqMenuBar* p = first;
|
|
int i = 0;
|
|
while(p){
|
|
if(p == b) return i;
|
|
p = p -> next;
|
|
i++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void sqPopupMenu::keytrap(int key)
|
|
{
|
|
switch(key){
|
|
case VK_TAB:
|
|
if(XKey.Pressed(VK_SHIFT))
|
|
owner -> message(M_PREVOBJ);
|
|
else
|
|
owner -> message(M_NEXTOBJ);
|
|
seeklen = 0;
|
|
break;
|
|
case VK_F7:
|
|
case VK_INSERT:
|
|
owner -> message(M_INSERT);
|
|
break;
|
|
case VK_F8:
|
|
case VK_DELETE:
|
|
owner -> message(M_DELETE);
|
|
break;
|
|
case VK_SPACE:
|
|
owner -> message(M_SETOPTION);
|
|
break;
|
|
case VK_RETURN:
|
|
if(XKey.Pressed(VK_SHIFT)){
|
|
if(seeklen)
|
|
if(pointer -> next)
|
|
seek(pointer -> next);
|
|
else
|
|
seek(first);
|
|
}
|
|
else {
|
|
seeklen = 0;
|
|
owner -> message(M_CHOICE);
|
|
}
|
|
break;
|
|
case VK_RSHIFT:
|
|
sqInputString::rus = 1 - sqInputString::rus;
|
|
break;
|
|
case VK_UP:
|
|
if(!pointer -> prev){
|
|
pointer = getbar(maxbars - 1);
|
|
topbar = (maxbars >= visibars)?maxbars - visibars:0;
|
|
}
|
|
else {
|
|
if(pointer == getbar(topbar)) topbar--;
|
|
pointer = pointer -> prev;
|
|
}
|
|
draw();
|
|
seeklen = 0;
|
|
break;
|
|
case VK_DOWN:
|
|
if(!pointer -> next){
|
|
pointer = first;
|
|
topbar = 0;
|
|
}
|
|
else {
|
|
if(getptr(pointer) - topbar + 1 == visibars) topbar++;
|
|
pointer = pointer -> next;
|
|
}
|
|
draw();
|
|
seeklen = 0;
|
|
break;
|
|
case VK_HOME:
|
|
if(pointer){
|
|
pointer = first;
|
|
topbar = 0;
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_END:
|
|
if(pointer -> next){
|
|
pointer = getbar(maxbars - 1);
|
|
topbar = (maxbars >= visibars)?maxbars - visibars:0;
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_LEFT:
|
|
if(pointer != getbar(topbar)){
|
|
pointer = getbar(topbar);
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_RIGHT:
|
|
if(pointer != getbar(topbar + MIN(visibars,maxbars) - 1)){
|
|
pointer = getbar(topbar + MIN(visibars,maxbars) - 1);
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_PRIOR:
|
|
if(pointer){
|
|
topbar = getptr(pointer) - visibars;
|
|
if(topbar < 0) topbar = 0;
|
|
pointer = getbar(topbar);
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_NEXT:
|
|
if(pointer != getbar(maxbars - 1)){
|
|
topbar = getptr(pointer) + visibars;
|
|
if(topbar >= maxbars) topbar = maxbars - 1;
|
|
pointer = getbar(topbar);
|
|
topbar -= MIN(maxbars,visibars) - 1;
|
|
draw();
|
|
}
|
|
seeklen = 0;
|
|
break;
|
|
case VK_OEM_PLUS:
|
|
owner -> message(M_SETALL);
|
|
break;
|
|
case VK_OEM_MINUS:
|
|
owner -> message(M_UNSETALL);
|
|
break;
|
|
default:
|
|
if(CLOCK() - seekcounter > SEEKDELAY) seeklen = 0;
|
|
if(seeklen <= MAXSEEK){
|
|
seekbuf[seeklen++] = key; // !
|
|
seek(pointer);
|
|
seekcounter = CLOCK();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sqPopupMenu::handler(sqEvent* e)
|
|
{
|
|
int n;
|
|
sqMenuBar* pb;
|
|
switch(e -> code){
|
|
case E_LBMPRESS:
|
|
// if( XGR_MouseObj.GetLeftClip() != getX() + x + XGR_MouseObj.SizeX/2){
|
|
// XGR_MouseObj.SetClip(getX() + x + XGR_MouseObj.SizeX/2, getY() + y + XGR_MouseObj.SizeY/2, getX() + x + sx - XGR_MouseObj.SizeX/2, getY() + y + sy - XGR_MouseObj.SizeY/2);
|
|
// XGR_MouseObj.left = getX() + x + XGR_MouseObj.SizeX/2;
|
|
// XGR_MouseObj.top = getY() + y + XGR_MouseObj.SizeY/2;
|
|
// XGR_MouseObj.right = getX() + x + sx - XGR_MouseObj.SizeX/2;
|
|
// XGR_MouseObj.bottom = getY() + y + sy - XGR_MouseObj.SizeY/2;
|
|
// XGR_MouseObj.change();
|
|
// }
|
|
owner -> message(M_SETOBJ,this);
|
|
n = topbar + (e -> y - (getY() + y))/font -> sy;
|
|
if(n >= maxbars) n = maxbars - 1;
|
|
pb = pointer;
|
|
pointer = getbar(n);
|
|
if(XGR_MouseObj.LastPosY > XGR_MouseObj.PosY && topbar + visibars - 1 == getptr(pointer)){
|
|
if(pointer -> next){
|
|
topbar++;
|
|
pointer = pointer -> next;
|
|
}
|
|
}
|
|
else
|
|
if(XGR_MouseObj.LastPosY < XGR_MouseObj.PosY && topbar == getptr(pointer)){
|
|
if(pointer -> prev){
|
|
topbar--;
|
|
pointer = pointer -> prev;
|
|
}
|
|
}
|
|
if(pointer != pb) draw();
|
|
break;
|
|
case E_LBMUNPRESS:
|
|
// XGR_MouseObj.SetClip(sqScr -> x + XGR_MouseObj.SizeX/2, sqScr -> y + XGR_MouseObj.SizeY/2, sqScr -> x + sqScr -> sx - XGR_MouseObj.SizeX/2, sqScr -> y + sqScr -> sy - XGR_MouseObj.SizeY/2);
|
|
// XGR_MouseObj.left = sqScr -> x + XGR_MouseObj.SizeX/2;
|
|
// XGR_MouseObj.right = sqScr -> x + sqScr -> sx - XGR_MouseObj.SizeX/2;
|
|
// XGR_MouseObj.top = sqScr -> y + XGR_MouseObj.SizeY/2;
|
|
// XGR_MouseObj.bottom = sqScr -> y + sqScr -> sy - XGR_MouseObj.SizeY/2;
|
|
// XGR_MouseObj.change();
|
|
break;
|
|
case E_LBMDOUBLE:
|
|
owner -> message(M_SETOBJ,this);
|
|
n = topbar + (e -> y - (getY() + y))/font -> sy;
|
|
if(n >= maxbars) n = maxbars - 1;
|
|
pointer = getbar(n);
|
|
draw();
|
|
owner -> message(M_SETOPTION);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sqPopupMenu::activate(int force)
|
|
{
|
|
// QuantObj = this;
|
|
if(force) remove();
|
|
set(1);
|
|
if(force) draw();
|
|
}
|
|
|
|
void sqPopupMenu::deactivate(void)
|
|
{
|
|
remove();
|
|
set(2);
|
|
draw();
|
|
}
|
|
|
|
void sqPopupMenu::seek(sqMenuBar* p0,int force)
|
|
{
|
|
sqMenuBar* p = p0;
|
|
while(p){
|
|
if(!memicmp(p -> data + margin,seekbuf,seeklen)){
|
|
setpointer(p,force);
|
|
return;
|
|
}
|
|
p = p -> next;
|
|
}
|
|
p = first;
|
|
while(p != p0){
|
|
if(!memicmp(p -> data + margin,seekbuf,seeklen)){
|
|
setpointer(p,force);
|
|
return;
|
|
}
|
|
p = p -> next;
|
|
}
|
|
}
|
|
|
|
void sqPopupMenu::setpointer(sqMenuBar* p,int force)
|
|
{
|
|
int dif = getptr(pointer) - topbar;
|
|
pointer = p;
|
|
topbar = getptr(p) - dif;
|
|
if(topbar < 0) topbar = 0;
|
|
else topbar = MIN(topbar,maxbars - MIN(maxbars,visibars));
|
|
if(force) draw();
|
|
}
|
|
|
|
void sqPopupMenu::free(void)
|
|
{
|
|
sqMenuBar* p = first,*p0;
|
|
while(p){
|
|
p0 = p -> next;
|
|
delete p;
|
|
p = p0;
|
|
}
|
|
if(first){
|
|
maxbars = topbar = nbar = seekcounter = 0;
|
|
first = pointer = insert = NULL;
|
|
len = len0;
|
|
seeklen = 0;
|
|
}
|
|
}
|
|
|
|
sqMultiMenu::sqMultiMenu(sqElem* _owner,int _x,int _y,int _visibars,sqFont* _font,int _maxlen)
|
|
{
|
|
owner = _owner;
|
|
x = _x; y = _y;
|
|
maxlen = _maxlen;
|
|
sx = _maxlen*_font -> sx + 2;
|
|
sy = _font -> sy + 8 + _visibars*_font -> sy + 2;
|
|
set(0);
|
|
*this + (edit = new sqInputString(this,2,0,_font -> sx*(_maxlen + 1),_font,(unsigned char*)NULL,_maxlen));
|
|
*this + (list = new sqPopupMenu(this,2,_font -> sy + 8,_visibars,_font,_maxlen + 2));
|
|
obj = NULL;
|
|
deleted = NULL;
|
|
}
|
|
|
|
void sqMultiMenu::keytrap(int key)
|
|
{
|
|
obj -> keytrap(key);
|
|
}
|
|
|
|
void sqMultiMenu::activate(int force)
|
|
{
|
|
obj = list;
|
|
obj -> activate();
|
|
}
|
|
|
|
void sqMultiMenu::deactivate(void)
|
|
{
|
|
obj -> deactivate();
|
|
obj = NULL;
|
|
}
|
|
|
|
void sqMultiMenu::message(int code,sqElem* object)
|
|
{
|
|
sqMenuBar* p;
|
|
switch(code){
|
|
case M_NEXTOBJ:
|
|
obj -> deactivate();
|
|
if(obj == edit){
|
|
obj = list;
|
|
obj -> activate();
|
|
}
|
|
else
|
|
owner -> message(M_NEXTOBJ);
|
|
break;
|
|
case M_PREVOBJ:
|
|
obj -> deactivate();
|
|
if(obj == edit){
|
|
obj = list;
|
|
obj -> activate();
|
|
}
|
|
else
|
|
owner -> message(M_PREVOBJ);
|
|
break;
|
|
case M_SETOBJ:
|
|
if(object != obj){
|
|
if((obj == edit && object == list) || (obj == list && object == edit))
|
|
obj -> deactivate();
|
|
else
|
|
owner -> message(M_DEACTIVATE,this);
|
|
obj = object;
|
|
obj -> activate();
|
|
}
|
|
break;
|
|
case M_CHOICE:
|
|
if(obj == edit){
|
|
list -> pointer -> replace(list,edit -> str);
|
|
obj -> deactivate();
|
|
obj = list;
|
|
obj -> activate();
|
|
}
|
|
else {
|
|
obj -> deactivate();
|
|
obj = edit;
|
|
obj -> activate();
|
|
}
|
|
break;
|
|
case M_SETOPTION:
|
|
list -> pointer -> status = 1 - list -> pointer -> status;
|
|
if(list -> pointer -> status) *list -> pointer -> data = 4;
|
|
else *list -> pointer -> data = ' ';
|
|
list -> draw();
|
|
break;
|
|
case M_CHANGEOPTION:
|
|
edit -> setstr(list -> pointer -> data + list -> margin);
|
|
edit -> draw();
|
|
owner -> message(M_CHANGEOPTION);
|
|
break;
|
|
case M_DELETE:
|
|
if(list -> maxbars > 1){
|
|
if(list -> pointer -> next) list -> insert = list -> pointer -> next;
|
|
else list -> insert = list -> pointer -> prev;
|
|
list -> remove();
|
|
list -> disconnect(list -> pointer,&deleted);
|
|
list -> pointer = list -> insert;
|
|
list -> draw();
|
|
}
|
|
break;
|
|
case M_INSERT:
|
|
if(!edit -> insert) list -> insert = list -> pointer;
|
|
else list -> insert = list -> pointer -> prev;
|
|
*list * new sqMenuBar((unsigned char*)NULL,list);
|
|
list -> pointer = list -> insert;
|
|
list -> draw();
|
|
message(M_CHOICE);
|
|
break;
|
|
case M_SETALL:
|
|
p = list -> first;
|
|
while(p){
|
|
*p -> data = 4;
|
|
p -> status = 1;
|
|
p = p -> next;
|
|
}
|
|
list -> draw();
|
|
break;
|
|
case M_UNSETALL:
|
|
p = list -> first;
|
|
while(p){
|
|
*p -> data = ' ';
|
|
p -> status = 0;
|
|
p = p -> next;
|
|
}
|
|
list -> draw();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sqMultiMenu::restore(int _x,int _y,int _sx,int _sy)
|
|
{
|
|
XGR_Rectangle(_x,_y,_sx,_sy,SQ_SYSCOLOR + 4,SQ_SYSCOLOR + 4,XGR_FILLED);
|
|
}
|
|
|
|
|
|
|