6832: Show message in editor when player is moved ingame, refactor rendering of editor mentions and modebar r=def- a=Robyt3

Show a short message below the existing chat mentions message that is shown in the top left area of the editor above the layers/images/sounds button when the player character is moved ingame while the editor is open. The messages are cleared when the editor is activated and when the client is disconnected.

Closes #1993.

Screenshots:
- Before:
![screenshot_2023-07-11_18-48-46](https://github.com/ddnet/ddnet/assets/23437060/aacac7c3-05ab-4748-b418-9c89d056d79b)
- After:
![screenshot_2023-07-11_18-03-32](https://github.com/ddnet/ddnet/assets/23437060/153be694-5847-40bc-9857-85c9bfae75ec)


## Checklist

- [X] Tested the change ingame
- [X] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2023-07-11 17:11:08 +00:00 committed by GitHub
commit 13806f1581
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 62 deletions

View file

@ -3200,7 +3200,7 @@ void CClient::Run()
{ {
Input()->MouseModeRelative(); Input()->MouseModeRelative();
GameClient()->OnActivateEditor(); GameClient()->OnActivateEditor();
m_pEditor->ResetMentions(); m_pEditor->OnActivate();
m_EditorActive = true; m_EditorActive = true;
} }
} }

View file

@ -12,11 +12,14 @@ public:
virtual void Init() = 0; virtual void Init() = 0;
virtual void OnUpdate() = 0; virtual void OnUpdate() = 0;
virtual void OnRender() = 0; virtual void OnRender() = 0;
virtual void OnActivate() = 0;
virtual bool HasUnsavedData() const = 0; virtual bool HasUnsavedData() const = 0;
virtual bool Load(const char *pFilename, int StorageType) = 0; virtual bool Load(const char *pFilename, int StorageType) = 0;
virtual bool Save(const char *pFilename) = 0; virtual bool Save(const char *pFilename) = 0;
virtual void UpdateMentions() = 0; virtual void UpdateMentions() = 0;
virtual void ResetMentions() = 0; virtual void ResetMentions() = 0;
virtual void OnIngameMoved() = 0;
virtual void ResetIngameMoved() = 0;
}; };
extern IEditor *CreateEditor(); extern IEditor *CreateEditor();

View file

@ -567,6 +567,9 @@ void CGameClient::OnReset()
m_LastDummyConnected = false; m_LastDummyConnected = false;
m_ReceivedDDNetPlayer = false; m_ReceivedDDNetPlayer = false;
Editor()->ResetMentions();
Editor()->ResetIngameMoved();
} }
void CGameClient::UpdatePositions() void CGameClient::UpdatePositions()
@ -1754,6 +1757,13 @@ void CGameClient::OnNewSnapshot()
for(auto &pComponent : m_vpAll) for(auto &pComponent : m_vpAll)
pComponent->OnNewSnapshot(); pComponent->OnNewSnapshot();
// notify editor when local character moved
if(m_Snap.m_pLocalCharacter && m_Snap.m_pLocalPrevCharacter &&
(m_Snap.m_pLocalCharacter->m_X != m_Snap.m_pLocalPrevCharacter->m_X || m_Snap.m_pLocalCharacter->m_Y != m_Snap.m_pLocalPrevCharacter->m_Y))
{
Editor()->OnIngameMoved();
}
// detect air jump for other players // detect air jump for other players
for(int i = 0; i < MAX_CLIENTS; i++) for(int i = 0; i < MAX_CLIENTS; i++)
if(m_Snap.m_aCharacters[i].m_Active && (m_Snap.m_aCharacters[i].m_Cur.m_Jumped & 2) && !(m_Snap.m_aCharacters[i].m_Prev.m_Jumped & 2)) if(m_Snap.m_aCharacters[i].m_Active && (m_Snap.m_aCharacters[i].m_Cur.m_Jumped & 2) && !(m_Snap.m_aCharacters[i].m_Prev.m_Jumped & 2))

View file

