📄 list.cpp
字号:
////////////////////////////////////////////
// //
// List.cpp //
// List类实现 //
// 在打开文件列表中专用 //
// 最后更新时间:2004年4月23日11:33 //
// //
////////////////////////////////////////////
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include "List.h"
List::List(const int Top, const int Left, const int Bottom, const int Right)
{
// 初始化
// 设置列表的左上角坐标
x0 = Top;
y0 = Left;
// 设置列表的右下角坐标
x1 = Bottom;
y1 = Right;
// 最新元素序号
TotItem = -1;
// 垂直滚动条游标位置
VerticalPos = Top + 2;
// 首行元素序号
HeadLine = 0;
}
List::~List()
{
}
void List::Add(const char New[MaxLenOfItem], const char Mess[MaxLenOfMessage])
{
// 添加新的元素
if (TotItem < MaxItem - 1)
{
// 可以继续添加
// 添加新的元素
TotItem++;
strcpy(Item[TotItem].Name, New);
strcpy(Item[TotItem].Message, Mess);
Item[TotItem].Chosen = false;
}
}
void List::SetTitle(const char Caption[MaxLenOfTitle])
{
// 设置标题
strcpy(Title, Caption);
}
void List::SetColor(const int FrameColor1, const int FrameColor2, const int TextColor1, const int TextColor2)
{
// 设置边框的前景色
FrameForeground = FrameColor1;
// 设置边框的背景色
FrameBackground = FrameColor2;
// 设置文本的前景色
TextForeground = TextColor1;
// 设置文本的背景色
TextBackground = TextColor2;
}
void List::Show()
{
// 显示列表
// 打印边框
// 设置颜色
::SetColor(FrameForeground, FrameBackground);
// 打印上下边框
for (int i = Left() + 1; i <= Right() - 1; i++)
{
PrintChar(Top(), i, 205);
PrintChar(Bottom(), i, 205);
}
// 打印左右边框
for (i = Top() + 1; i <= Bottom() - 1; i++)
{
PrintChar(i, Left(), 186);
PrintChar(i, Right(), 186);
}
// 打印4个角
PrintChar(Top(), Left(), 201);
PrintChar(Top(), Right(), 187);
PrintChar(Bottom(), Left(), 200);
PrintChar(Bottom(), Right(), 188);
// 打印标题
gotoxy((Right() - Left() - strlen(Title)) / 2 + Left(), Top());
cprintf(" %s ", Title);
// 打印阴影
// 设置颜色
::SetColor(LIGHTGRAY, BLACK);
// 打印右侧阴影
for (i = Top() + 1; i <= Bottom() + 1; i++)
{
PrintChar(i, Right() + 1, 32);
PrintChar(i, Right() + 2, 32);
}
// 打印底部阴影
for (i = Left() + 1; i <= Right(); i++)
{
PrintChar(Bottom() + 1, i, 32);
}
// 打印垂直滚动条
// 设置颜色
::SetColor(CYAN, LIGHTBLUE);
// 打印滑轨
for (i = Top() + 2; i <=Bottom() - 2; i++)
{
PrintChar(i, Right(), 177);
}
// 设置颜色
::SetColor(BLUE, CYAN);
// 打印上下指示箭头
PrintChar(Top() + 1, Right(), 30);
PrintChar(Bottom() - 1, Right(), 31);
// 打印游标
PrintChar(Top() + 2, Right(), 254);
// 打印列表元素
Refresh();
}
int List::Work()
{
// 等待用户选择列表元素
// 当前选中的元素序号
int ItemNo = 0;
// 打印元素总数
gotoxy(Left() + 1, Top() + 1);
cprintf(" Total : %-3d ", TotItem);
// 用户输入的键
int Key;
// 先选中第一个元素
Active(0);
// 标记第一个元素已选中
Item[0].Chosen = true;
do
{
// 接受用户输入
Receive(Key);
switch(Key)
{
case KeyUp:
// 是上键
if (ItemNo > 0)
{
// 可以向上选择
// 隐藏当前元素
Inactive(ItemNo);
// 改变选中标记
Item[ItemNo].Chosen = false;
// 改变当前元素
ItemNo--;
// 选中当前元素
Item[ItemNo].Chosen = true;
if (ItemNo < HeadLine)
{
// 需要向上卷屏
// 改变首行序号
HeadLine--;
// 重新打印元素
Refresh();
}
else
{
// 以选中方式打印当前元素
Active(ItemNo);
}
// 滚动垂直滚动条
ScrollVertical(ItemNo);
}
break;
case KeyDown:
// 是下键
if (ItemNo < TotItem)
{
// 可以向下选择
// 隐藏当前元素
Inactive(ItemNo);
// 改变选中标记
Item[ItemNo].Chosen = false;
// 改变当前元素
ItemNo++;
// 选中当前元素
Item[ItemNo].Chosen = true;
if (ItemNo > HeadLine + High() - 1)
{
// 需要向下卷屏
// 改变首行序号
HeadLine++;
// 重新打印元素
Refresh();
}
else
{
// 以选中方式打印当前元素
Active(ItemNo);
}
// 滚动垂直滚动条
ScrollVertical(ItemNo);
}
break;
case KeyPageDown:
// 是向下翻屏键
// 改变选中标志
Item[ItemNo].Chosen = false;
// 改变当前元素序号
ItemNo += High() - 1;
if (ItemNo >= TotItem)
{
// 越界
// 最后一个为当前元素
ItemNo = TotItem;
}
// 选中当前元素
Item[ItemNo].Chosen = true;
// 改变首行序号
HeadLine = ItemNo - High() + 1;
if (HeadLine < 0)
{
// 越界
// 第一个为首行
HeadLine = 0;
}
// 重新打印元素
Refresh();
// 滚动垂直滚动条
ScrollVertical(ItemNo);
break;
case KeyPageUp:
// 是向下翻屏键
// 改变选中标志
Item[ItemNo].Chosen = false;
// 改变当前元素序号
ItemNo -= High() - 1;
if (ItemNo < 0)
{
// 越界
// 第一个为当前元素
ItemNo = 0;
}
// 选中当前元素
Item[ItemNo].Chosen = true;
// 当前元素为首行
HeadLine = ItemNo;
// 重新打印元素
Refresh();
// 滚动垂直滚动条
ScrollVertical(ItemNo);
break;
case KeyHome:
// 到第一个元素
if (ItemNo > 0)
{
// 当前不在第一个元素
// 设置首行序号
HeadLine = 0;
// 改变当前选中标志
Item[ItemNo].Chosen = false;
// 当前选中第一个
ItemNo = 0;
// 选中当前元素
Item[ItemNo].Chosen = true;
// 重新打印元素
Refresh();
// 滚动垂直滚动条
ScrollVertical(ItemNo);
}
break;
case KeyEnd:
// 到最后一个元素
if (ItemNo < TotItem)
{
// 修改首行序号
HeadLine = TotItem - High() + 1;
if (HeadLine < 0)
{
// 不够一屏,修正首行序号
HeadLine = 0;
}
// 修改选中标志
Item[ItemNo].Chosen = false;
// 改变当前元素
ItemNo = TotItem;
// 选中当前元素
Item[ItemNo].Chosen = true;
// 重新打印元素
Refresh();
// 滚动垂直滚动条
ScrollVertical(ItemNo);
}
break;
case KeyEnter:
// 是回车键
// 返回选中的序号
return ItemNo;
case KeyEsc:
// 是ESC键
// 撤销本次操作
return Cancel;
default:
Key = (char)toupper((char)Key);
for (int i = 1; i <= TotItem; i++)
{
if (Item[i].Name[0] == (char)Key)
{
Item[ItemNo].Chosen = false;
Item[i].Chosen = true;
if (HeadLine <= i && i < HeadLine + High())
{
Inactive(ItemNo);
Active(i);
ItemNo = i;
}
else
{
ItemNo = i;
HeadLine = ItemNo;
Refresh();
}
// 滚动垂直滚动条
ScrollVertical(ItemNo);
break;
}
}
}
} while (true);
}
void List::Hide()
{
// 隐藏列表
for (int i = Top(); i <= Bottom() + 1; i++)
{
// 重新打印没一行文本
PrintLine(i + ::x0 - 3);
}
}
void List::Refresh()
{
// 重新打印元素
window(Left() + 1, Top() + 2, Right() - 1, Bottom() - 1);
::SetColor(TextForeground, TextBackground);
clrscr();
window(1, 1, 80, 25);
for (int i = HeadLine; i <= TotItem && i < HeadLine + High(); i++)
{
if (Item[i].Chosen)
{
// 本行已选中
Active(i);
}
else
{
// 本行未选中
Inactive(i);
}
}
}
void List::ScrollVertical(const int Now)
{
// 滚动垂直滚动条
::SetColor(CYAN, LIGHTBLUE);
PrintChar(VerticalPos, Right(), 177);
if (TotItem < 0)
{
// 列表为空
// 置游标于最顶端
VerticalPos = Top() + 2;
}
else
{
// 计算游标的最新位置
VerticalPos = (double)High() / (TotItem + 1) * Now + Top() + 2;
}
// 打印游标
::SetColor(BLUE, CYAN);
PrintChar(VerticalPos, Right(), 254);
}
void List::Active(const int ItemNo)
{
// 激活元素
// 以激活的颜色打印元素
::SetColor(WHITE, GREEN);
gotoxy(Left() + 2, ItemNo - HeadLine + Top() + 2);
cprintf("%12s", Item[ItemNo].Name);
// 打印元素说明信息
::SetColor(BLACK, WHITE);
PrintChar(25, 10, 179);
cprintf(" %s", Item[ItemNo].Message);
clreol();
}
void List::Inactive(const int ItemNo)
{
// 隐藏元素
// 以普通的颜色打印元素
::SetColor(BLACK, TextBackground);
gotoxy(Left() + 2, ItemNo - HeadLine + Top() + 2);
cprintf("%12s", Item[ItemNo].Name);
}
void List::Sort()
{
// 对元素按照名称升序进行排列
// 字符串的交换变量
char strSwap[MaxY];
// 选中标志的交换变量
int intSwap;
for (int i = 1; i < TotItem - 1; i++)
{
for (int j = i + 1; j < TotItem; j++)
{
if (strcmp(Item[i].Name, Item[j].Name) > 0)
{
strcpy(strSwap, Item[i].Name);
strcpy(Item[i].Name, Item[j].Name);
strcpy(Item[j].Name, strSwap);
strcpy(strSwap, Item[i].Message);
strcpy(Item[i].Message, Item[j].Message);
strcpy(Item[j].Message, strSwap);
intSwap = Item[i].Chosen;
Item[i].Chosen = Item[j].Chosen;
Item[j].Chosen = intSwap;
}
}
}
}
void List::Clear()
{
// 清除元素
// 元素序号置空
TotItem = -1;
// 游标位置置顶
VerticalPos = Top() + 2;
// 首行序号清零
HeadLine = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -