Fix duplicate items in keyboard shortcuts list (fix #4387)

Introduced Key::isListed() and Command::isListed() to customize when a
command should be displayed in the list of shortcuts.

Removed commands:
'Launch'
'OpenBrowser'
And removed unnecessary commands:
'Change Color Mode: Indexed'
'Contract Selection'
'Export Sprite Sheet'
'Flip Canvas Horizontally'
'Frame Properties'
'Load Palette'
'Open Sprite'
'Playback Speed 1x'
'Run Script'
'Save Palette'
'Select Used Colors'
'Set Palette Entry Size'
'Tileset Mode: Auto'
This commit is contained in:
Gaspar Capello 2024-05-21 12:36:33 -03:00 committed by David Capello
parent a7a31f9a4a
commit 04c45f4329
26 changed files with 154 additions and 7 deletions

View File

@ -538,7 +538,7 @@
</key> </key>
<key command="ChangePixelFormat"> <key command="ChangePixelFormat">
<param name="format" value="indexed" /> <param name="format" value="indexed" />
<param name="dithering" value="old-ordered" /> <param name="dithering" value="old" />
</key> </key>
<key command="ChangeBrush"> <key command="ChangeBrush">
<param name="change" value="increment-angle" /> <param name="change" value="increment-angle" />

View File

@ -280,6 +280,8 @@ Flip_Canvas = Canvas
Flip_Horizontally = Horizontally Flip_Horizontally = Horizontally
Flip_Selection = Selection Flip_Selection = Selection
Flip_Vertically = Vertically Flip_Vertically = Vertically
FrameProperties_All = Frame Properties of all frames
FrameProperties_Current = Frame Properties of the current range
FrameProperties = Frame Properties FrameProperties = Frame Properties
FrameTagProperties = Tag Properties FrameTagProperties = Tag Properties
FullscreenMode = Toggle Fullscreen Mode FullscreenMode = Toggle Fullscreen Mode
@ -313,6 +315,7 @@ LayerVisibility = Layer Visibility
LinkCels = Links Cels LinkCels = Links Cels
LoadMask = Load Selection LoadMask = Load Selection
LoadPalette = Load Palette LoadPalette = Load Palette
LoadDefaultPalette = Load Default Palette
MaskAll = Mask All MaskAll = Mask All
MaskByColor = Mask By Color MaskByColor = Mask By Color
MaskContent = Mask Content MaskContent = Mask Content
@ -404,6 +407,8 @@ SaveFileAs = Save File As
SaveFileCopyAs = Export SaveFileCopyAs = Export
SaveMask = Save Selection SaveMask = Save Selection
SavePalette = Save Palette SavePalette = Save Palette
SavePaletteAsDefault = Save Palette as Default
SavePaletteAsPreset = Save Palette as Preset
Screenshot = Screenshot Screenshot = Screenshot
Screenshot_Open = Take & Open Screenshot Screenshot_Open = Take & Open Screenshot
Screenshot_Save = Take & Save Screenshot Screenshot_Save = Take & Save Screenshot

View File

@ -64,6 +64,9 @@ public:
protected: protected:
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
bool isListed(const Params& params, const KeyContext& context) const override {
return params.empty();
}
}; };
} // namespace app } // namespace app

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2024 Igara Studio S.A.
// Copyright (C) 2001-2015 David Capello // Copyright (C) 2001-2015 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -9,6 +10,7 @@
#pragma once #pragma once
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/params.h"
#include "doc/algorithm/flip_type.h" #include "doc/algorithm/flip_type.h"
namespace app { namespace app {
@ -24,6 +26,9 @@ namespace app {
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override {
return !params.empty();
}
private: private:
bool m_flipMask; bool m_flipMask;

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -14,6 +15,7 @@
#include "app/context.h" #include "app/context.h"
#include "app/context_access.h" #include "app/context_access.h"
#include "app/doc_api.h" #include "app/doc_api.h"
#include "app/i18n/strings.h"
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "app/tx.h" #include "app/tx.h"
#include "base/convert_to.h" #include "base/convert_to.h"
@ -35,6 +37,7 @@ protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
private: private:
enum Target { enum Target {
@ -137,6 +140,17 @@ void FramePropertiesCommand::onExecute(Context* context)
} }
} }
std::string FramePropertiesCommand::onGetFriendlyName() const
{
switch (m_target) {
case CURRENT_RANGE:
return Strings::commands_FrameProperties_Current() ;
case ALL_FRAMES:
return Strings::commands_FrameProperties_All();
}
return Command::onGetFriendlyName();
}
Command* CommandFactory::createFramePropertiesCommand() Command* CommandFactory::createFramePropertiesCommand()
{ {
return new FramePropertiesCommand; return new FramePropertiesCommand;

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2022 Igara Studio S.A. // Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -87,6 +87,9 @@ protected:
return (frame > 0 ? frame-1: last); return (frame > 0 ? frame-1: last);
} }
bool isListed(const Params& params, const KeyContext& context) const override {
return context == KeyContext::Normal;
}
}; };
class GotoNextFrameCommand : public GotoCommand { class GotoNextFrameCommand : public GotoCommand {
@ -100,6 +103,9 @@ protected:
return (frame < last ? frame+1: 0); return (frame < last ? frame+1: 0);
} }
bool isListed(const Params& params, const KeyContext& context) const override {
return context == KeyContext::Normal;
}
}; };
class GotoNextFrameWithSameTagCommand : public GotoCommand { class GotoNextFrameWithSameTagCommand : public GotoCommand {

View File

@ -606,7 +606,8 @@ private:
if (key->type() == KeyType::Tool || if (key->type() == KeyType::Tool ||
key->type() == KeyType::Quicktool || key->type() == KeyType::Quicktool ||
key->type() == KeyType::WheelAction || key->type() == KeyType::WheelAction ||
key->type() == KeyType::DragAction) { key->type() == KeyType::DragAction ||
key->isListed()) {
continue; continue;
} }

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020 Igara Studio S.A. // Copyright (C) 2020-2024 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -24,6 +24,10 @@ public:
protected: protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override {
return params.get("path") != "";
}
private: private:
enum Type { Url }; enum Type { Url };
@ -59,6 +63,11 @@ void LaunchCommand::onExecute(Context* context)
} }
} }
std::string LaunchCommand::onGetFriendlyName() const
{
return Command::onGetFriendlyName() + ": " + m_path;
}
Command* CommandFactory::createLaunchCommand() Command* CommandFactory::createLaunchCommand()
{ {
return new LaunchCommand; return new LaunchCommand;

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2020-2023 Igara Studio S.A. // Copyright (C) 2020-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -56,6 +56,9 @@ public:
protected: protected:
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
bool isListed(const Params& params, const KeyContext& context) const override {
return context == KeyContext::Normal;
}
}; };
class LayerPropertiesWindow; class LayerPropertiesWindow;

