Skip to content

Commit

Permalink
Command list now displays line number and vertical lines delimiting i…
Browse files Browse the repository at this point in the history
…f blocks + displaying a lot of commands now works faster because indenting now happens once instead once for each command
  • Loading branch information
EvidentlyCube committed Nov 25, 2020
1 parent 2e228cc commit d3f24b3
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 176 deletions.
258 changes: 138 additions & 120 deletions DROD/CharacterDialogWidget.cpp
Expand Up @@ -26,6 +26,7 @@
* ***** END LICENSE BLOCK ***** */

#include "CharacterDialogWidget.h"
#include "CommandListBoxWidget.h"
#include "DrodBitmapManager.h"
#include "DrodFontManager.h"
#include "EditRoomScreen.h"
Expand Down Expand Up @@ -189,6 +190,9 @@ const UINT LIST_LINE_HEIGHT = 22;
const SURFACECOLOR PaleRed = {255, 192, 192};

std::map<UINT, UINT> CCharacterDialogWidget::speechLengthCache;
const UINT CCharacterDialogWidget::INDENT_PREFIX_SIZE = 6;
const UINT CCharacterDialogWidget::INDENT_TAB_SIZE = 3;
const UINT CCharacterDialogWidget::INDENT_IF_CONDITION_SIZE = 5;

#define NOT_FOUND (UINT(-1))

