diff --git a/src/audio_karaoke.cpp b/src/audio_karaoke.cpp index 3f871d5b16..69ca14cd0a 100644 --- a/src/audio_karaoke.cpp +++ b/src/audio_karaoke.cpp @@ -63,11 +63,11 @@ AudioKaraoke::AudioKaraoke(wxWindow *parent, agi::Context *c) { using std::bind; - cancel_button = new wxBitmapButton(this, -1, GETIMAGE(kara_split_cancel_16)); + cancel_button = new wxBitmapButton(this, -1, GETBUNDLE(kara_split_cancel, 16)); cancel_button->SetToolTip(_("Discard all uncommitted splits")); cancel_button->Bind(wxEVT_BUTTON, bind(&AudioKaraoke::CancelSplit, this)); - accept_button = new wxBitmapButton(this, -1, GETIMAGE(kara_split_accept_16)); + accept_button = new wxBitmapButton(this, -1, GETBUNDLE(kara_split_accept, 16)); accept_button->SetToolTip(_("Commit splits")); accept_button->Bind(wxEVT_BUTTON, bind(&AudioKaraoke::AcceptSplit, this)); diff --git a/src/command/command.h b/src/command/command.h index dd672e664c..91272e7679 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -37,12 +37,8 @@ namespace agi { struct Context; } #define STR_HELP(a) wxString StrHelp() const override { return _(a); } #define CMD_TYPE(a) int Type() const override { using namespace cmd; return a; } -#define CMD_ICON(icon) wxBitmap Icon(int size, double scale = 1.0, wxLayoutDirection dir = wxLayout_LeftToRight) const override { \ - if (size * scale >= 64) return GETIMAGEDIR(icon##_64, scale, dir); \ - if (size * scale >= 48) return GETIMAGEDIR(icon##_48, scale, dir); \ - if (size * scale >= 32) return GETIMAGEDIR(icon##_32, scale, dir); \ - if (size * scale >= 24) return GETIMAGEDIR(icon##_24, scale, dir); \ - return GETIMAGEDIR(icon##_16, scale, dir); \ +#define CMD_ICON(icon) wxBitmapBundle Icon(int height, wxLayoutDirection dir = wxLayout_LeftToRight) const override { \ + return GETBUNDLEDIR(icon, height, dir); \ } #define COMMAND_GROUP(cname, cmdname, menu, disp, help) \ @@ -113,7 +109,7 @@ DEFINE_EXCEPTION(CommandNotFound, CommandError); /// Request icon. /// @param size Icon size. - virtual wxBitmap Icon(int size, double scale = 1.0, wxLayoutDirection = wxLayout_LeftToRight) const { return wxBitmap{}; } + virtual wxBitmapBundle Icon(int height = 16, wxLayoutDirection = wxLayout_LeftToRight) const { return wxBitmapBundle{}; } /// Command function virtual void operator()(agi::Context *c)=0; diff --git a/src/dialog_attachments.cpp b/src/dialog_attachments.cpp index c8e3e27aec..9edd13bded 100644 --- a/src/dialog_attachments.cpp +++ b/src/dialog_attachments.cpp @@ -68,7 +68,7 @@ DialogAttachments::DialogAttachments(wxWindow *parent, AssFile *ass) : d(parent, -1, _("Attachment List")) , ass(ass) { - d.SetIcon(GETICON(attach_button_16)); + d.SetIcons(GETICONS(attach_button)); listView = new wxListView(&d, -1, wxDefaultPosition, wxSize(500, 200)); UpdateList(); diff --git a/src/dialog_automation.cpp b/src/dialog_automation.cpp index dfa73c4000..82acaff922 100644 --- a/src/dialog_automation.cpp +++ b/src/dialog_automation.cpp @@ -110,7 +110,7 @@ DialogAutomation::DialogAutomation(agi::Context *c) , global_manager(config::global_scripts) , global_scripts_changed(global_manager->AddScriptChangeListener(&DialogAutomation::RebuildList, this)) { - SetIcon(GETICON(automation_toolbutton_16)); + SetIcons(GETICONS(automation_toolbutton)); // create main controls list = new wxListView(this, -1, wxDefaultPosition, wxSize(600, 175), wxLC_REPORT|wxLC_SINGLE_SEL); diff --git a/src/dialog_autosave.cpp b/src/dialog_autosave.cpp index b11dbfb644..72a1d30535 100644 --- a/src/dialog_autosave.cpp +++ b/src/dialog_autosave.cpp @@ -65,7 +65,7 @@ class DialogAutosave { DialogAutosave::DialogAutosave(wxWindow *parent) : d(parent, -1, _("Open autosave file"), wxDefaultPosition, wxSize(800, 350), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - d.SetIcon(GETICON(open_toolbutton_16)); + d.SetIcons(GETICONS(open_toolbutton)); wxSizer *files_box = new wxStaticBoxSizer(wxVERTICAL, &d, _("Files")); file_list = new wxListBox(&d, -1); diff --git a/src/dialog_colorpicker.cpp b/src/dialog_colorpicker.cpp index 7a2dc6a966..80612bbe4f 100644 --- a/src/dialog_colorpicker.cpp +++ b/src/dialog_colorpicker.cpp @@ -585,7 +585,7 @@ DialogColorPicker::DialogColorPicker(wxWindow *parent, agi::Color initial_color, preview_box = new wxStaticBitmap(this, -1, wxBitmap(40, 40, 24), wxDefaultPosition, wxSize(40, 40), STATIC_BORDER_FLAG); recent_box = new ColorPickerRecent(this, 8, 4, 16); - eyedropper_bitmap = GETIMAGE(eyedropper_tool_24); + eyedropper_bitmap = GETBUNDLE(eyedropper_tool, 24).GetBitmapFor(this); eyedropper_bitmap.SetMask(new wxMask(eyedropper_bitmap, wxColour(255, 0, 255))); screen_dropper_icon = new wxStaticBitmap(this, -1, eyedropper_bitmap, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER); screen_dropper = new ColorPickerScreenDropper(this, 7, 7, 8); diff --git a/src/dialog_dummy_video.cpp b/src/dialog_dummy_video.cpp index 16260c72e2..3c67a6fcc9 100644 --- a/src/dialog_dummy_video.cpp +++ b/src/dialog_dummy_video.cpp @@ -102,7 +102,7 @@ wxComboBox *resolution_shortcuts(wxWindow *parent, int width, int height) { DialogDummyVideo::DialogDummyVideo(wxWindow *parent) : d(parent, -1, _("Dummy video options")) { - d.SetIcon(GETICON(use_dummy_video_menu_16)); + d.SetIcons(GETICONS(use_dummy_video_menu)); auto res_sizer = new wxBoxSizer(wxHORIZONTAL); res_sizer->Add(spin_ctrl(&d, 1, 10000, &width), wxSizerFlags(1).Expand()); diff --git a/src/dialog_export.cpp b/src/dialog_export.cpp index c04099c697..e0b3e848f5 100644 --- a/src/dialog_export.cpp +++ b/src/dialog_export.cpp @@ -102,7 +102,7 @@ DialogExport::DialogExport(agi::Context *c) , c(c) , exporter(c) { - d.SetIcon(GETICON(export_menu_16)); + d.SetIcons(GETICONS(export_menu)); d.SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY); std::vector filters = exporter.GetAllFilterNames(); diff --git a/src/dialog_fonts_collector.cpp b/src/dialog_fonts_collector.cpp index 13fff87961..acff8a04c4 100644 --- a/src/dialog_fonts_collector.cpp +++ b/src/dialog_fonts_collector.cpp @@ -227,7 +227,7 @@ DialogFontsCollector::DialogFontsCollector(agi::Context *c) , subs(c->ass.get()) , path(*c->path) { - SetIcon(GETICON(font_collector_button_16)); + SetIcons(GETICONS(font_collector_button)); wxString modes[] = { _("Check fonts for availability") diff --git a/src/dialog_jumpto.cpp b/src/dialog_jumpto.cpp index 8503240f8b..1076c5f200 100644 --- a/src/dialog_jumpto.cpp +++ b/src/dialog_jumpto.cpp @@ -68,7 +68,7 @@ DialogJumpTo::DialogJumpTo(agi::Context *c) , c(c) , jumpframe(c->videoController->GetFrameN()) { - d.SetIcon(GETICON(jumpto_button_16)); + d.SetIcons(GETICONS(jumpto_button)); auto LabelFrame = new wxStaticText(&d, -1, _("Frame: ")); auto LabelTime = new wxStaticText(&d, -1, _("Time: ")); diff --git a/src/dialog_kara_timing_copy.cpp b/src/dialog_kara_timing_copy.cpp index 115a860b8d..e2abbc5f2c 100644 --- a/src/dialog_kara_timing_copy.cpp +++ b/src/dialog_kara_timing_copy.cpp @@ -385,7 +385,7 @@ DialogKanjiTimer::DialogKanjiTimer(agi::Context *c) : wxDialog(c->parent, -1, _("Kanji timing")) , subs(c->ass.get()) { - SetIcon(GETICON(kara_timing_copier_16)); + SetIcons(GETICONS(kara_timing_copier)); wxSizer *DisplayBoxSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Text")); wxSizer *StylesBoxSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Styles")); diff --git a/src/dialog_properties.cpp b/src/dialog_properties.cpp index 658e6ccd2a..8e8eb7c5f5 100644 --- a/src/dialog_properties.cpp +++ b/src/dialog_properties.cpp @@ -89,7 +89,7 @@ DialogProperties::DialogProperties(agi::Context *c) : d(c->parent, -1, _("Script Properties")) , c(c) { - d.SetIcon(GETICON(properties_toolbutton_16)); + d.SetIcons(GETICONS(properties_toolbutton)); // Button sizer // Create buttons first. See: diff --git a/src/dialog_resample.cpp b/src/dialog_resample.cpp index e161caef20..514eb46990 100644 --- a/src/dialog_resample.cpp +++ b/src/dialog_resample.cpp @@ -90,7 +90,7 @@ DialogResample::DialogResample(agi::Context *c, ResampleSettings &settings) : d(c->parent, -1, _("Resample Resolution")) , c(c) { - d.SetIcon(GETICON(resample_toolbutton_16)); + d.SetIcons(GETICONS(resample_toolbutton)); memset(&settings, 0, sizeof(settings)); c->ass->GetResolution(script_w, script_h); diff --git a/src/dialog_selection.cpp b/src/dialog_selection.cpp index 1f821c80a4..d0e596ca39 100644 --- a/src/dialog_selection.cpp +++ b/src/dialog_selection.cpp @@ -106,7 +106,7 @@ DialogSelection::DialogSelection(agi::Context *c) : wxDialog (c->parent, -1, _("Select"), wxDefaultPosition, wxDefaultSize, wxCAPTION) , con(c) { - SetIcon(GETICON(select_lines_button_16)); + SetIcons(GETICONS(select_lines_button)); wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/dialog_shift_times.cpp b/src/dialog_shift_times.cpp index 902ec09696..91d569f210 100644 --- a/src/dialog_shift_times.cpp +++ b/src/dialog_shift_times.cpp @@ -137,7 +137,7 @@ DialogShiftTimes::DialogShiftTimes(agi::Context *context) , timecodes_loaded_slot(context->project->AddTimecodesListener(&DialogShiftTimes::OnTimecodesLoaded, this)) , selected_set_changed_slot(context->selectionController->AddSelectionListener(&DialogShiftTimes::OnSelectedSetChanged, this)) { - SetIcon(GETICON(shift_times_toolbutton_16)); + SetIcons(GETICONS(shift_times_toolbutton)); // Create controls shift_by_time = new wxRadioButton(this, -1, _("&Time: "), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); diff --git a/src/dialog_spellchecker.cpp b/src/dialog_spellchecker.cpp index 3deac9ca2d..cfbc4d1074 100644 --- a/src/dialog_spellchecker.cpp +++ b/src/dialog_spellchecker.cpp @@ -104,7 +104,7 @@ DialogSpellChecker::DialogSpellChecker(agi::Context *context) , context(context) , spellchecker(SpellCheckerFactory::GetSpellChecker()) { - SetIcon(GETICON(spellcheck_toolbutton_16)); + SetIcons(GETICONS(spellcheck_toolbutton)); wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/dialog_style_editor.cpp b/src/dialog_style_editor.cpp index 941d9bdc07..0f60e956af 100644 --- a/src/dialog_style_editor.cpp +++ b/src/dialog_style_editor.cpp @@ -141,7 +141,7 @@ DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Con work = std::make_unique(*style); - SetIcon(GETICON(style_toolbutton_16)); + SetIcons(GETICONS(style_toolbutton)); auto add_with_label = [&](wxSizer *sizer, wxString const& label, wxWindow *ctrl) { sizer->Add(new wxStaticText(this, -1, label), wxSizerFlags().Center().Border(wxLEFT | wxRIGHT)); diff --git a/src/dialog_style_manager.cpp b/src/dialog_style_manager.cpp index 46249eafd7..fa0b07cd52 100644 --- a/src/dialog_style_manager.cpp +++ b/src/dialog_style_manager.cpp @@ -173,7 +173,7 @@ class DialogStyleManager final : public wxDialog { DialogStyleManager(agi::Context *context); }; -wxBitmapButton *add_bitmap_button(wxWindow *parent, wxSizer *sizer, wxBitmap const& img, wxString const& tooltip) { +wxBitmapButton *add_bitmap_button(wxWindow *parent, wxSizer *sizer, wxBitmapBundle const& img, wxString const& tooltip) { wxBitmapButton *btn = new wxBitmapButton(parent, -1, img); btn->SetToolTip(tooltip); sizer->Add(btn, wxSizerFlags().Expand()); @@ -184,11 +184,11 @@ wxSizer *make_move_buttons(wxWindow *parent, wxButton **up, wxButton **down, wxB wxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->AddStretchSpacer(1); - *up = add_bitmap_button(parent, sizer, GETIMAGE(arrow_up_24), _("Move style up")); - *down = add_bitmap_button(parent, sizer, GETIMAGE(arrow_down_24), _("Move style down")); - *top = add_bitmap_button(parent, sizer, GETIMAGE(arrow_up_stop_24), _("Move style to top")); - *bottom = add_bitmap_button(parent, sizer, GETIMAGE(arrow_down_stop_24), _("Move style to bottom")); - *sort = add_bitmap_button(parent, sizer, GETIMAGE(arrow_sort_24), _("Sort styles alphabetically")); + *up = add_bitmap_button(parent, sizer, GETBUNDLE(arrow_up, 24), _("Move style up")); + *down = add_bitmap_button(parent, sizer, GETBUNDLE(arrow_down, 24), _("Move style down")); + *top = add_bitmap_button(parent, sizer, GETBUNDLE(arrow_up_stop, 24), _("Move style to top")); + *bottom = add_bitmap_button(parent, sizer, GETBUNDLE(arrow_down_stop, 24), _("Move style to bottom")); + *sort = add_bitmap_button(parent, sizer, GETBUNDLE(arrow_sort, 24), _("Sort styles alphabetically")); sizer->AddStretchSpacer(1); return sizer; @@ -266,7 +266,7 @@ DialogStyleManager::DialogStyleManager(agi::Context *context) })) { using std::bind; - SetIcon(GETICON(style_toolbutton_16)); + SetIcons(GETICONS(style_toolbutton)); // Catalog wxSizer *CatalogBox = new wxStaticBoxSizer(wxHORIZONTAL,this,_("Catalog of available storages")); diff --git a/src/dialog_styling_assistant.cpp b/src/dialog_styling_assistant.cpp index af96f8f00c..b5297e8dfd 100644 --- a/src/dialog_styling_assistant.cpp +++ b/src/dialog_styling_assistant.cpp @@ -54,7 +54,7 @@ DialogStyling::DialogStyling(agi::Context *context) , c(context) , active_line_connection(context->selectionController->AddActiveLineListener(&DialogStyling::OnActiveLineChanged, this)) { - SetIcon(GETICON(styling_toolbutton_16)); + SetIcons(GETICONS(styling_toolbutton)); wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); wxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL); diff --git a/src/dialog_timing_processor.cpp b/src/dialog_timing_processor.cpp index 78fe1d8780..87ceda3234 100644 --- a/src/dialog_timing_processor.cpp +++ b/src/dialog_timing_processor.cpp @@ -141,7 +141,7 @@ DialogTimingProcessor::DialogTimingProcessor(agi::Context *c) { using std::bind; - d.SetIcon(GETICON(timing_processor_toolbutton_16)); + d.SetIcons(GETICONS(timing_processor_toolbutton)); // Read options leadIn = OPT_GET("Tool/Timing Post Processor/Lead/IN")->GetInt(); diff --git a/src/dialog_translation.cpp b/src/dialog_translation.cpp index 1396ee7046..3b6119a400 100644 --- a/src/dialog_translation.cpp +++ b/src/dialog_translation.cpp @@ -68,7 +68,7 @@ DialogTranslation::DialogTranslation(agi::Context *c) , active_line(c->selectionController->GetActiveLine()) , line_count(c->ass->Events.size()) { - SetIcon(GETICON(translation_toolbutton_16)); + SetIcons(GETICONS(translation_toolbutton)); wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); diff --git a/src/hotkey_data_view_model.cpp b/src/hotkey_data_view_model.cpp index 503369b671..9dc25f901e 100644 --- a/src/hotkey_data_view_model.cpp +++ b/src/hotkey_data_view_model.cpp @@ -84,11 +84,9 @@ class HotkeyModelCombo final : public HotkeyModelItem { if (col == 0) variant = to_wx(combo.Str()); else if (col == 1) { - wxIcon icon; + wxBitmapBundle icon; try { - auto icon_bmp = cmd::get(combo.CmdName())->Icon(16); - if (icon_bmp.IsOk()) - icon.CopyFromBitmap(icon_bmp); + icon = cmd::get(combo.CmdName())->Icon(); } catch (agi::Exception const&) { // Just use no icon; error is reported in the description column diff --git a/src/libresrc/libresrc.cpp b/src/libresrc/libresrc.cpp index 0150bb6a1a..5101377109 100644 --- a/src/libresrc/libresrc.cpp +++ b/src/libresrc/libresrc.cpp @@ -14,19 +14,21 @@ #include "libresrc.h" +#include + #include +#include #include +#include #include #include #include -wxBitmap libresrc_getimage(const unsigned char *buff, size_t size, double scale, int dir) { +wxBitmap libresrc_getimage(const unsigned char *buff, size_t size, int dir) { wxMemoryInputStream mem(buff, size); if (dir != wxLayout_RightToLeft) - // Since wxWidgets 3.1.0, there is an undocumented third parameter in the ctor of wxBitmap from wxImage - // This "scale" parameter sets the logical scale factor of the created wxBitmap - return wxBitmap(wxImage(mem), wxBITMAP_SCREEN_DEPTH, scale); - return wxBitmap(wxImage(mem).Mirror(), wxBITMAP_SCREEN_DEPTH, scale); + return wxBitmap(wxImage(mem)); + return wxBitmap(wxImage(mem).Mirror()); } wxIcon libresrc_geticon(const unsigned char *buff, size_t size) { @@ -35,3 +37,42 @@ wxIcon libresrc_geticon(const unsigned char *buff, size_t size) { icon.CopyFromBitmap(wxBitmap(wxImage(mem))); return icon; } + +wxBitmapBundle libresrc_getbitmapbundle(const LibresrcBlob *images, size_t count, int height, int dir) { + // This function should only ever be called on the GUI thread but declaring this thread_local is the safe way + thread_local std::map, wxBitmapBundle> cache; + auto key = std::make_tuple(images, height, dir); + + if (auto cached = cache.find(key); cached != cache.end()) { + return cached->second; + } + + wxVector bitmaps; + bitmaps.reserve(count); + for (size_t i = 0; i < count; i++) { + bitmaps.push_back(libresrc_getimage(images[i].data, images[i].size, dir)); + bitmaps.back().SetScaleFactor(double(images[i].scale) / height); + } + + auto bundle = wxBitmapBundle::FromBitmaps(bitmaps); + cache[key] = bundle; + + return bundle; +} + +wxIconBundle libresrc_geticonbundle(const LibresrcBlob *images, size_t count) { + thread_local std::map cache; + + if (auto cached = cache.find(images); cached != cache.end()) { + return cached->second; + } + + wxIconBundle bundle; + for (size_t i = 0; i < count; i++) { + bundle.AddIcon(libresrc_geticon(images[i].data, images[i].size)); + } + + cache[images] = bundle; + + return bundle; +} diff --git a/src/libresrc/libresrc.h b/src/libresrc/libresrc.h index aa6d9b468d..8866b43b72 100644 --- a/src/libresrc/libresrc.h +++ b/src/libresrc/libresrc.h @@ -15,18 +15,36 @@ #include #include +struct LibresrcBlob { + const unsigned char *data; + size_t size; + int scale; +}; + #include "bitmap.h" #include "default_config.h" #include class wxBitmap; +class wxBitmapBundle; class wxIcon; +class wxIconBundle; -wxBitmap libresrc_getimage(const unsigned char *image, size_t size, double scale=1.0, int dir=0); +wxBitmap libresrc_getimage(const unsigned char *image, size_t size, int dir=0); wxIcon libresrc_geticon(const unsigned char *image, size_t size); #define GETIMAGE(a) libresrc_getimage(a, sizeof(a)) -#define GETIMAGEDIR(a, s, d) libresrc_getimage(a, sizeof(a), s, d) -#define GETICON(a) libresrc_geticon(a, sizeof(a)) #define GET_DEFAULT_CONFIG(a) std::string_view(reinterpret_cast(a), sizeof(a)) + +// height is the desired displayed height of the bitmap bundle in DIP. +// Having to specify this when constructing the bitmap is slightly awkward, +// but wxWidgets doesn't allow you to scale a wxBitmapBundle after creating it, +// so the scale has to be set for the individual bitmaps before constructing it. +wxBitmapBundle libresrc_getbitmapbundle(const LibresrcBlob *images, size_t count, int height, int dir=0); + +wxIconBundle libresrc_geticonbundle(const LibresrcBlob *images, size_t count); + +#define GETBUNDLE(a, h) libresrc_getbitmapbundle(a, sizeof(a) / sizeof(*a), h) +#define GETBUNDLEDIR(a, h, d) libresrc_getbitmapbundle(a, sizeof(a) / sizeof(*a), h, d) +#define GETICONS(a) libresrc_geticonbundle(a, sizeof(a) / sizeof(*a)) diff --git a/src/menu.cpp b/src/menu.cpp index 7d638f3aa4..e627bdc342 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -200,7 +200,7 @@ class CommandManager { #ifndef __WXMAC__ /// @todo Maybe make this a configuration option instead? if (kind == wxITEM_NORMAL) - item->SetBitmap(co->Icon(16)); + item->SetBitmap(co->Icon()); #endif parent->Append(item); items.push_back(co->name()); diff --git a/src/preferences.cpp b/src/preferences.cpp index 2bd6e533d1..7844639b3d 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -709,7 +709,7 @@ void Preferences::OnResetDefault(wxCommandEvent&) { } Preferences::Preferences(wxWindow *parent): wxDialog(parent, -1, _("Preferences"), wxDefaultPosition, wxSize(-1, -1), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { - SetIcon(GETICON(options_button_16)); + SetIcons(GETICONS(options_button)); book = new wxTreebook(this, -1, wxDefaultPosition, wxDefaultSize); General(book, this); diff --git a/src/subs_edit_box.cpp b/src/subs_edit_box.cpp index 147630b982..768daf4e18 100644 --- a/src/subs_edit_box.cpp +++ b/src/subs_edit_box.cpp @@ -281,7 +281,7 @@ TimeEdit *SubsEditBox::MakeTimeCtrl(wxString const& tooltip, TimeField field) { void SubsEditBox::MakeButton(const char *cmd_name) { cmd::Command *command = cmd::get(cmd_name); - wxBitmapButton *btn = new wxBitmapButton(this, -1, command->Icon(16, GetContentScaleFactor())); + wxBitmapButton *btn = new wxBitmapButton(this, -1, command->Icon()); ToolTipManager::Bind(btn, command->StrHelp(), "Subtitle Edit Box", cmd_name); middle_right_sizer->Add(btn, wxSizerFlags().Expand()); diff --git a/src/toggle_bitmap.cpp b/src/toggle_bitmap.cpp index 71de3ca576..312a8fb16a 100644 --- a/src/toggle_bitmap.cpp +++ b/src/toggle_bitmap.cpp @@ -45,7 +45,7 @@ ToggleBitmap::ToggleBitmap(wxWindow *parent, agi::Context *context, const char * : wxControl(parent, -1, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER) , context(context) , command(*cmd::get(cmd_name)) -, img(command.Icon(icon_size)) +, img(command.Icon(icon_size).GetBitmapFor(this)) { int w = size.GetWidth() != -1 ? size.GetWidth() : img.GetWidth(); int h = size.GetHeight() != -1 ? size.GetHeight() : img.GetHeight(); diff --git a/src/toolbar.cpp b/src/toolbar.cpp index 78a7caffcc..bbaffe38bf 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -136,8 +136,7 @@ namespace { flags & cmd::COMMAND_TOGGLE ? wxITEM_CHECK : wxITEM_NORMAL; - wxBitmap const& bitmap = command->Icon(icon_size, GetContentScaleFactor(), GetLayoutDirection()); - AddTool(TOOL_ID_BASE + commands.size(), command->StrDisplay(context), wxBitmapBundle(bitmap), command->GetTooltip(ht_context), kind); + AddTool(TOOL_ID_BASE + commands.size(), command->StrDisplay(context), command->Icon(icon_size, GetLayoutDirection()), command->GetTooltip(ht_context), kind); commands.push_back(command); needs_onidle = needs_onidle || flags != cmd::COMMAND_NORMAL; diff --git a/src/visual_tool_drag.cpp b/src/visual_tool_drag.cpp index 16ab74cc5b..c81c98e682 100644 --- a/src/visual_tool_drag.cpp +++ b/src/visual_tool_drag.cpp @@ -41,8 +41,6 @@ static const DraggableFeatureType DRAG_ORIGIN = DRAG_BIG_TRIANGLE; static const DraggableFeatureType DRAG_START = DRAG_BIG_SQUARE; static const DraggableFeatureType DRAG_END = DRAG_BIG_CIRCLE; -#define ICON(name) (OPT_GET("App/Toolbar Icon Size")->GetInt() == 16 ? GETIMAGE(name ## _16) : GETIMAGE(name ## _24)) - VisualToolDrag::VisualToolDrag(VideoDisplay *parent, agi::Context *context) : VisualTool(parent, context) { @@ -54,7 +52,7 @@ VisualToolDrag::VisualToolDrag(VideoDisplay *parent, agi::Context *context) void VisualToolDrag::SetToolbar(wxToolBar *tb) { toolbar = tb; toolbar->AddSeparator(); - toolbar->AddTool(-1, _("Toggle between \\move and \\pos"), ICON(visual_move_conv_move)); + toolbar->AddTool(-1, _("Toggle between \\move and \\pos"), GETBUNDLE(visual_move_conv_move, OPT_GET("App/Toolbar Icon Size")->GetInt())); toolbar->Realize(); toolbar->Show(true); @@ -71,8 +69,9 @@ void VisualToolDrag::UpdateToggleButtons() { if (to_move == button_is_move) return; + int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt(); toolbar->SetToolNormalBitmap(toolbar->GetToolByPos(1)->GetId(), - to_move ? ICON(visual_move_conv_move) : ICON(visual_move_conv_pos)); + to_move ? GETBUNDLE(visual_move_conv_move, icon_size) : GETBUNDLE(visual_move_conv_pos, icon_size)); button_is_move = to_move; } diff --git a/tools/respack.py b/tools/respack.py index 9952b5089d..7b9afba285 100755 --- a/tools/respack.py +++ b/tools/respack.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import sys, os +from collections import defaultdict manifestfile, cppfile, hfile, sourcepath = sys.argv[1:] @@ -33,6 +34,7 @@ with open(cppfile, 'w') as cpp: cpp.write('#include "libresrc.h"\n') with open(hfile, 'w') as h: + groups = defaultdict(list) for k in files: with open(files[k], 'rb') as f: @@ -42,3 +44,12 @@ name = os.path.splitext(os.path.basename(k))[0] cpp.write('const unsigned char {}[] = {{{}}};\n'.format(name, datastr)) h.write('extern const unsigned char {}[{}];\n'.format(name, len(data))) + + if name.split('_')[-1].isnumeric(): + groups['_'.join(name.split('_')[:-1])].append(name) + + if groups: + h.write('\n') + + for group in sorted(groups): + h.write('const LibresrcBlob {}[] = {{{}}};\n'.format(group, ', '.join('{{{}, sizeof({}), {}}}'.format(file, file, file.split('_')[-1]) for file in groups[group])))