guihandler.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 2,423 行 · 第 1/5 页
CPP
2,423 行
return;
}
}
}
void CGuiHandler::LayoutIcons(bool useSelectionPage)
{
const bool defCmd =
(mouse->buttons[SDL_BUTTON_RIGHT].pressed &&
(defaultCmdMemory >= 0) && (inCommand < 0) &&
((activeReceiver == this) || (minimap->ProxyMode())));
const int activeCmd = defCmd ? defaultCmdMemory : inCommand;
// copy the current command state
const bool validInCommand = (activeCmd >= 0) && (activeCmd < commands.size());
CommandDescription cmdDesc;
if (validInCommand) {
cmdDesc = commands[activeCmd];
}
const bool samePage = validInCommand && (activePage == FindInCommandPage());
useSelectionPage = useSelectionPage && !samePage;
// reset some of our state
inCommand = -1;
defaultCmdMemory = -1;
commands.clear();
forceLayoutUpdate = false;
// try using the custom layout handler
if (firstLayout) {
firstLayout = false;
if (!!configHandler.GetInt("LuaUI", 0)) {
CLuaUI::LoadHandler();
}
}
if ((luaUI != NULL) && luaUI->HasLayoutButtons()) {
if (LayoutCustomIcons(useSelectionPage)) {
if (validInCommand) {
RevertToCmdDesc(cmdDesc, defCmd, samePage);
}
return; // we're done here
}
else {
CLuaUI::FreeHandler();
LoadConfig("ctrlpanel.txt");
}
}
// get the commands to process
CSelectedUnits::AvailableCommandsStruct ac;
ac = selectedUnits.GetAvailableCommands();
ConvertCommands(ac.commands);
vector<CommandDescription> hidden;
vector<CommandDescription>::const_iterator cdi;
// separate the visible/hidden icons
for (cdi = ac.commands.begin(); cdi != ac.commands.end(); ++cdi){
if (cdi->onlyKey) {
hidden.push_back(*cdi);
} else {
commands.push_back(*cdi);
}
}
// assign extra icons for internal commands
int extraIcons = 0;
if (deadIconSlot >= 0) { extraIcons++; }
if (prevPageSlot >= 0) { extraIcons++; }
if (nextPageSlot >= 0) { extraIcons++; }
const int cmdCount = (int)commands.size();
const int cmdIconsPerPage = (iconsPerPage - extraIcons);
const int pageCount = ((cmdCount + (cmdIconsPerPage - 1)) / cmdIconsPerPage);
const bool multiPage = (pageCount > 1);
const int prevPageCmd = cmdCount + 0;
const int nextPageCmd = cmdCount + 1;
maxPage = max(0, pageCount - 1);
iconsCount = pageCount * iconsPerPage;
// resize the icon array if required
ResizeIconArray(iconsCount);
int ci = 0; // command index
for (int ii = 0; ii < iconsCount; ii++) {
// map the icon order
const int tmpSlot = (ii % iconsPerPage);
const int mii = ii - tmpSlot + fillOrder[tmpSlot]; // mapped icon index
IconInfo& icon = icons[mii];
const int slot = (mii % iconsPerPage);
if (slot == deadIconSlot) {
icon.commandsID = -1;
}
else if (slot == nextPageSlot) {
icon.commandsID = multiPage ? nextPageCmd : -1;
}
else if (slot == prevPageSlot) {
icon.commandsID = multiPage ? prevPageCmd : -1;
}
else if (ci >= cmdCount) {
icon.commandsID = -1;
}
else {
icon.commandsID = ci;
ci++;
}
// setup the geometry
if (icon.commandsID >= 0) {
const float fx = (float)(slot % xIcons);
const float fy = (float)(slot / xIcons);
const float fullBorder = frameBorder + iconBorder;
icon.visual.x1 = buttonBox.x1 + (fullBorder + (fx * xIconStep));
icon.visual.x2 = icon.visual.x1 + xIconSize;
icon.visual.y1 = buttonBox.y2 - (fullBorder + (fy * yIconStep));
icon.visual.y2 = icon.visual.y1 - yIconSize;
const float noGap = selectGaps ? 0.0f : (iconBorder + 0.0005f);
icon.selection.x1 = icon.visual.x1 - noGap;
icon.selection.x2 = icon.visual.x2 + noGap;
icon.selection.y1 = icon.visual.y1 + noGap;
icon.selection.y2 = icon.visual.y2 - noGap;
}
else {
// make sure this icon does not get selected
icon.selection.x1 = icon.selection.x2 = -1.0f;
icon.selection.y1 = icon.selection.y2 = -1.0f;
}
}
// append the Prev and Next commands (if required)
if (multiPage) {
AppendPrevAndNext(commands);
}
// append the hidden commands
for (cdi = hidden.begin(); cdi != hidden.end(); ++cdi) {
commands.push_back(*cdi);
}
// try to setup the old command state
// (inCommand, activePage, showingMetal)
if (validInCommand) {
RevertToCmdDesc(cmdDesc, defCmd, samePage);
} else if (useSelectionPage) {
activePage = min(maxPage, ac.commandPage);
}
activePage = min(maxPage, activePage);
}
bool CGuiHandler::LayoutCustomIcons(bool useSelectionPage)
{
if (luaUI == NULL) {
return false;
}
// get the commands to process
CSelectedUnits::AvailableCommandsStruct ac;
ac = selectedUnits.GetAvailableCommands();
vector<CommandDescription> cmds = ac.commands;
if (cmds.size() > 0) {
ConvertCommands(cmds);
AppendPrevAndNext(cmds);
}
// call for a custom layout
int tmpXicons = xIcons;
int tmpYicons = yIcons;
vector<int> removeCmds;
vector<CommandDescription> customCmds;
vector<int> onlyTextureCmds;
vector<CLuaUI::ReStringPair> reTextureCmds;
vector<CLuaUI::ReStringPair> reNamedCmds;
vector<CLuaUI::ReStringPair> reTooltipCmds;
vector<CLuaUI::ReParamsPair> reParamsCmds;
map<int, int> iconMap;
if (!luaUI->LayoutButtons(tmpXicons, tmpYicons, cmds,
removeCmds, customCmds,
onlyTextureCmds, reTextureCmds,
reNamedCmds, reTooltipCmds, reParamsCmds,
iconMap, menuName)) {
return false;
}
if ((tmpXicons < 2) || (tmpYicons < 2)) {
logOutput.Print("LayoutCustomIcons() bad xIcons or yIcons (%i, %i)\n",
tmpXicons, tmpYicons);
return false;
}
unsigned int i;
const int tmpIconsPerPage = (tmpXicons * tmpYicons);
// build a set to better find unwanted commands
set<int> removeIDs;
for (i = 0; i < removeCmds.size(); i++) {
const int index = removeCmds[i];
if ((index >= 0) || (index < cmds.size())) {
removeIDs.insert(index);
} else {
logOutput.Print("LayoutCustomIcons() skipping bad removeCmd (%i)\n",
index);
}
}
// remove unwanted commands (and mark all as onlyKey)
vector<CommandDescription> tmpCmds;
for (i = 0; i < cmds.size(); i++) {
if (removeIDs.find(i) == removeIDs.end()) {
cmds[i].onlyKey = true;
tmpCmds.push_back(cmds[i]);
}
}
cmds = tmpCmds;
// add the custom commands
for (i = 0; i < customCmds.size(); i++) {
customCmds[i].onlyKey = true;
cmds.push_back(customCmds[i]);
}
const int cmdCount = (int)cmds.size();
// set commands to onlyTexture
for (i = 0; i < onlyTextureCmds.size(); i++) {
const int index = onlyTextureCmds[i];
if ((index >= 0) && (index < cmdCount)) {
cmds[index].onlyTexture = true;
} else {
logOutput.Print("LayoutCustomIcons() skipping bad onlyTexture (%i)\n",
index);
}
}
// retexture commands
for (i = 0; i < reTextureCmds.size(); i++) {
const int index = reTextureCmds[i].cmdIndex;
if ((index >= 0) && (index < cmdCount)) {
cmds[index].iconname = reTextureCmds[i].texture;
} else {
logOutput.Print("LayoutCustomIcons() skipping bad reTexture (%i)\n",
index);
}
}
// reNamed commands
for (i = 0; i < reNamedCmds.size(); i++) {
const int index = reNamedCmds[i].cmdIndex;
if ((index >= 0) && (index < cmdCount)) {
cmds[index].name = reNamedCmds[i].texture;
} else {
logOutput.Print("LayoutCustomIcons() skipping bad reNamed (%i)\n",
index);
}
}
// reTooltip commands
for (i = 0; i < reTooltipCmds.size(); i++) {
const int index = reTooltipCmds[i].cmdIndex;
if ((index >= 0) && (index < cmdCount)) {
cmds[index].tooltip = reTooltipCmds[i].texture;
} else {
logOutput.Print("LayoutCustomIcons() skipping bad reNamed (%i)\n",
index);
}
}
// reParams commands
for (i = 0; i < reParamsCmds.size(); i++) {
const int index = reParamsCmds[i].cmdIndex;
if ((index >= 0) && (index < cmdCount)) {
const map<int, string>& params = reParamsCmds[i].params;
map<int, string>::const_iterator pit;
for (pit = params.begin(); pit != params.end(); ++pit) {
const int p = pit->first;
if ((p >= 0) && (p < (int)cmds[index].params.size())) {
cmds[index].params[p] = pit->second;
}
}
} else {
logOutput.Print("LayoutCustomIcons() skipping bad reParams (%i)\n",
index);
}
}
// build the iconList from the map
vector<int> iconList;
int nextPos = 0;
map<int, int>::iterator mit;
for (mit = iconMap.begin(); mit != iconMap.end(); ++mit) {
const int iconPos = mit->first;
if (iconPos < nextPos) {
continue;
}
else if (iconPos > nextPos) {
// fill in the blanks
for (int p = nextPos; p < iconPos; p++) {
iconList.push_back(-1);
}
}
iconList.push_back(mit->second); // cmdIndex
nextPos = iconPos + 1;
}
const int iconListCount = (int)iconList.size();
const int pageCount = ((iconListCount + (tmpIconsPerPage - 1)) / tmpIconsPerPage);
const int tmpIconsCount = (pageCount * tmpIconsPerPage);
// resize the icon array if required
ResizeIconArray(tmpIconsCount);
// build the iconList
for (int ii = 0; ii < tmpIconsCount; ii++) {
IconInfo& icon = icons[ii];
const int index = (ii < (int)iconList.size()) ? iconList[ii] : -1;
if ((index >= 0) && (index < cmdCount)) {
icon.commandsID = index;
cmds[index].onlyKey = false;
const int slot = (ii % tmpIconsPerPage);
const float fx = (float)(slot % tmpXicons);
const float fy = (float)(slot / tmpXicons);
const float fullBorder = frameBorder + iconBorder;
icon.visual.x1 = buttonBox.x1 + (fullBorder + (fx * xIconStep));
icon.visual.x2 = icon.visual.x1 + xIconSize;
icon.visual.y1 = buttonBox.y2 - (fullBorder + (fy * yIconStep));
icon.visual.y2 = icon.visual.y1 - yIconSize;
const float noGap = selectGaps ? 0.0f : (iconBorder + 0.0005f);
icon.selection.x1 = icon.visual.x1 - noGap;
icon.selection.x2 = icon.visual.x2 + noGap;
icon.selection.y1 = icon.visual.y1 + noGap;
icon.selection.y2 = icon.visual.y2 - noGap;
}
else {
// make sure this icon does not get selected
icon.commandsID = -1;
icon.selection.x1 = icon.selection.x2 = -1.0f;
icon.selection.y1 = icon.selection.y2 = -1.0f;
}
}
commands = cmds;
xIcons = tmpXicons;
yIcons = tmpYicons;
iconsCount = tmpIconsCount;
iconsPerPage = tmpIconsPerPage;
maxPage = max(0, pageCount - 1);
if (useSelectionPage) {
activePage = min(maxPage, ac.commandPage);
} else {
activePage = min(maxPage, activePage);
}
buttonBox.x1 = xPos;
buttonBox.x2 = xPos + (frameBorder * 2.0f) + (xIcons * xIconStep);
buttonBox.y1 = yPos;
buttonBox.y2 = yPos + (frameBorder * 2.0f) + (yIcons * yIconStep);
return true;
}
void CGuiHandler::GiveCommand(const Command& cmd, bool fromUser) const
{
if (luaUI != NULL) {
if (luaUI->CommandNotify(cmd)) {
return;
}
}
selectedUnits.GiveCommand(cmd, fromUser);
if (gatherMode) {
if ((cmd.id == CMD_MOVE) || (cmd.id == CMD_FIGHT)) {
Command gatherCmd;
gatherCmd.id = CMD_GATHERWAIT;
GiveCommand(gatherCmd, false);
}
}
}
void CGuiHandler::ConvertCommands(vector<CommandDescription>& cmds)
{
if (newAttackMode) {
const int count = (int)cmds.size();
for (int i = 0; i < count; i++) {
CommandDescription& cd = cmds[i];
if ((cd.id == CMD_ATTACK) && (cd.type == CMDTYPE_ICON_UNIT_OR_MAP)) {
if (attackRect) {
cd.type = CMDTYPE_ICON_UNIT_OR_RECTANGLE;
} else {
cd.type = CMDTYPE_ICON_UNIT_OR_AREA;
}
}
}
}
}
void CGuiHandler::SetShowingMetal(bool show)
{
CBaseGroundDrawer* gd = readmap->GetGroundDrawer();
if (!show) {
if (showingMetal) {
gd->DisableExtraTexture();
showingMetal = false;
}
}
else {
if (autoShowMetal) {
if (gd->drawMode != CBaseGroundDrawer::drawMetal) {
CMetalMap* mm = readmap->metalMap;
gd->SetMetalTexture(mm->metalMap, &mm->extractionMap.front(), mm->metalPal, false);
showingMetal = true;
}
}
}
}
void CGuiHandler::Update()
{
SetCursorIcon();
// Notify LuaUI about groups that have changed
if (!changedGroups.empty()) {
if (luaUI != NULL) {
set<int>::const_iterator it;
for (it = changedGroups.begin(); it != changedGroups.end(); ++it) {
luaUI->GroupChanged(*it);
}
}
changedGroups.clear();
}
if (!invertQueueKey && (needShift && !keys[SDLK_LSHIFT])) {
SetShowingMetal(false);
inCommand=-1;
needShift=false;
}
const bool commandsChanged = selectedUnits.CommandsChanged();
if (commandsChanged) {
SetShowingMetal(false);
LayoutIcons(true);
fadein = 100;
}
else if (forceLayoutUpdate) {
LayoutIcons(false);
}
if (fadein > 0) {
fadein -= 5;
}
}
/******************************************************************************/
/******************************************************************************/
void CGuiHandler::SetCursorIcon() const
{
mouse->cursorText = "";
mouse->cursorScale = 1.0f;
CInputReceiver* ir = NULL;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?