Expand Down Expand Up @@ -493,8 +497,8 @@ CCharacterDialogWidget::CCharacterDialogWidget(

AddWidget(new CLabelWidget(0L, X_COMMANDSLABEL, Y_COMMANDSLABEL,
CX_COMMANDSLABEL, CY_COMMANDSLABEL, F_Small, g_pTheDB->GetMessageText(MID_Commands)));
this->pCommandsListBox = new CListBoxWidget(TAG_COMMANDSLISTBOX, X_COMMANDS, Y_COMMANDS,
CX_COMMANDS, CY_COMMANDS, false, true, true);
this->pCommandsListBox = new CCommandListBoxWidget(TAG_COMMANDSLISTBOX, X_COMMANDS, Y_COMMANDS,
CX_COMMANDS, CY_COMMANDS);
AddWidget(this->pCommandsListBox);

//Appearance (character/tile graphic).
Expand Down Expand Up @@ -2462,7 +2466,7 @@ void CCharacterDialogWidget::OnKeyDown(
line!=selectedLines.end(); ++line)
{
if (*line < pCommands->size())
wstrCommandsText += toText(*pCommands, (*pCommands)[*line]);
wstrCommandsText += toText(*pCommands, (*pCommands)[*line], *line);
}
if (!wstrCommandsText.empty())
g_pTheSound->PlaySoundEffect(SEID_POTION);
Expand Down Expand Up @@ -3228,8 +3232,6 @@ const
{
WSTRING wstr;

wstr += GetPrettyPrinting(commands, pCommand, 6, 3); //indent the If conditions considerably

//Call language-specific version of method.
switch (Language::GetLanguage())
{
Expand Down Expand Up @@ -4066,158 +4068,169 @@ WSTRING CCharacterDialogWidget::GetDataName(const UINT dwID) const
}

//*****************************************************************************
WSTRING CCharacterDialogWidget::GetPrettyPrinting(
//Add indenting to clarify the code flow.
//
//Params:
const COMMANDPTR_VECTOR& commands,
CCharacterCommand* pCommand,
const UINT ifIndent, const UINT tabSize)
const
UINT CCharacterDialogWidget::ExtractCommandIndent(const UINT wCommandIndex) const
//Extracts command's indent size from the command listbox text
{
ASSERT(pCommand);
WSTRING wstr = this->pCommandsListBox->GetTextAtLine(wCommandIndex);

WSTRING wstr;
UINT i = 0;
for (; i < wstr.size(); ++i)
{
if (!iswspace(wstr.at(i)))
break;
}

//Determine indentation for command.
if (pCommand->command == CCharacterCommand::CC_Label) //labels always have indent 0
return wstr;
return i;
}

UINT wNestDepth = 0, wIndent = 2; //insert past labels
//*****************************************************************************
void CCharacterDialogWidget::PrettyPrintCommands(const COMMANDPTR_VECTOR &commands)
{
WSTRING wstr;

UINT wNestDepth = 0, wIndent = INDENT_PREFIX_SIZE; //insert past labels

bool bIfCondition = false;
UINT index = 0;
bool bLastWasIfCondition = false;
for (COMMANDPTR_VECTOR::const_iterator command = commands.begin();
(*command) != pCommand && command != commands.end(); ++command)
command != commands.end(); ++command, ++index)
{
bIfCondition = false;
switch ((*command)->command)
wstr.clear();
CCharacterCommand *pCommand = *command;
bool bIsIfCondition = false;
bool bUndoOneDepth = false;
switch (pCommand->command)
{
case CCharacterCommand::CC_If:
bIfCondition = true;
bIsIfCondition = true;
++wNestDepth; //indent inside of if block
break;
bUndoOneDepth = true;
break;
case CCharacterCommand::CC_IfElseIf:
bIfCondition = true;
break;
bIsIfCondition = true;
break;
case CCharacterCommand::CC_IfEnd:
if (wNestDepth)
--wNestDepth;
else
wstr += wszExclamation; //superfluous IfEnd
break;
break;
default: break;
}
}

//Unnest If block markers.
switch (pCommand->command)
{
case CCharacterCommand::CC_IfEnd:
case CCharacterCommand::CC_IfElse:
case CCharacterCommand::CC_IfElseIf:
if (wNestDepth)
--wNestDepth;
else
wstr += wszExclamation; //superfluous IfEnd
//no break
case CCharacterCommand::CC_Disappear:
case CCharacterCommand::CC_MoveTo:
case CCharacterCommand::CC_MoveRel:
case CCharacterCommand::CC_EndScript:
case CCharacterCommand::CC_EndScriptOnExit:
case CCharacterCommand::CC_FlushSpeech:
case CCharacterCommand::CC_GoSub:
case CCharacterCommand::CC_GoTo:
case CCharacterCommand::CC_If:
case CCharacterCommand::CC_Imperative:
case CCharacterCommand::CC_Behavior:
case CCharacterCommand::CC_Label:
case CCharacterCommand::CC_LevelEntrance:
case CCharacterCommand::CC_SetMusic:
case CCharacterCommand::CC_Speech:
case CCharacterCommand::CC_TurnIntoMonster:
case CCharacterCommand::CC_PlayerEquipsWeapon:
case CCharacterCommand::CC_SetPlayerStealth:
case CCharacterCommand::CC_SetWaterTraversal:
case CCharacterCommand::CC_StartGlobalScript:
case CCharacterCommand::CC_AnswerOption:
case CCharacterCommand::CC_AmbientSound:
case CCharacterCommand::CC_AmbientSoundAt:
case CCharacterCommand::CC_PlayVideo:
case CCharacterCommand::CC_WorldMapSelect:
case CCharacterCommand::CC_WorldMapMusic:
case CCharacterCommand::CC_WorldMapIcon:
case CCharacterCommand::CC_WorldMapImage:
case CCharacterCommand::CC_ChallengeCompleted:
case CCharacterCommand::CC_Return:
if (bIfCondition)
wstr += wszQuestionMark; //questionable If condition
break;
//Unnest If block markers.
switch (pCommand->command)
{
case CCharacterCommand::CC_IfElse:
case CCharacterCommand::CC_IfElseIf:
if (wNestDepth)
bUndoOneDepth = true;
else
wstr += wszExclamation; //superfluous IfEnd
//no break
case CCharacterCommand::CC_IfEnd:
case CCharacterCommand::CC_Disappear:
case CCharacterCommand::CC_MoveTo:
case CCharacterCommand::CC_MoveRel:
case CCharacterCommand::CC_EndScript:
case CCharacterCommand::CC_EndScriptOnExit:
case CCharacterCommand::CC_FlushSpeech:
case CCharacterCommand::CC_GoSub:
case CCharacterCommand::CC_GoTo:
case CCharacterCommand::CC_If:
case CCharacterCommand::CC_Imperative:
case CCharacterCommand::CC_Behavior:
case CCharacterCommand::CC_Label:
case CCharacterCommand::CC_LevelEntrance:
case CCharacterCommand::CC_SetMusic:
case CCharacterCommand::CC_Speech:
case CCharacterCommand::CC_TurnIntoMonster:
case CCharacterCommand::CC_PlayerEquipsWeapon:
case CCharacterCommand::CC_SetPlayerStealth:
case CCharacterCommand::CC_SetWaterTraversal:
case CCharacterCommand::CC_StartGlobalScript:
case CCharacterCommand::CC_AnswerOption:
case CCharacterCommand::CC_AmbientSound:
case CCharacterCommand::CC_AmbientSoundAt:
case CCharacterCommand::CC_PlayVideo:
case CCharacterCommand::CC_WorldMapSelect:
case CCharacterCommand::CC_WorldMapMusic:
case CCharacterCommand::CC_WorldMapIcon:
case CCharacterCommand::CC_WorldMapImage:
case CCharacterCommand::CC_ChallengeCompleted:
case CCharacterCommand::CC_Return:
if (bLastWasIfCondition)
wstr += wszQuestionMark; //questionable If condition
break;

case CCharacterCommand::CC_ImageOverlay:
if (bIfCondition)
wstr += wszQuestionMark; //questionable If condition
if (pCommand->label.empty()) {
wstr += wszExclamation;
} else {
vector<ImageOverlayCommand> temp;
if (!CImageOverlay::parse(pCommand->label, temp))
case CCharacterCommand::CC_ImageOverlay:
if (bLastWasIfCondition)
wstr += wszQuestionMark; //questionable If condition
if (pCommand->label.empty()) {
wstr += wszExclamation;
}
break;
}
else {
vector<ImageOverlayCommand> temp;
if (!CImageOverlay::parse(pCommand->label, temp))
wstr += wszExclamation;
}
break;

case CCharacterCommand::CC_VarSet:
if (bIfCondition)
wstr += wszQuestionMark; //questionable If condition
//no break
case CCharacterCommand::CC_WaitForVar:
{
//Verify integrity of hold var refs.
switch (pCommand->y)
case CCharacterCommand::CC_VarSet:
if (bLastWasIfCondition)
wstr += wszQuestionMark; //questionable If condition
//no break
case CCharacterCommand::CC_WaitForVar:
{
//Verify integrity of hold var refs.
switch (pCommand->y)
{
case ScriptVars::AppendText:
case ScriptVars::AssignText:
break;
break;
default:
if (!pCommand->label.empty()) //an expression is used as an operand
{
CEditRoomScreen *pEditRoomScreen = DYN_CAST(CEditRoomScreen*, CScreen*,
g_pTheSM->GetScreen(SCR_EditRoom));
CEditRoomScreen *pEditRoomScreen = DYN_CAST(CEditRoomScreen *, CScreen *,
g_pTheSM->GetScreen(SCR_EditRoom));
ASSERT(pEditRoomScreen);
ASSERT(pEditRoomScreen->pHold);
UINT index=0;
UINT index = 0;
if (!CCharacter::IsValidExpression(pCommand->label.c_str(), index, pEditRoomScreen->pHold))
wstr += wszAsterisk; //expression is not valid
}
break;
break;
}
}
break;

//Deprecated commands.
case CCharacterCommand::CC_GotoIf:
case CCharacterCommand::CC_WaitForHalph:
case CCharacterCommand::CC_WaitForNotHalph:
case CCharacterCommand::CC_WaitForMonster:
case CCharacterCommand::CC_WaitForNotMonster:
case CCharacterCommand::CC_WaitForCharacter:
case CCharacterCommand::CC_WaitForNotCharacter:
wstr += wszAsterisk;
break;
default: break;
}
break;

//Deprecated commands.
case CCharacterCommand::CC_GotoIf:
case CCharacterCommand::CC_WaitForHalph:
case CCharacterCommand::CC_WaitForNotHalph:
case CCharacterCommand::CC_WaitForMonster:
case CCharacterCommand::CC_WaitForNotMonster:
case CCharacterCommand::CC_WaitForCharacter:
case CCharacterCommand::CC_WaitForNotCharacter:
wstr += wszAsterisk;
break;
default: break;
}
UINT wFinalIndent = wNestDepth * INDENT_TAB_SIZE;
if (bLastWasIfCondition)
wFinalIndent += INDENT_IF_CONDITION_SIZE;

if (bIfCondition)
{
wIndent += ifIndent;
if (bIfCondition)
if (wNestDepth) //...but don't include If indentation in the code block
--wNestDepth;
}
else if (bUndoOneDepth)
wFinalIndent -= INDENT_TAB_SIZE;

wstr.insert(wstr.end(), wIndent + wNestDepth*tabSize, W_t(' '));
wstr.insert(wstr.begin(), wIndent, W_t(' '));
wstr.insert(wstr.end(), wFinalIndent, W_t(' '));
wstr += this->pCommandsListBox->GetTextAtLine(index);
this->pCommandsListBox->SetItemTextAtLine(index, wstr.c_str());

return wstr;
bLastWasIfCondition = bIsIfCondition;
}
}

//*****************************************************************************
Expand Down Expand Up @@ -4731,6 +4744,9 @@ void CCharacterDialogWidget::PopulateCommandDescriptions(
GetCommandDesc(commands, pCommand).c_str());
SetCommandColor(pCommandList, insertedIndex, pCommand->command);
}