@ -458,13 +458,6 @@ int CEditor::DoButton_MenuItem(const void *pID, const char *pText, int Checked,
return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip); return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
} }
int CEditor::DoButton_Tab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip)
{
pRect->Draw(GetButtonColor(pID, Checked), IGraphics::CORNER_T, 5.0f);
UI()->DoLabel(pRect, pText, 10.0f, TEXTALIGN_MC);
return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip);
}
int CEditor::DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize) int CEditor::DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize)
{ {
pRect->Draw(GetButtonColor(pID, Checked), Corners, 3.0f); pRect->Draw(GetButtonColor(pID, Checked), Corners, 3.0f);
@ -5270,44 +5263,59 @@ void CEditor::ShowFileDialogError(const char *pFormat, ...)
void CEditor::RenderModebar(CUIRect View) void CEditor::RenderModebar(CUIRect View)
{ {
CUIRect Button; CUIRect Mentions, IngameMoved, ModeButton;
View.HSplitTop(12.0f, &Mentions, &View);
View.HSplitTop(12.0f, &IngameMoved, &View);
View.HSplitTop(8.0f, nullptr, &ModeButton);
ModeButton.VSplitLeft(65.0f, &ModeButton, nullptr);
// mode buttons // mentions
if(m_Mentions)
{ {
View.VSplitLeft(65.0f, &Button, &View); char aBuf[64];
Button.HSplitTop(30.0f, nullptr, &Button); if(m_Mentions == 1)
static int s_Button = 0; str_copy(aBuf, Localize("1 new mention"));
const char *pButName = ""; else if(m_Mentions <= 9)
str_format(aBuf, sizeof(aBuf), Localize("%d new mentions"), m_Mentions);
else
str_copy(aBuf, Localize("9+ new mentions"));
TextRender()->TextColor(ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
UI()->DoLabel(&Mentions, aBuf, 10.0f, TEXTALIGN_MC);
TextRender()->TextColor(TextRender()->DefaultTextColor());
}
// ingame moved warning
if(m_IngameMoved)
{
TextRender()->TextColor(ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f));
UI()->DoLabel(&IngameMoved, Localize("Moved ingame"), 10.0f, TEXTALIGN_MC);
TextRender()->TextColor(TextRender()->DefaultTextColor());
}
// mode button
{
const char *pModeLabel = "";
if(m_Mode == MODE_LAYERS) if(m_Mode == MODE_LAYERS)
pButName = "Layers"; pModeLabel = "Layers";
else if(m_Mode == MODE_IMAGES) else if(m_Mode == MODE_IMAGES)
pButName = "Images"; pModeLabel = "Images";
else if(m_Mode == MODE_SOUNDS) else if(m_Mode == MODE_SOUNDS)
pButName = "Sounds"; pModeLabel = "Sounds";
else
dbg_assert(false, "m_Mode invalid");
int MouseButton = DoButton_Tab(&s_Button, pButName, 0, &Button, 0, "Switch between images, sounds and layers management."); static int s_ModeButton = 0;
const int MouseButton = DoButton_Ex(&s_ModeButton, pModeLabel, 0, &ModeButton, 0, "Switch between images, sounds and layers management.", IGraphics::CORNER_T, 10.0f);
if(MouseButton == 2 || (Input()->KeyPress(KEY_LEFT) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0)) if(MouseButton == 2 || (Input()->KeyPress(KEY_LEFT) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0))
{ {
if(m_Mode == MODE_LAYERS) m_Mode = (m_Mode + NUM_MODES - 1) % NUM_MODES;
m_Mode = MODE_SOUNDS;
else if(m_Mode == MODE_IMAGES)
m_Mode = MODE_LAYERS;
else
m_Mode = MODE_IMAGES;
} }
else if(MouseButton == 1 || (Input()->KeyPress(KEY_RIGHT) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0)) else if(MouseButton == 1 || (Input()->KeyPress(KEY_RIGHT) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0))
{ {
if(m_Mode == MODE_LAYERS) m_Mode = (m_Mode + 1) % NUM_MODES;
m_Mode = MODE_IMAGES;
else if(m_Mode == MODE_IMAGES)
m_Mode = MODE_SOUNDS;
else
m_Mode = MODE_LAYERS;
} }
} }
View.VSplitLeft(5.0f, nullptr, &View);
} }
void CEditor::RenderStatusbar(CUIRect View) void CEditor::RenderStatusbar(CUIRect View)
@ -6229,7 +6237,7 @@ void CEditor::Render()
// render checker // render checker
RenderBackground(View, m_CheckerTexture, 32.0f, 1.0f); RenderBackground(View, m_CheckerTexture, 32.0f, 1.0f);
CUIRect MenuBar, CModeBar, ToolBar, StatusBar, ExtraEditor, ToolBox; CUIRect MenuBar, ModeBar, ToolBar, StatusBar, ExtraEditor, ToolBox;
m_ShowPicker = Input()->KeyIsPressed(KEY_SPACE) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0 && UI()->LastActiveItem() != &m_SettingsCommandInput && m_vSelectedLayers.size() == 1; m_ShowPicker = Input()->KeyIsPressed(KEY_SPACE) && m_Dialog == DIALOG_NONE && m_EditBoxActive == 0 && UI()->LastActiveItem() != &m_SettingsCommandInput && m_vSelectedLayers.size() == 1;
if(m_GuiActive) if(m_GuiActive)
@ -6326,34 +6334,12 @@ void CEditor::Render()
RenderBackground(ToolBar, m_BackgroundTexture, 128.0f, Brightness); RenderBackground(ToolBar, m_BackgroundTexture, 128.0f, Brightness);
ToolBar.Margin(2.0f, &ToolBar); ToolBar.Margin(2.0f, &ToolBar);
ToolBar.VSplitLeft(100.0f, &CModeBar, &ToolBar); ToolBar.VSplitLeft(100.0f, &ModeBar, &ToolBar);
RenderBackground(StatusBar, m_BackgroundTexture, 128.0f, Brightness); RenderBackground(StatusBar, m_BackgroundTexture, 128.0f, Brightness);
StatusBar.Margin(2.0f, &StatusBar); StatusBar.Margin(2.0f, &StatusBar);
} }
// show mentions
if(m_GuiActive && m_Mentions)
{
char aBuf[64];
if(m_Mentions == 1)
{
str_copy(aBuf, Localize("1 new mention"));
}
else if(m_Mentions <= 9)
{
str_format(aBuf, sizeof(aBuf), Localize("%d new mentions"), m_Mentions);
}
else
{
str_copy(aBuf, Localize("9+ new mentions"));
}
TextRender()->TextColor(1.0f, 0.0f, 0.0f, 1.0f);
TextRender()->Text(5.0f, 27.0f, 10.0f, aBuf, -1.0f);
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
}
// do the toolbar // do the toolbar
if(m_Mode == MODE_LAYERS) if(m_Mode == MODE_LAYERS)
DoToolbarLayers(ToolBar); DoToolbarLayers(ToolBar);
@ -6471,8 +6457,7 @@ void CEditor::Render()
if(m_GuiActive) if(m_GuiActive)
{ {
RenderMenubar(MenuBar); RenderMenubar(MenuBar);
RenderModebar(ModeBar);
RenderModebar(CModeBar);
if(!m_ShowPicker) if(!m_ShowPicker)
{ {
if(m_ShowEnvelopeEditor) if(m_ShowEnvelopeEditor)
@ -7245,6 +7230,12 @@ void CEditor::OnRender()
CLineInput::RenderCandidates(); CLineInput::RenderCandidates();
} }
void CEditor::OnActivate()
{
ResetMentions();
ResetIngameMoved();
}
void CEditor::LoadCurrentMap() void CEditor::LoadCurrentMap()
{ {
if(Load(m_pClient->GetCurrentMapPath(), IStorage::TYPE_SAVE)) if(Load(m_pClient->GetCurrentMapPath(), IStorage::TYPE_SAVE))

View file

@ -36,6 +36,7 @@ enum
MODE_LAYERS = 0, MODE_LAYERS = 0,
MODE_IMAGES, MODE_IMAGES,
MODE_SOUNDS, MODE_SOUNDS,
NUM_MODES,
DIALOG_NONE = 0, DIALOG_NONE = 0,
DIALOG_FILE, DIALOG_FILE,
@ -865,16 +866,17 @@ public:
m_PreventUnusedTilesWasWarned = false; m_PreventUnusedTilesWasWarned = false;
m_AllowPlaceUnusedTiles = 0; m_AllowPlaceUnusedTiles = 0;
m_BrushDrawDestructive = true; m_BrushDrawDestructive = true;
m_Mentions = 0;
} }
void Init() override; void Init() override;
void OnUpdate() override; void OnUpdate() override;
void OnRender() override; void OnRender() override;
void OnActivate() override;
bool HasUnsavedData() const override { return m_Map.m_Modified; } bool HasUnsavedData() const override { return m_Map.m_Modified; }
void UpdateMentions() override { m_Mentions++; } void UpdateMentions() override { m_Mentions++; }
void ResetMentions() override { m_Mentions = 0; } void ResetMentions() override { m_Mentions = 0; }
void OnIngameMoved() override { m_IngameMoved = true; }
void ResetIngameMoved() override { m_IngameMoved = false; }
void HandleCursorMovement(); void HandleCursorMovement();
void HandleAutosave(); void HandleAutosave();
@ -955,7 +957,8 @@ public:
int m_AllowPlaceUnusedTiles; int m_AllowPlaceUnusedTiles;
bool m_BrushDrawDestructive; bool m_BrushDrawDestructive;
int m_Mentions; int m_Mentions = 0;
bool m_IngameMoved = false;
enum enum
{ {
@ -1175,7 +1178,6 @@ public:
int DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_Editor(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
int DoButton_Env(const void *pID, const char *pText, int Checked, const CUIRect *pRect, const char *pToolTip, ColorRGBA Color, int Corners); int DoButton_Env(const void *pID, const char *pText, int Checked, const CUIRect *pRect, const char *pToolTip, ColorRGBA Color, int Corners);
int DoButton_Tab(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);
int DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize = 10.0f); int DoButton_Ex(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize = 10.0f);
int DoButton_FontIcon(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize = 10.0f); int DoButton_FontIcon(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip, int Corners, float FontSize = 10.0f);
int DoButton_ButtonDec(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_ButtonDec(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip);