DarkMode for MSW (#6632)

* MSW specific: Dark Mode: First implementation

* Use menu instead of NoteBook

* Implemented MessageDialog
+ Fixed DarkMode for all dialogs and ColorPicker

* MSW DarkMode: Added missed updates for the switching between modes

* MSW DarkMode: Updated all existed context menus after switching of the mode
+ Added markers for the menu item witch is related to the selected tab

* Used wxFrame instead of wxDialog for SettingsDialog
(this change allow us to use menu bar in SettingsDialog)

+ fix for #6548 - Prusa Slicer 2.3.1 not activating non-modal settings window if settings window is minimized

* Implemented "Always use Dark mode colors" preference option

* Fixes for non_MSW build

* Next fixes for non-MSW builds

* Preferences: Fixed selection of the Settings Layout for non-MSW platforms
+ Updated DarkMode for colorpickers

* Windows DarkMode next fixes

* MSWDarkMode: Suppress to use system color to the PrusaSlicer
Select "Preferences -> Use Dark color mode (experimental)" to allow dark mode for the application

* Fixed MSW build

* MSWDarkMode: Upadteed color mode for ExtruderSequenceDialog and for dialogs related to the DoubleSlider

* Implemented Auto recreation of the PrusaSlicer when color mode is changed.

* Preferences: Added option "Set settings tabs as menu items (experimental)"
This commit is contained in:
Oleksandra Yushchenko 2021-06-18 19:46:04 +02:00 committed by GitHub
parent 65f440c2ba
commit fd071421cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 2011 additions and 443 deletions

View file

@ -138,11 +138,11 @@ std::map<std::string, std::string> SettingsFactory::CATEGORY_ICON =
{ L("Hollowing") , "hollowing" }
};
wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name)
wxBitmap SettingsFactory::get_category_bitmap(const std::string& category_name, bool menu_bmp /*= true*/)
{
if (CATEGORY_ICON.find(category_name) == CATEGORY_ICON.end())
return wxNullBitmap;
return create_scaled_bitmap(CATEGORY_ICON.at(category_name));
return menu_bmp ? create_menu_bitmap(CATEGORY_ICON.at(category_name)) : create_scaled_bitmap(CATEGORY_ICON.at(category_name));
}
@ -206,6 +206,34 @@ static void get_full_settings_hierarchy(FullSettingsHierarchy& settings_menu, co
}
}
static int GetSelectedChoices( wxArrayInt& selections,
const wxString& message,
const wxString& caption,
const wxArrayString& choices)
{
#ifdef _WIN32
wxMultiChoiceDialog dialog(nullptr, message, caption, choices);
wxGetApp().UpdateDlgDarkUI(&dialog);
// call this even if selections array is empty and this then (correctly)
// deselects the first item which is selected by default
dialog.SetSelections(selections);
if (dialog.ShowModal() != wxID_OK)
{
// NB: intentionally do not clear the selections array here, the caller
// might want to preserve its original contents if the dialog was
// cancelled
return -1;
}
selections = dialog.GetSelections();
return static_cast<int>(selections.GetCount());
#else
return wxGetSelectedChoices(selections, message, caption, choices);
#endif
}
static wxMenu* create_settings_popupmenu(wxMenu* parent_menu, const bool is_object_settings, wxDataViewItem item/*, ModelConfig& config*/)
{
wxMenu* menu = new wxMenu;
@ -236,7 +264,7 @@ static wxMenu* create_settings_popupmenu(wxMenu* parent_menu, const bool is_obje
}
if (!category_options.empty() &&
wxGetSelectedChoices(selections, _L("Select showing settings"), category_name, names) != -1) {
GetSelectedChoices(selections, _L("Select showing settings"), category_name, names) != -1) {
for (auto sel : selections)
category_options[sel].second = true;
}
@ -374,7 +402,7 @@ std::vector<wxBitmap> MenuFactory::get_volume_bitmaps()
std::vector<wxBitmap> volume_bmps;
volume_bmps.reserve(ADD_VOLUME_MENU_ITEMS.size());
for (auto item : ADD_VOLUME_MENU_ITEMS)
volume_bmps.push_back(create_scaled_bitmap(item.second));
volume_bmps.push_back(create_menu_bitmap(item.second));
return volume_bmps;
}
@ -542,7 +570,7 @@ wxMenuItem* MenuFactory::append_menu_item_settings(wxMenu* menu_)
// Add full settings list
auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name);
menu_item->SetBitmap(create_scaled_bitmap("cog"));
menu_item->SetBitmap(create_menu_bitmap("cog"));
menu_item->SetSubMenu(create_settings_popupmenu(menu, is_object_settings, item));
return menu->Append(menu_item);
@ -702,7 +730,10 @@ void MenuFactory::append_menu_item_change_extruder(wxMenu* menu)
}
menu->AppendSubMenu(extruder_selection_menu, name);
append_submenu(menu, extruder_selection_menu, wxID_ANY, name, _L("Use another extruder"),
"edit_uni"/* : "change_extruder"*/, []() {return true; }, GUI::wxGetApp().plater());
// menu->AppendSubMenu(extruder_selection_menu, name);
}
void MenuFactory::append_menu_item_scale_selection_to_fit_print_volume(wxMenu* menu)
@ -1046,5 +1077,43 @@ void MenuFactory::msw_rescale()
msw_rescale_menu(dynamic_cast<wxMenu*>(menu));
}
#ifdef _WIN32
// For this class is used code from stackoverflow:
// https://stackoverflow.com/questions/257288/is-it-possible-to-write-a-template-to-check-for-a-functions-existence
// Using this code we can to inspect of an existence of IsWheelInverted() function in class T
template <typename T>
class menu_has_update_def_colors
{
typedef char one;
struct two { char x[2]; };
template <typename C> static one test(decltype(&C::UpdateDefColors));
template <typename C> static two test(...);
public:
static constexpr bool value = sizeof(test<T>(0)) == sizeof(char);
};
template<typename T>
static void update_menu_item_def_colors(T* item)
{
if constexpr (menu_has_update_def_colors<wxMenuItem>::value) {
item->UpdateDefColors();
}
}
#endif
void MenuFactory::sys_color_changed()
{
for (MenuWithSeparators* menu : { &m_object_menu, &m_sla_object_menu, &m_part_menu, &m_default_menu }) {
msw_rescale_menu(dynamic_cast<wxMenu*>(menu));// msw_rescale_menu updates just icons, so use it
#ifdef _WIN32
// but under MSW we have to update item's bachground color
for (wxMenuItem* item : menu->GetMenuItems())
update_menu_item_def_colors(item);
#endif
}
}
} //namespace GUI
} //namespace Slic3r