PrettyPrintCommands(commands);

if (commands.size())
pCommandList->SelectLine(0);
}
Expand Down Expand Up @@ -7747,7 +7763,8 @@ WSTRING CCharacterDialogWidget::toText(
//
//Params:
const COMMANDPTR_VECTOR& commands,
CCharacterCommand* pCommand) //Command to parse
CCharacterCommand* pCommand, //Command to parse
const UINT wCommandIndex) //Index of the command
{
#define concatNum(n) wstr += _itoW(n,temp,10)
#define concatNumWithComma(n) concatNum(n); wstr += wszComma;
Expand All @@ -7761,7 +7778,8 @@ WSTRING CCharacterDialogWidget::toText(
if (wstrCommandName.empty())
return wstr;

wstr += GetPrettyPrinting(commands, pCommand, 6, 3);
UINT indent = ExtractCommandIndent(wCommandIndex);
wstr.insert(wstr.end(), indent - INDENT_PREFIX_SIZE + 2, W_t(' '));
wstr += wstrCommandName;
wstr += wszSpace;

Expand Down
11 changes: 7 additions & 4 deletions DROD/CharacterDialogWidget.h
Expand Up @@ -79,6 +79,10 @@ friend class CRenameDialogWidget;
bool RenameCharacter();
bool RenameVar();

static const UINT INDENT_PREFIX_SIZE;
static const UINT INDENT_TAB_SIZE;
static const UINT INDENT_IF_CONDITION_SIZE;

private:
void AddCharacterDialog();
void AddCommandDialog();
Expand Down Expand Up @@ -108,9 +112,8 @@ friend class CRenameDialogWidget;
const WCHAR* pText) const;
HoldCharacter* GetCustomCharacter();
WSTRING GetDataName(const UINT dwID) const;
WSTRING GetPrettyPrinting(const COMMANDPTR_VECTOR& commands,
CCharacterCommand* pCommand,
const UINT ifIndent, const UINT tabSize) const;
UINT ExtractCommandIndent(const UINT wCommandIndex) const;
void PrettyPrintCommands(const COMMANDPTR_VECTOR &commands);
WSTRING GetEntranceName(CEditRoomScreen *pEditRoomScreen, UINT entranceID) const;
void AppendGotoDestination(WSTRING& wstr, const COMMANDPTR_VECTOR& commands,
const CCharacterCommand& pCommand) const;
Expand Down Expand Up @@ -168,7 +171,7 @@ friend class CRenameDialogWidget;

//For text editing of script commands.
CCharacterCommand* fromText(WSTRING text);
WSTRING toText(const COMMANDPTR_VECTOR& commands, CCharacterCommand* pCommand);
WSTRING toText(const COMMANDPTR_VECTOR& commands, CCharacterCommand* pCommand, const UINT wCommandIndex);

CListBoxWidget *pGraphicListBox, *pPlayerGraphicListBox, *pAddCommandGraphicListBox;
COptionButtonWidget *pIsVisibleButton;
Expand Down

0 comments on commit d3f24b3

Please sign in to comment.