Merge pull request #8618 from ChillerDragon/pr_editor_prompt

Add ctrl+p editor prompt (quick actions)
This commit is contained in:
Dennis Felsing 2024-08-31 21:42:48 +00:00 committed by GitHub
commit 36f0bcc509
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 406 additions and 29 deletions

View file

@ -2500,8 +2500,13 @@ if(CLIENT)
mapitems/sound.cpp mapitems/sound.cpp
mapitems/sound.h mapitems/sound.h
popups.cpp popups.cpp
prompt.cpp
prompt.h
proof_mode.cpp proof_mode.cpp
proof_mode.h proof_mode.h
quick_action.h
quick_actions.cpp
quick_actions.h
smooth_value.cpp smooth_value.cpp
smooth_value.h smooth_value.h
tileart.cpp tileart.cpp

View file

@ -1074,11 +1074,9 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
// proof button // proof button
TB_Top.VSplitLeft(40.0f, &Button, &TB_Top); TB_Top.VSplitLeft(40.0f, &Button, &TB_Top);
static int s_ProofButton = 0; if(DoButton_Ex(&m_QuickActionProof, m_QuickActionProof.Label(), m_QuickActionProof.Active(), &Button, 0, m_QuickActionProof.Description(), IGraphics::CORNER_L))
if(DoButton_Ex(&s_ProofButton, "Proof", MapView()->ProofMode()->IsEnabled(), &Button, 0, "[ctrl+p] Toggles proof borders. These borders represent the area that a player can see with default zoom.", IGraphics::CORNER_L) ||
(m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_P) && ModPressed))
{ {
MapView()->ProofMode()->Toggle(); m_QuickActionProof.Call();
} }
TB_Top.VSplitLeft(14.0f, &Button, &TB_Top); TB_Top.VSplitLeft(14.0f, &Button, &TB_Top);
@ -1254,10 +1252,9 @@ void CEditor::DoToolbarLayers(CUIRect ToolBar)
// refocus button // refocus button
{ {
TB_Bottom.VSplitLeft(50.0f, &Button, &TB_Bottom); TB_Bottom.VSplitLeft(50.0f, &Button, &TB_Bottom);
static int s_RefocusButton = 0;
int FocusButtonChecked = MapView()->IsFocused() ? -1 : 1; int FocusButtonChecked = MapView()->IsFocused() ? -1 : 1;
if(DoButton_Editor(&s_RefocusButton, "Refocus", FocusButtonChecked, &Button, 0, "[HOME] Restore map focus") || (m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_HOME))) if(DoButton_Editor(&m_QuickActionRefocus, m_QuickActionRefocus.Label(), FocusButtonChecked, &Button, 0, m_QuickActionRefocus.Description()) || (m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->KeyPress(KEY_HOME)))
MapView()->Focus(); m_QuickActionRefocus.Call();
TB_Bottom.VSplitLeft(5.0f, nullptr, &TB_Bottom); TB_Bottom.VSplitLeft(5.0f, nullptr, &TB_Bottom);
} }
@ -4302,12 +4299,9 @@ void CEditor::RenderLayers(CUIRect LayersBox)
if(s_ScrollRegion.AddRect(AddGroupButton)) if(s_ScrollRegion.AddRect(AddGroupButton))
{ {
AddGroupButton.HSplitTop(RowHeight, &AddGroupButton, 0); AddGroupButton.HSplitTop(RowHeight, &AddGroupButton, 0);
static int s_AddGroupButton = 0; if(DoButton_Editor(&m_QuickActionAddGroup, m_QuickActionAddGroup.Label(), 0, &AddGroupButton, IGraphics::CORNER_R, m_QuickActionAddGroup.Description()))
if(DoButton_Editor(&s_AddGroupButton, "Add group", 0, &AddGroupButton, IGraphics::CORNER_R, "Adds a new group"))
{ {
m_Map.NewGroup(); m_QuickActionAddGroup.Call();
m_SelectedGroup = m_Map.m_vpGroups.size() - 1;
m_EditorHistory.RecordAction(std::make_shared<CEditorActionGroup>(this, m_SelectedGroup, false));
} }
} }
@ -4806,8 +4800,8 @@ void CEditor::RenderImagesList(CUIRect ToolBox)
{ {
AddImageButton.HSplitTop(5.0f, nullptr, &AddImageButton); AddImageButton.HSplitTop(5.0f, nullptr, &AddImageButton);
AddImageButton.HSplitTop(RowHeight, &AddImageButton, nullptr); AddImageButton.HSplitTop(RowHeight, &AddImageButton, nullptr);
if(DoButton_Editor(&s_AddImageButton, "Add", 0, &AddImageButton, 0, "Load a new image to use in the map")) if(DoButton_Editor(&s_AddImageButton, m_QuickActionAddImage.Label(), 0, &AddImageButton, 0, m_QuickActionAddImage.Description()))
InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", false, AddImage, this); m_QuickActionAddImage.Call();
} }
s_ScrollRegion.End(); s_ScrollRegion.End();
} }
@ -5750,9 +5744,9 @@ void CEditor::RenderStatusbar(CUIRect View, CUIRect *pTooltipRect)
CUIRect Button; CUIRect Button;
View.VSplitRight(100.0f, &View, &Button); View.VSplitRight(100.0f, &View, &Button);
static int s_EnvelopeButton = 0; static int s_EnvelopeButton = 0;
if(DoButton_Editor(&s_EnvelopeButton, "Envelopes", ButtonsDisabled ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES, &Button, 0, "Toggles the envelope editor.") == 1) if(DoButton_Editor(&s_EnvelopeButton, m_QuickActionEnvelopes.Label(), m_QuickActionEnvelopes.Color(), &Button, 0, m_QuickActionEnvelopes.Description()) == 1)
{ {
m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES ? EXTRAEDITOR_NONE : EXTRAEDITOR_ENVELOPES; m_QuickActionEnvelopes.Call();
} }
View.VSplitRight(10.0f, &View, nullptr); View.VSplitRight(10.0f, &View, nullptr);
@ -7919,7 +7913,7 @@ void CEditor::Render()
InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CallbackSaveCopyMap, this); InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CallbackSaveCopyMap, this);
// ctrl+shift+s to save as // ctrl+shift+s to save as
else if(Input()->KeyPress(KEY_S) && ModPressed && ShiftPressed) else if(Input()->KeyPress(KEY_S) && ModPressed && ShiftPressed)
InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CallbackSaveMap, this); m_QuickActionSaveAs.Call();
// ctrl+s to save // ctrl+s to save
else if(Input()->KeyPress(KEY_S) && ModPressed) else if(Input()->KeyPress(KEY_S) && ModPressed)
{ {
@ -8362,6 +8356,7 @@ void CEditor::Init()
m_vComponents.emplace_back(m_MapView); m_vComponents.emplace_back(m_MapView);
m_vComponents.emplace_back(m_MapSettingsBackend); m_vComponents.emplace_back(m_MapSettingsBackend);
m_vComponents.emplace_back(m_LayerSelector); m_vComponents.emplace_back(m_LayerSelector);
m_vComponents.emplace_back(m_Prompt);
for(CEditorComponent &Component : m_vComponents) for(CEditorComponent &Component : m_vComponents)
Component.OnInit(this); Component.OnInit(this);

View file

@ -38,6 +38,8 @@
#include "layer_selector.h" #include "layer_selector.h"
#include "map_view.h" #include "map_view.h"
#include "smooth_value.h" #include "smooth_value.h"
#include <game/editor/prompt.h>
#include <game/editor/quick_action.h>
#include <deque> #include <deque>
#include <functional> #include <functional>
@ -60,7 +62,8 @@ enum
DIALOG_NONE = 0, DIALOG_NONE = 0,
DIALOG_FILE, DIALOG_FILE,
DIALOG_MAPSETTINGS_ERROR DIALOG_MAPSETTINGS_ERROR,
DIALOG_QUICK_PROMPT,
}; };
class CEditorImage; class CEditorImage;
@ -278,6 +281,7 @@ class CEditor : public IEditor
std::vector<std::reference_wrapper<CEditorComponent>> m_vComponents; std::vector<std::reference_wrapper<CEditorComponent>> m_vComponents;
CMapView m_MapView; CMapView m_MapView;
CLayerSelector m_LayerSelector; CLayerSelector m_LayerSelector;
CPrompt m_Prompt;
bool m_EditorWasUsedBefore = false; bool m_EditorWasUsedBefore = false;
@ -319,7 +323,18 @@ public:
const CMapView *MapView() const { return &m_MapView; } const CMapView *MapView() const { return &m_MapView; }
CLayerSelector *LayerSelector() { return &m_LayerSelector; } CLayerSelector *LayerSelector() { return &m_LayerSelector; }
void AddGroup();
void AddTileLayer();
void LayerSelectImage();
bool IsNonGameTileLayerSelected() const;
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) CQuickAction m_QuickAction##name;
#include <game/editor/quick_actions.h>
#undef REGISTER_QUICK_ACTION
CEditor() : CEditor() :
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) m_QuickAction##name(text, description, callback, disabled, active, button_color),
#include <game/editor/quick_actions.h>
#undef REGISTER_QUICK_ACTION
m_ZoomEnvelopeX(1.0f, 0.1f, 600.0f), m_ZoomEnvelopeX(1.0f, 0.1f, 600.0f),
m_ZoomEnvelopeY(640.0f, 0.1f, 32000.0f), m_ZoomEnvelopeY(640.0f, 0.1f, 32000.0f),
m_MapSettingsCommandContext(m_MapSettingsBackend.NewContext(&m_SettingsCommandInput)) m_MapSettingsCommandContext(m_MapSettingsBackend.NewContext(&m_SettingsCommandInput))

