This repository has been archived on 2023-07-11. You can view files and clone it, but cannot push or open issues or pull requests.
fte/i_choice.cpp

187 lines
4.6 KiB
C++
Raw Permalink Normal View History

/* i_choice.cpp
*
* Copyright (c) 1994-1996, Marko Macek
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
#include "fte.h"
ExChoice::ExChoice(const char *ATitle, int NSel, va_list ap): ExView() {
char msg[1024];
int i;
char *fmt;
Cur = 0;
MouseCaptured = 0;
Title = strdup(ATitle);
lTitle = strlen(Title);
NOpt = NSel;
lChoice = 0;
for (i = 0; i < NSel; i++) {
SOpt[i] = strdup(va_arg(ap, char *));
lChoice += CStrLen(SOpt[i]) + 1;
}
fmt = va_arg(ap, char *);
vsprintf(msg, fmt, ap);
strncpy(Prompt, msg, sizeof(Prompt));
Prompt[sizeof(Prompt) - 1] = 0;
}
ExChoice::~ExChoice() {
free(Title);
for (int i = 0; i < NOpt; i++)
free(SOpt[i]);
}
void ExChoice::Activate(int gotfocus) {
ExView::Activate(gotfocus);
}
int ExChoice::BeginMacro() {
return 1;
}
int ExChoice::FindChoiceByPoint(int x, int y) {
int pos, i;
int W, H;
Win->ConQuerySize(&W, &H);
if (y != H - 1)
return -1;
pos = W - lChoice;
if (x < pos)
return -1;
for (i = 0; i < NOpt; i++) {
int clen = CStrLen(SOpt[i]);
if (x > pos && x <= pos + clen)
return i;
pos += clen + 1;
}
return -1;
}
void ExChoice::HandleEvent(TEvent &Event) {
int i;
switch (Event.What) {
case evKeyDown:
switch (kbCode(Event.Key.Code)) {
case kbTab | kfShift:
case kbLeft: if (Cur == -1) Cur = 0; Cur--; if (Cur < 0) Cur = NOpt - 1; Event.What = evNone; break;
case kbTab:
case kbRight: if (Cur == -1) Cur = 0; Cur++; if (Cur >= NOpt) Cur = 0; Event.What = evNone; break;
case kbHome: Cur = 0; Event.What = evNone; break;
case kbEnd: Cur = NOpt - 1; Event.What = evNone; break;
case kbEnter: if (Cur >= 0 && NOpt > 0) EndExec(Cur); Event.What = evNone; break;
case kbEsc: EndExec(-1); Event.What = evNone; break;
default:
if (isAscii(Event.Key.Code)) {
char c = char(Event.Key.Code & 0xFF);
char s[3];
s[0] = '&';
s[1] = (char)(toupper((char)c) & 0xFF);
s[2] = 0;
for (i = 0; i < NOpt; i++) {
if (strstr(SOpt[i], s) != 0) {
Win->EndExec(i);
break;
}
}
Event.What = evNone;
}
break;
}
break;
case evMouseDown:
if (Win->CaptureMouse(1))
MouseCaptured = 1;
else
break;
Cur = FindChoiceByPoint(Event.Mouse.X, Event.Mouse.Y);
Event.What = evNone;
break;
case evMouseMove:
if (MouseCaptured)
Cur = FindChoiceByPoint(Event.Mouse.X, Event.Mouse.Y);
Event.What = evNone;
break;
case evMouseUp:
if (MouseCaptured)
Win->CaptureMouse(0);
else
break;
MouseCaptured = 0;
Cur = FindChoiceByPoint(Event.Mouse.X, Event.Mouse.Y);
Event.What = evNone;
if (Cur >= 0 && Cur < NOpt && NOpt > 0)
EndExec(Cur);
else
Cur = 0;
break;
}
}
void ExChoice::UpdateView() {
if (Next) {
Next->UpdateView();
}
}
void ExChoice::RepaintView() {
if (Next) {
Next->RepaintView();
}
}
void ExChoice::UpdateStatus() {
RepaintStatus();
}
void ExChoice::RepaintStatus() {
TDrawBuffer B;
int W, H;
int pos, i;
TAttr color1, color2;
ConQuerySize(&W, &H);
if (Cur != -1) {
if (Cur >= NOpt) Cur = NOpt - 1;
if (Cur < 0) Cur = 0;
}
MoveCh(B, ' ', hcChoice_Background, W);
MoveStr(B, 0, W, Title, hcChoice_Title, W);
MoveChar(B, lTitle, W, ':', hcChoice_Background, 1);
MoveStr(B, lTitle + 2, W, Prompt, hcChoice_Param, W);
pos = W - lChoice;
for (i = 0; i < NOpt; i++) {
if (i == Cur) {
color1 = hcChoice_ActiveItem;
color2 = hcChoice_ActiveChar;
} else {
color1 = hcChoice_NormalItem;
color2 = hcChoice_NormalChar;
}
if (i == Cur)
ConSetCursorPos(pos + 1, H - 1);
MoveChar(B, pos, W, ConGetDrawChar(DCH_V), hcChoice_Background, 1);
MoveCStr(B, pos + 1, W, SOpt[i], color1, color2, W);
pos += CStrLen(SOpt[i]) + 1;
}
ConPutBox(0, H - 1, W, 1, B);
}