From 798d6df5ffb1367e7b56a5603183225c0210b3cc Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 5 Sep 2018 13:35:13 -0300 Subject: [PATCH] Add File > Scripts menu --- data/gui.xml | 9 ++- data/scripts/white_to_alpha.lua | 17 ------ data/strings/en.ini | 3 + src/app/CMakeLists.txt | 1 + src/app/app_menus.cpp | 49 +++++++++++++++- src/app/commands/cmd_open_script_folder.cpp | 65 +++++++++++++++++++++ src/app/commands/commands_list.h | 1 + src/ui/menu.cpp | 16 +++++ src/ui/menu.h | 1 + 9 files changed, 137 insertions(+), 25 deletions(-) delete mode 100644 data/scripts/white_to_alpha.lua create mode 100644 src/app/commands/cmd_open_script_folder.cpp diff --git a/data/gui.xml b/data/gui.xml index 95514afe3..185c6fa1e 100644 --- a/data/gui.xml +++ b/data/gui.xml @@ -583,6 +583,10 @@ + + + + @@ -669,11 +673,6 @@ - diff --git a/data/scripts/white_to_alpha.lua b/data/scripts/white_to_alpha.lua deleted file mode 100644 index 7211e0863..000000000 --- a/data/scripts/white_to_alpha.lua +++ /dev/null @@ -1,17 +0,0 @@ --- Aseprite --- Copyright (C) 2015-2018 by David Capello - -local pc = app.pixelColor -local img = app.activeImage - -for y=0,img.height-1 do - for x=0,img.width-1 do - local c = img:getPixel(x, y) - local r = pc.rgbaR(c) - local g = pc.rgbaG(c) - local b = pc.rgbaB(c) - local a = pc.rgbaA(c) - if a > 0 then a = 255 - (r+g+b)/3 end - img:putPixel(x, y, pc.rgba(r, g, b, a)) - end -end diff --git a/data/strings/en.ini b/data/strings/en.ini index b9eaa2c1e..521c544dc 100644 --- a/data/strings/en.ini +++ b/data/strings/en.ini @@ -315,6 +315,7 @@ OpenBrowser = Open Browser OpenFile = Open Sprite OpenGroup = Open/Close Group OpenInFolder = Open In Folder +OpenScriptFolder = Open Script Folder OpenWithApp = Open With Associated Application Options = Preferences PaletteEditor = Switch{0}{1}{2} @@ -646,6 +647,8 @@ file_close_all = Close All file_import_sprite_sheet = &Import Sprite Sheet file_export_sprite_sheet = &Export Sprite Sheet file_repeat_last_export = Repeat &Last Export +file_scripts = Scri&pts +file_open_script_folder = &Open Scripts Folder file_exit = E&xit edit = &Edit edit_undo = &Undo diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 9de0e6a1b..a23f5f939 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -144,6 +144,7 @@ if(ENABLE_SCRIPTING) if(ENABLE_UI) set(scripting_files_ui commands/cmd_developer_console.cpp + commands/cmd_open_script_folder.cpp ui/devconsole_view.cpp) endif() set(scripting_files diff --git a/src/app/app_menus.cpp b/src/app/app_menus.cpp index 2f387277f..e722177b9 100644 --- a/src/app/app_menus.cpp +++ b/src/app/app_menus.cpp @@ -368,6 +368,44 @@ void AppMenus::reload() KeyboardShortcuts::instance()->importFile(fn, KeySource::UserDefined); } + // Add one menu item to run each script from the user scripts/ folder + { + MenuItem* scriptsMenu = dynamic_cast( + m_rootMenu->findItemById("scripts_menu")); +#ifdef ENABLE_SCRIPTING + // Load scripts + ResourceFinder rf; + rf.includeUserDir("scripts/."); + std::string scriptsDir = rf.getFirstOrCreateDefault(); + scriptsDir = base::get_file_path(scriptsDir); + if (base::is_directory(scriptsDir)) { + Command* cmd_run_script = + Commands::instance()->byId(CommandId::RunScript()); + + for (auto fn : base::list_files(scriptsDir)) { + if (base::string_to_lower(base::get_file_extension(fn)) == "lua") { + std::string fullFn = base::join_path(scriptsDir, fn); + if (base::is_file(fullFn)) { + Params params; + params.set("filename", fullFn.c_str()); + auto menuitem = new AppMenuItem( + fn.c_str(), + cmd_run_script, + params); + scriptsMenu->getSubmenu()->addChild(menuitem); + } + } + } + } +#else + // Scripting is not available + if (scriptsMenu) { + delete scriptsMenu; + delete m_rootMenu->findItemById("scripts_menu_separator"); + } +#endif + } + // Create native menus after the default + user defined keyboard // shortcuts are loaded correctly. createNativeMenus(); @@ -485,9 +523,14 @@ Menu* AppMenus::convertXmlelemToMenu(TiXmlElement* elem) Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem) { + const char* id = elem->Attribute("id"); + // is it a ? - if (strcmp(elem->Value(), "separator") == 0) - return new MenuSeparator; + if (strcmp(elem->Value(), "separator") == 0) { + auto item = new MenuSeparator; + if (id) item->setId(id); + return item; + } const char* command_id = elem->Attribute("command"); Command* command = @@ -515,10 +558,10 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem) if (!menuitem) return nullptr; + if (id) menuitem->setId(id); menuitem->processMnemonicFromText(); // Has it a ID? - const char* id = elem->Attribute("id"); if (id) { // Recent list menu if (std::strcmp(id, "recent_list") == 0) { diff --git a/src/app/commands/cmd_open_script_folder.cpp b/src/app/commands/cmd_open_script_folder.cpp new file mode 100644 index 000000000..b99a300a5 --- /dev/null +++ b/src/app/commands/cmd_open_script_folder.cpp @@ -0,0 +1,65 @@ +// Aseprite +// Copyright (C) 2018 David Capello +// +// This program is distributed under the terms of +// the End-User License Agreement for Aseprite. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef ENABLE_SCRIPTING + #error ENABLE_SCRIPTING must be defined +#endif + +#include "app/app.h" +#include "app/commands/command.h" +#include "app/ini_file.h" +#include "app/launcher.h" +#include "base/fs.h" +#include "base/fstream_path.h" + +#include + +namespace app { + +using namespace ui; + +class OpenScriptFolderCommand : public Command { +public: + OpenScriptFolderCommand(); +protected: + void onExecute(Context* context); +}; + +OpenScriptFolderCommand::OpenScriptFolderCommand() + : Command(CommandId::OpenScriptFolder(), CmdUIOnlyFlag) +{ +} + +void OpenScriptFolderCommand::onExecute(Context* context) +{ + std::string path = app::main_config_filename(); + path = base::get_file_path(path); + path = base::join_path(path, "scripts"); + if (!base::is_directory(path)) { + // Create "scripts" folder for first time + base::make_directory(path); + // Create README.txt file + std::ofstream os(FSTREAM_PATH(base::join_path(path, "README.txt"))); + os << "Put your scripts here and restart Aseprite to see them in File > Scripts\n" + << "\n" + << "Scripts are .lua files, you can find more information here:\n" + << "\n" + << " https://github.com/aseprite/api\n" + << "\n"; + } + app::launcher::open_folder(path); +} + +Command* CommandFactory::createOpenScriptFolderCommand() +{ + return new OpenScriptFolderCommand; +} + +} // namespace app diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h index f91135aed..59a145d4a 100644 --- a/src/app/commands/commands_list.h +++ b/src/app/commands/commands_list.h @@ -156,6 +156,7 @@ FOR_EACH_COMMAND(Zoom) #ifdef ENABLE_SCRIPTING #ifdef ENABLE_UI FOR_EACH_COMMAND(DeveloperConsole) + FOR_EACH_COMMAND(OpenScriptFolder) #endif FOR_EACH_COMMAND(RunScript) #endif // ENABLE_SCRIPTING diff --git a/src/ui/menu.cpp b/src/ui/menu.cpp index 776da9911..d48f24e26 100644 --- a/src/ui/menu.cpp +++ b/src/ui/menu.cpp @@ -291,6 +291,22 @@ void Menu::showPopup(const gfx::Point& pos) } +Widget* Menu::findItemById(const char* id) +{ + Widget* result = findChild(id); + if (result) + return result; + for (auto child : children()) { + if (child->type() == kMenuItemWidget) { + result = static_cast(child) + ->getSubmenu()->findItemById(id); + if (result) + return result; + } + } + return nullptr; +} + void Menu::onPaint(PaintEvent& ev) { theme()->paintMenu(ev); diff --git a/src/ui/menu.h b/src/ui/menu.h index 1f5e06dfd..bbbdd6228 100644 --- a/src/ui/menu.h +++ b/src/ui/menu.h @@ -28,6 +28,7 @@ namespace ui { ~Menu(); void showPopup(const gfx::Point& pos); + Widget* findItemById(const char* id); // Returns the MenuItem that has as submenu this menu. MenuItem* getOwnerMenuItem() {