View file

@ -107,9 +107,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupMenuFile(void *pContext, CUIRect Vie
View.HSplitTop(2.0f, nullptr, &View); View.HSplitTop(2.0f, nullptr, &View);
View.HSplitTop(12.0f, &Slot, &View); View.HSplitTop(12.0f, &Slot, &View);
if(pEditor->DoButton_MenuItem(&s_SaveAsButton, "Save As", 0, &Slot, 0, "Saves the current map under a new name (ctrl+shift+s)")) if(pEditor->DoButton_MenuItem(&s_SaveAsButton, pEditor->m_QuickActionSaveAs.Label(), 0, &Slot, 0, pEditor->m_QuickActionSaveAs.Description()))
{ {
pEditor->InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save", "maps", true, CEditor::CallbackSaveMap, pEditor); pEditor->m_QuickActionSaveAs.Call();
return CUi::POPUP_CLOSE_CURRENT; return CUi::POPUP_CLOSE_CURRENT;
} }
@ -578,16 +578,9 @@ CUi::EPopupMenuFunctionResult CEditor::PopupGroup(void *pContext, CUIRect View,
// new tile layer // new tile layer
View.HSplitBottom(5.0f, &View, nullptr); View.HSplitBottom(5.0f, &View, nullptr);
View.HSplitBottom(12.0f, &View, &Button); View.HSplitBottom(12.0f, &View, &Button);
static int s_NewTileLayerButton = 0; if(pEditor->DoButton_Editor(&pEditor->m_QuickActionAddTileLayer, pEditor->m_QuickActionAddTileLayer.Label(), 0, &Button, 0, pEditor->m_QuickActionAddTileLayer.Description()))
if(pEditor->DoButton_Editor(&s_NewTileLayerButton, "Add tile layer", 0, &Button, 0, "Creates a new tile layer"))
{ {
std::shared_ptr<CLayer> pTileLayer = std::make_shared<CLayerTiles>(pEditor, pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height); pEditor->m_QuickActionAddTileLayer.Call();
pTileLayer->m_pEditor = pEditor;
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->AddLayer(pTileLayer);
int LayerIndex = pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_vpLayers.size() - 1;
pEditor->SelectLayer(LayerIndex);
pEditor->m_Map.m_vpGroups[pEditor->m_SelectedGroup]->m_Collapse = false;
pEditor->m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(pEditor, pEditor->m_SelectedGroup, LayerIndex));
return CUi::POPUP_CLOSE_CURRENT; return CUi::POPUP_CLOSE_CURRENT;
} }

169
src/game/editor/prompt.cpp Normal file
View file

@ -0,0 +1,169 @@
#include <engine/keys.h>
#include <game/client/ui_listbox.h>
#include <game/editor/quick_action.h>
#include "editor.h"
#include "prompt.h"
bool FuzzyMatch(const char *pHaystack, const char *pNeedle)
{
if(!pNeedle || !pNeedle[0])
return false;
char aBuf[2] = {0};
const char *pHit = pHaystack;
int NeedleLen = str_length(pNeedle);
for(int i = 0; i < NeedleLen; i++)
{
if(!pHit)
return false;
aBuf[0] = pNeedle[i];
pHit = str_find_nocase(pHit, aBuf);
if(pHit)
pHit++;
}
return pHit;
}
bool CPrompt::IsActive()
{
return CEditorComponent::IsActive() || Editor()->m_Dialog == DIALOG_QUICK_PROMPT;
}
void CPrompt::SetActive()
{
Editor()->m_Dialog = DIALOG_QUICK_PROMPT;
CEditorComponent::SetActive();
Ui()->SetActiveItem(&m_PromptInput);
}
void CPrompt::SetInactive()
{
m_ResetFilterResults = true;
m_PromptInput.Clear();
if(Editor()->m_Dialog == DIALOG_QUICK_PROMPT)
Editor()->m_Dialog = DIALOG_NONE;
CEditorComponent::SetInactive();
}
bool CPrompt::OnInput(const IInput::CEvent &Event)
{
if(Input()->ModifierIsPressed() && Input()->KeyIsPressed(KEY_P))
{
SetActive();
}
return false;
}
void CPrompt::OnInit(CEditor *pEditor)
{
CEditorComponent::OnInit(pEditor);
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description) m_vQuickActions.emplace_back(&Editor()->m_QuickAction##name);
#include <game/editor/quick_actions.h>
#undef REGISTER_QUICK_ACTION
}
void CPrompt::OnRender(CUIRect _)
{
if(!IsActive())
return;
if(Ui()->ConsumeHotkey(CUi::HOTKEY_ESCAPE))
{
SetInactive();
return;
}
static CListBox s_ListBox;
CUIRect Prompt, PromptBox;
CUIRect Suggestions;
Ui()->MapScreen();
CUIRect Overlay = *Ui()->Screen();
Overlay.Draw(ColorRGBA(0, 0, 0, 0.33f), IGraphics::CORNER_NONE, 0.0f);
CUIRect Background;
Overlay.VMargin(150.0f, &Background);
Background.HMargin(50.0f, &Background);
Background.Draw(ColorRGBA(0, 0, 0, 0.80f), IGraphics::CORNER_ALL, 5.0f);
Background.Margin(10.0f, &Prompt);
Prompt.VSplitMid(nullptr, &PromptBox);
Prompt.HSplitTop(16.0f, &PromptBox, &Suggestions);
PromptBox.Draw(ColorRGBA(0, 0, 0, 0.75f), IGraphics::CORNER_ALL, 2.0f);
Suggestions.y += 6.0f;
if(Ui()->DoClearableEditBox(&m_PromptInput, &PromptBox, 10.0f) || m_ResetFilterResults)
{
m_PromptSelectedIndex = 0;
m_vpFilteredPromptList.clear();
if(m_ResetFilterResults && m_pLastAction)
{
m_vpFilteredPromptList.push_back(m_pLastAction);
}
for(auto *pQuickAction : m_vQuickActions)
{
if(pQuickAction->Disabled())
continue;
if(m_PromptInput.IsEmpty() || FuzzyMatch(pQuickAction->Label(), m_PromptInput.GetString()))
{
bool Skip = false;
if(m_ResetFilterResults)
if(pQuickAction == m_pLastAction)
Skip = true;
if(!Skip)
m_vpFilteredPromptList.push_back(pQuickAction);
}
}
m_ResetFilterResults = false;
}
s_ListBox.SetActive(!Ui()->IsPopupOpen());
s_ListBox.DoStart(15.0f, m_vpFilteredPromptList.size(), 1, 5, m_PromptSelectedIndex, &Suggestions, false);
for(size_t i = 0; i < m_vpFilteredPromptList.size(); i++)
{
const CListboxItem Item = s_ListBox.DoNextItem(m_vpFilteredPromptList[i], m_PromptSelectedIndex >= 0 && (size_t)m_PromptSelectedIndex == i);
if(!Item.m_Visible)
continue;
CUIRect LabelColumn, DescColumn;
Item.m_Rect.VSplitLeft(5.0f, nullptr, &LabelColumn);
LabelColumn.VSplitLeft(100.0f, &LabelColumn, &DescColumn);
LabelColumn.VSplitRight(5.0f, &LabelColumn, nullptr);
SLabelProperties Props;
Props.m_MaxWidth = LabelColumn.w;
Props.m_EllipsisAtEnd = true;
Ui()->DoLabel(&LabelColumn, m_vpFilteredPromptList[i]->Label(), 10.0f, TEXTALIGN_ML, Props);
Props.m_MaxWidth = DescColumn.w;
ColorRGBA DescColor = TextRender()->DefaultTextColor();
DescColor.a = Item.m_Selected ? 1.0f : 0.8f;
TextRender()->TextColor(DescColor);
Ui()->DoLabel(&DescColumn, m_vpFilteredPromptList[i]->Description(), 10.0f, TEXTALIGN_MR, Props);
TextRender()->TextColor(TextRender()->DefaultTextColor());
}
const int NewSelected = s_ListBox.DoEnd();
if(m_PromptSelectedIndex != NewSelected)
{
m_PromptSelectedIndex = NewSelected;
}
if(s_ListBox.WasItemActivated())
{
if(m_PromptSelectedIndex >= 0)
{
const CQuickAction *pBtn = m_vpFilteredPromptList[m_PromptSelectedIndex];
SetInactive();
pBtn->Call();
m_pLastAction = pBtn;
}
}
}

29
src/game/editor/prompt.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef GAME_EDITOR_PROMPT_H
#define GAME_EDITOR_PROMPT_H
#include <game/client/lineinput.h>
#include <game/client/ui_rect.h>
#include <game/editor/quick_action.h>
#include "component.h"
class CPrompt : public CEditorComponent
{
bool m_ResetFilterResults = true;
const CQuickAction *m_pLastAction = nullptr;
int m_PromptSelectedIndex = -1;
std::vector<const CQuickAction *> m_vpFilteredPromptList;
std::vector<CQuickAction *> m_vQuickActions;
CLineInputBuffered<512> m_PromptInput;
public:
void OnInit(CEditor *pEditor) override;
bool OnInput(const IInput::CEvent &Event) override;
void OnRender(CUIRect _) override;
bool IsActive();
void SetActive();
void SetInactive();
};
#endif

View file

@ -0,0 +1,58 @@
#ifndef GAME_EDITOR_QUICK_ACTION_H
#define GAME_EDITOR_QUICK_ACTION_H
#include <functional>
#include <utility>
typedef std::function<void()> FButtonClickCallback;
typedef std::function<bool()> FButtonDisabledCallback;
typedef std::function<bool()> FButtonActiveCallback;
typedef std::function<int()> FButtonColorCallback;
class CQuickAction
{
private:
const char *m_pLabel;
const char *m_pDescription;
FButtonClickCallback m_pfnCallback;
FButtonDisabledCallback m_pfnDisabledCallback;
FButtonActiveCallback m_pfnActiveCallback;
FButtonColorCallback m_pfnColorCallback;
public:
CQuickAction(
const char *pLabel,
const char *pDescription,
FButtonClickCallback pfnCallback,
FButtonDisabledCallback pfnDisabledCallback,
FButtonActiveCallback pfnActiveCallback,
FButtonColorCallback pfnColorCallback) :
m_pLabel(pLabel),
m_pDescription(pDescription),
m_pfnCallback(std::move(pfnCallback)),
m_pfnDisabledCallback(std::move(pfnDisabledCallback)),
m_pfnActiveCallback(std::move(pfnActiveCallback)),
m_pfnColorCallback(std::move(pfnColorCallback))
{
}
// code to run when the action is triggered
void Call() const { m_pfnCallback(); }
// bool that indicates if the action can be performed not or not
bool Disabled() { return m_pfnDisabledCallback(); }
// bool that indicates if the action is currently running
// only applies to actions that can be turned on or off like proof borders
bool Active() { return m_pfnActiveCallback(); }
// color "enum" that represents the state of the quick actions button
// used as Checked argument for DoButton_Editor()
int Color() { return m_pfnColorCallback(); }
const char *Label() const { return m_pLabel; }
const char *Description() const { return m_pDescription; }
};
#endif

View file

@ -0,0 +1,55 @@
#include <game/mapitems.h>
#include "editor.h"
#include "editor_actions.h"
void CEditor::AddGroup()
{
m_Map.NewGroup();
m_SelectedGroup = m_Map.m_vpGroups.size() - 1;
m_EditorHistory.RecordAction(std::make_shared<CEditorActionGroup>(this, m_SelectedGroup, false));
}
void CEditor::AddTileLayer()
{
std::shared_ptr<CLayer> pTileLayer = std::make_shared<CLayerTiles>(this, m_Map.m_pGameLayer->m_Width, m_Map.m_pGameLayer->m_Height);
pTileLayer->m_pEditor = this;
m_Map.m_vpGroups[m_SelectedGroup]->AddLayer(pTileLayer);
int LayerIndex = m_Map.m_vpGroups[m_SelectedGroup]->m_vpLayers.size() - 1;
SelectLayer(LayerIndex);
m_Map.m_vpGroups[m_SelectedGroup]->m_Collapse = false;
m_EditorHistory.RecordAction(std::make_shared<CEditorActionAddLayer>(this, m_SelectedGroup, LayerIndex));
}
bool CEditor::IsNonGameTileLayerSelected() const
{
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
if(!pLayer)
return false;
if(pLayer->m_Type != LAYERTYPE_TILES)
return false;
if(
pLayer == m_Map.m_pGameLayer ||
pLayer == m_Map.m_pFrontLayer ||
pLayer == m_Map.m_pSwitchLayer ||
pLayer == m_Map.m_pTeleLayer ||
pLayer == m_Map.m_pSpeedupLayer ||
pLayer == m_Map.m_pTuneLayer)
return false;
return true;
}
void CEditor::LayerSelectImage()
{
if(!IsNonGameTileLayerSelected())
return;
std::shared_ptr<CLayer> pLayer = GetSelectedLayer(0);
std::shared_ptr<CLayerTiles> pTiles = std::static_pointer_cast<CLayerTiles>(pLayer);
static SLayerPopupContext s_LayerPopupContext = {};
s_LayerPopupContext.m_pEditor = this;
Ui()->DoPopupMenu(&s_LayerPopupContext, Ui()->MouseX(), Ui()->MouseY(), 120, 270, &s_LayerPopupContext, PopupLayer);
PopupSelectImageInvoke(pTiles->m_Image, Ui()->MouseX(), Ui()->MouseY());
}

View file

@ -0,0 +1,58 @@
// This file can be included several times.
#ifndef REGISTER_QUICK_ACTION
#define REGISTER_QUICK_ACTION(name, text, callback, disabled, active, button_color, description)
#endif
#define ALWAYS_FALSE []() -> bool { return false; }
#define DEFAULT_BTN []() -> int { return -1; }
REGISTER_QUICK_ACTION(
AddGroup, "Add group", [&]() { AddGroup(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Adds a new group")
REGISTER_QUICK_ACTION(
Refocus, "Refocus", [&]() { MapView()->Focus(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "[HOME] Restore map focus")
REGISTER_QUICK_ACTION(
Proof,
"Proof",
[&]() { MapView()->ProofMode()->Toggle(); },
ALWAYS_FALSE,
[&]() -> bool { return MapView()->ProofMode()->IsEnabled(); },
DEFAULT_BTN,
"Toggles proof borders. These borders represent the area that a player can see with default zoom.")
REGISTER_QUICK_ACTION(
AddTileLayer, "Add tile layer", [&]() { AddTileLayer(); }, ALWAYS_FALSE, ALWAYS_FALSE, DEFAULT_BTN, "Creates a new tile layer.")
REGISTER_QUICK_ACTION(
SaveAs,
"Save As",
[&]() { InvokeFileDialog(IStorage::TYPE_SAVE, FILETYPE_MAP, "Save map", "Save As", "maps", true, CEditor::CallbackSaveMap, this); },
ALWAYS_FALSE,
ALWAYS_FALSE,
DEFAULT_BTN,
"Saves the current map under a new name (ctrl+shift+s)")
REGISTER_QUICK_ACTION(
Envelopes,
"Envelopes",
[&]() { m_ActiveExtraEditor = m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES ? EXTRAEDITOR_NONE : EXTRAEDITOR_ENVELOPES; },
ALWAYS_FALSE,
ALWAYS_FALSE,
[&]() -> int { return m_ShowPicker ? -1 : m_ActiveExtraEditor == EXTRAEDITOR_ENVELOPES; },
"Toggles the envelope editor.")
REGISTER_QUICK_ACTION(
AddImage,
"Add Image",
[&]() { InvokeFileDialog(IStorage::TYPE_ALL, FILETYPE_IMG, "Add Image", "Add", "mapres", false, AddImage, this); },
ALWAYS_FALSE,
ALWAYS_FALSE,
DEFAULT_BTN,
"Load a new image to use in the map")
REGISTER_QUICK_ACTION(
LayerPropAddImage,
"Layer: Add Image",
[&]() { LayerSelectImage(); },
[&]() -> bool { return !IsNonGameTileLayerSelected(); },
ALWAYS_FALSE,
DEFAULT_BTN,
"Pick mapres image for currently selected layer")
#undef ALWAYS_FALSE
#undef DEFAULT_BTN