View File

@ -32,6 +32,7 @@ public:
protected: protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
private: private:
std::string m_preset; std::string m_preset;
@ -88,6 +89,14 @@ void LoadPaletteCommand::onExecute(Context* context)
context->executeCommand(cmd); context->executeCommand(cmd);
} }
std::string LoadPaletteCommand::onGetFriendlyName() const
{
std::string name = Command::onGetFriendlyName();
if (m_preset == "default")
name = Strings::commands_LoadDefaultPalette();
return name;
}
Command* CommandFactory::createLoadPaletteCommand() Command* CommandFactory::createLoadPaletteCommand()
{ {
return new LoadPaletteCommand; return new LoadPaletteCommand;

View File

@ -45,6 +45,9 @@ protected:
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override {
return !params.empty();
}
private: private:
std::string getActionName() const; std::string getActionName() const;

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2024 Igara Studio S.A.
// Copyright (C) 2016-2017 David Capello // Copyright (C) 2016-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -23,6 +24,10 @@ public:
protected: protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override {
return !params.empty();
}
private: private:
std::string m_filename; std::string m_filename;
@ -43,6 +48,11 @@ void OpenBrowserCommand::onExecute(Context* context)
App::instance()->mainWindow()->showBrowser(m_filename); App::instance()->mainWindow()->showBrowser(m_filename);
} }
std::string OpenBrowserCommand::onGetFriendlyName() const
{
return Command::onGetFriendlyName() + ": " + m_filename;
}
Command* CommandFactory::createOpenBrowserCommand() Command* CommandFactory::createOpenBrowserCommand()
{ {
return new OpenBrowserCommand; return new OpenBrowserCommand;

View File

@ -269,6 +269,21 @@ void OpenFileCommand::onExecute(Context* context)
} }
} }
std::string OpenFileCommand::onGetFriendlyName() const
{
// TO DO: would be better to show the last part of the path
// via text size hint instead of a fixed number of chars.
auto uiScale = Preferences::instance().general.uiScale();
auto scScale = Preferences::instance().general.screenScale();
int pos(68.0 / double(uiScale) / double(scScale));
return Command::onGetFriendlyName().append(
(m_filename.empty() ?
"" :
(": " + (m_filename.size() >= pos ?
m_filename.substr(m_filename.size() - pos, pos) :
m_filename))));
}
Command* CommandFactory::createOpenFileCommand() Command* CommandFactory::createOpenFileCommand()
{ {
return new OpenFileCommand; return new OpenFileCommand;

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/params.h"
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "base/paths.h" #include "base/paths.h"
@ -32,6 +33,7 @@ namespace app {
protected: protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
private: private:
std::string m_filename; std::string m_filename;

View File

@ -39,6 +39,10 @@ protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override
{
return !params.empty();
}
private: private:
std::string m_filename; std::string m_filename;

View File

@ -34,6 +34,7 @@ public:
protected: protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
private: private:
std::string m_preset; std::string m_preset;
@ -101,6 +102,15 @@ void SavePaletteCommand::onExecute(Context* ctx)
} }
} }
std::string SavePaletteCommand::onGetFriendlyName() const
{
if (m_preset == "default")
return Strings::commands_SavePaletteAsDefault();
else if (m_saveAsPreset)
return Strings::commands_SavePaletteAsPreset();
return Command::onGetFriendlyName();
}
Command* CommandFactory::createSavePaletteCommand() Command* CommandFactory::createSavePaletteCommand()
{ {
return new SavePaletteCommand; return new SavePaletteCommand;

View File

@ -45,6 +45,10 @@ protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override
{
return !params.empty();
}
private: private:
void selectTiles(const Layer* layer, void selectTiles(const Layer* layer,

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -33,6 +34,9 @@ protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override; bool onEnabled(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
bool isListed(const Params& params, const KeyContext& context) const override {
return context == KeyContext::FramesSelection;
}
Action m_action; Action m_action;
doc::frame_t m_begin, m_end; doc::frame_t m_begin, m_end;

View File

@ -1,4 +1,5 @@
// Aseprite // Aseprite
// Copyright (c) 2024 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -23,6 +24,11 @@ protected:
void onLoadParams(const Params& params) override; void onLoadParams(const Params& params) override;
bool onChecked(Context* context) override; bool onChecked(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override
{
return !params.empty();
}
private: private:
int m_size; int m_size;
@ -50,6 +56,11 @@ void SetPaletteEntrySizeCommand::onExecute(Context* context)
ColorBar::instance()->getPaletteView()->setBoxSize(m_size); ColorBar::instance()->getPaletteView()->setBoxSize(m_size);
} }
std::string SetPaletteEntrySizeCommand::onGetFriendlyName() const
{
return Command::onGetFriendlyName() + " " + std::to_string(m_size);
}
Command* CommandFactory::createSetPaletteEntrySizeCommand() Command* CommandFactory::createSetPaletteEntrySizeCommand()
{ {
return new SetPaletteEntrySizeCommand; return new SetPaletteEntrySizeCommand;

View File

@ -29,6 +29,10 @@ protected:
bool onChecked(Context* context) override; bool onChecked(Context* context) override;
void onExecute(Context* context) override; void onExecute(Context* context) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override
{
return !params.empty();
}
filters::TiledMode m_mode; filters::TiledMode m_mode;
}; };

View File

@ -11,6 +11,7 @@
#include "app/commands/command_factory.h" #include "app/commands/command_factory.h"
#include "app/commands/command_ids.h" #include "app/commands/command_ids.h"
#include "app/ui/key_context.h"
#include <string> #include <string>
@ -36,6 +37,13 @@ namespace app {
void loadParams(const Params& params); void loadParams(const Params& params);
bool isEnabled(Context* context); bool isEnabled(Context* context);
bool isChecked(Context* context); bool isChecked(Context* context);
// Not all Commands must be listed on KeyBoard Shortcut list, so
// this function returns if a key command should be listed or not.
// Used on 'cmd_keyboard_shorcuts.cpp'.
virtual bool isListed(const Params& params, const KeyContext& context) const
{
return true;
}
protected: protected:
virtual bool onNeedsParams() const; virtual bool onNeedsParams() const;

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2019-2021 Igara Studio S.A. // Copyright (C) 2019-2024 Igara Studio S.A.
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -54,6 +54,9 @@ public:
protected: protected:
void onExecute(Context* ctx) override; void onExecute(Context* ctx) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override {
return !params.empty();
}
}; };
ScreenshotCommand::ScreenshotCommand() ScreenshotCommand::ScreenshotCommand()

View File

@ -26,6 +26,10 @@ protected:
bool onChecked(Context* ctx) override; bool onChecked(Context* ctx) override;
void onExecute(Context* ctx) override; void onExecute(Context* ctx) override;
std::string onGetFriendlyName() const override; std::string onGetFriendlyName() const override;
bool isListed(const Params& params, const KeyContext& context) const override
{
return !params.empty();
}
}; };
SetPlaybackSpeedCommand::SetPlaybackSpeedCommand() SetPlaybackSpeedCommand::SetPlaybackSpeedCommand()

View File

@ -54,6 +54,10 @@ protected:
return Strings::commands_TilesetMode(mode); return Strings::commands_TilesetMode(mode);
} }
bool isListed(const Params& params, const KeyContext& context) const override {
return !params.empty();
}
private: private:
TilesetMode m_mode; TilesetMode m_mode;
}; };

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2018-2023 Igara Studio S.A. // Copyright (C) 2018-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello // Copyright (C) 2001-2018 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
@ -138,6 +138,7 @@ namespace app {
const KeyboardShortcuts& globalKeys) const; const KeyboardShortcuts& globalKeys) const;
bool isPressed() const; bool isPressed() const;
bool isLooselyPressed() const; bool isLooselyPressed() const;
bool isListed() const;
bool hasAccel(const ui::Accelerator& accel) const; bool hasAccel(const ui::Accelerator& accel) const;
bool hasUserDefinedAccels() const; bool hasUserDefinedAccels() const;

View File

@ -494,6 +494,11 @@ bool Key::isLooselyPressed() const
return false; return false;
} }
bool Key::isListed() const
{
return type() != KeyType::Command || !command()->isListed(params(), keycontext());
}
bool Key::hasAccel(const ui::Accelerator& accel) const bool Key::hasAccel(const ui::Accelerator& accel) const
{ {
return accels().has(accel); return accels().has(accel);