Skip to content

Commit

Permalink
Fix custom brush slot cannot be deleted when it's in the middle of th…
Browse files Browse the repository at this point in the history
…e list (fix aseprite#4058)
  • Loading branch information
Gasparoken committed Oct 5, 2023
1 parent af19d81 commit 8be3e16
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 7 deletions.
5 changes: 4 additions & 1 deletion src/app/app_brushes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ AppBrushes::AppBrushes()
}
}
m_userBrushesFilename = fn;
m_lastSlotDeletedIndex = 0xffff;
}

AppBrushes::~AppBrushes()
Expand Down Expand Up @@ -225,7 +226,9 @@ void AppBrushes::removeBrushSlot(slot_id slot)
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size()) {
m_slots[slot] = BrushSlot();

m_slots.erase(m_slots.begin() + slot);
m_lastSlotDeletedIndex = slot + 1; // the first slot_id is 1

// Erase empty trailing slots
while (!m_slots.empty() &&
Expand Down
8 changes: 7 additions & 1 deletion src/app/app_brushes.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2021 Igara Studio S.A.
// Copyright (C) 2021-2023 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
Expand Down Expand Up @@ -42,6 +42,11 @@ namespace app {
void unlockBrushSlot(slot_id slot);
bool isBrushSlotLocked(slot_id slot) const;

const int getlastDeletedSlotIndex() {
return m_lastSlotDeletedIndex;
}
void resetDeletedSlotIndex() { m_lastSlotDeletedIndex = 0xffff; }

obs::signal<void()> ItemsChange;

private:
Expand All @@ -52,6 +57,7 @@ namespace app {
doc::Brushes m_standard;
BrushSlots m_slots;
std::string m_userBrushesFilename;
int m_lastSlotDeletedIndex;
};

} // namespace app
Expand Down
4 changes: 1 addition & 3 deletions src/app/commands/cmd_keyboard_shortcuts.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2022 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
Expand Down Expand Up @@ -50,8 +50,6 @@
#include <map>
#include <memory>

#define KEYBOARD_FILENAME_EXTENSION "aseprite-keys"

namespace app {

using namespace skin;
Expand Down
13 changes: 11 additions & 2 deletions src/app/ui/brush_popup.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2022 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
Expand All @@ -19,6 +19,7 @@
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/pref/preferences.h"
#include "app/resource_finder.h"
#include "app/tools/tool.h"
#include "app/ui/app_menuitem.h"
#include "app/ui/button_set.h"
Expand Down Expand Up @@ -411,9 +412,13 @@ void BrushPopup::regenerate(ui::Display* display,
m_customBrushes->setTriggerOnMouseUp(true);

int slot = 0;
int lastDeletedSlotIndex = App::instance()->brushes().getlastDeletedSlotIndex();
for (const auto& brush : brushSlots) {
++slot;

if (slot >= lastDeletedSlotIndex)
KeyboardShortcuts::instance()->replaceCustomBrushShortcut(slot);

// Get shortcut
std::string shortcut;
{
Expand All @@ -422,8 +427,10 @@ void BrushPopup::regenerate(ui::Display* display,
params.set("slot", base::convert_to<std::string>(slot).c_str());
KeyPtr key = KeyboardShortcuts::instance()->command(
CommandId::ChangeBrush(), params);
if (key && !key->accels().empty())
if (key && !key->accels().empty()) {
shortcut = key->accels().front().toString();
key->originalKeyToUserDefinedKey();
}
}
m_customBrushes->addItem(new SelectBrushItem(brush, slot));
m_customBrushes->addItem(new BrushShortcutItem(shortcut, slot));
Expand All @@ -439,6 +446,8 @@ void BrushPopup::regenerate(ui::Display* display,
// Resize the window and change the hot region.
fit_bounds(display, this, gfx::Rect(pos, sizeHint()));
setHotRegion(gfx::Region(boundsOnScreen()));

App::instance()->brushes().resetDeletedSlotIndex();
}

void BrushPopup::onBrushChanges()
Expand Down
10 changes: 10 additions & 0 deletions src/app/ui/context_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "app/ini_file.h"
#include "app/match_words.h"
#include "app/pref/preferences.h"
#include "app/resource_finder.h"
#include "app/shade.h"
#include "app/site.h"
#include "app/tools/active_tool.h"
Expand Down Expand Up @@ -170,6 +171,15 @@ class ContextBar::BrushTypeField : public ButtonSet {
rgn |= gfx::Region(this->boundsOnScreen());
m_popupWindow.setHotRegion(rgn);
});
m_popupWindow.Close.connect(
[this]{
// Save keyboard shortcuts in configuration file
auto globalKeys = KeyboardShortcuts::instance();
ResourceFinder rf;
rf.includeUserDir("user." KEYBOARD_FILENAME_EXTENSION);
std::string fn = rf.getFirstOrCreateDefault();
globalKeys->exportFile(fn);
});
}

~BrushTypeField() {
Expand Down
2 changes: 2 additions & 0 deletions src/app/ui/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ namespace app {
void reset();

void copyOriginalToUser();
void copyAddsAndDels(const KeyPtr key);
void originalKeyToUserDefinedKey();

// for KeyType::Command
Command* command() const { return m_command; }
Expand Down
88 changes: 88 additions & 0 deletions src/app/ui/keyboard_shortcuts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,33 @@ void Key::copyOriginalToUser()
m_accels.reset();
}

void Key::copyAddsAndDels(const KeyPtr key) {
m_dels.clear();
auto delsCopy = key->delsKeys();
for (const auto& kv : delsCopy)
m_dels.emplace_back(kv.first, kv.second);

m_adds.clear();
auto addsCopy = key->addsKeys();
for (const auto& kv : addsCopy)
m_adds.emplace_back(kv.first, kv.second);

m_accels.reset();
}

void Key::originalKeyToUserDefinedKey()
{
auto addsCopy = m_adds;
m_adds.clear();
for (const auto& kv : addsCopy) {
if (kv.first == KeySource::Original)
m_adds.emplace_back(KeySource::UserDefined, kv.second);
else
m_adds.emplace_back(kv.first, kv.second);
}
m_accels.reset();
}

std::string Key::triggerString() const
{
switch (m_type) {
Expand Down Expand Up @@ -961,6 +988,67 @@ void KeyboardShortcuts::reset()
key->reset();
}

int KeyboardShortcuts::findKeyCommandShortcutIndex(
const char* commandName,
const Params& params,
const KeyContext keyContext) const
{
Command* command = Commands::instance()->byId(commandName);
int i = 0;
for (KeyPtr& key : m_keys) {
if (key &&
key->type() == KeyType::Command &&
key->keycontext() == keyContext &&
key->command() == command &&
key->params() == params) {
return i;
}
i++;
}
return -1;
}

bool KeyboardShortcuts::deleteKeyCommandShortcut(
const char* commandName,
const Params& params,
const KeyContext keyContext) const
{
int i = -1;
while (i < 0) {
i = findKeyCommandShortcutIndex(commandName, params, keyContext);
if (i < 0)
return false;
m_keys.erase(m_keys.begin() + i);
i = -1;
}
return true;
}

void KeyboardShortcuts::replaceCustomBrushShortcut(int slot)
{
Command* command = Commands::instance()->byId(CommandId::ChangeBrush());
Params params;
params.set("change", "custom");
params.set("slot", base::convert_to<std::string>(slot + 1).c_str());
KeyPtr nextBrushKey = instance()->command(CommandId::ChangeBrush(), params);
params.set("slot", base::convert_to<std::string>(slot).c_str());

if (nextBrushKey) {
KeyPtr newKey = std::make_shared<Key>(command, params, KeyContext::Any);
newKey->copyAddsAndDels(nextBrushKey);

// Clear all commands/shortcuts related to current slot
deleteKeyCommandShortcut(CommandId::ChangeBrush(), params);

// Adding new commad/shortcuts to KeyboardShortcuts
m_keys.push_back(newKey);

return;
}
params.set("slot", base::convert_to<std::string>(slot).c_str());
deleteKeyCommandShortcut(CommandId::ChangeBrush(), params);
}

KeyPtr KeyboardShortcuts::command(const char* commandName,
const Params& params,
const KeyContext keyContext) const
Expand Down
9 changes: 9 additions & 0 deletions src/app/ui/keyboard_shortcuts.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "app/ui/key.h"
#include "obs/signal.h"

#define KEYBOARD_FILENAME_EXTENSION "aseprite-keys"

class TiXmlElement;

namespace app {
Expand Down Expand Up @@ -43,6 +45,13 @@ namespace app {
void exportFile(const std::string& filename);
void reset();

int findKeyCommandShortcutIndex(const char* commandName,
const Params& params = Params(),
const KeyContext keyContext = KeyContext::Any) const;
bool deleteKeyCommandShortcut(const char* commandName,
const Params& params = Params(),
const KeyContext keyContext = KeyContext::Any) const;
void replaceCustomBrushShortcut(int slot);
KeyPtr command(const char* commandName,
const Params& params = Params(),
const KeyContext keyContext = KeyContext::Any) const;
Expand Down

0 comments on commit 8be3e16

Please sign in to comment.