Merge branch 'dk_tips'

This commit is contained in:
David Kocik 2021-08-10 14:53:14 +02:00
commit 60a818852e
7 changed files with 215 additions and 130 deletions

View File

@ -40,13 +40,13 @@
# hypertext_type = gallery
#
#
# Each notification can have disabled and preferred modes and techs - divided by ;
# preferred_mode = simple
# disabled_mode = advanced; expert
# preferred_tech = SLA
# disabled_tech = FFF; MMU
# Algorithm shows hint only if in preffered mode / tech.
# Algorithm shows hint only if not in disabled mode / tech.
# Each notification can have disabled and enabled modes and techs - divided by ; and space
# enabled_tags = ...
# disabled_tags = ...
# supported tags are: simple; advanced; expert; FFF; MMU; SLA
# FFF is affirmative for both one or more extruder printers.
# Algorithm shows hint only if ALL enabled tags are affirmative. (so never do enabled_tags = FFF; SLA;)
# Algorithm shows hint only if not in all disabled tags.
# if there are both disabled and preferred, only preferred that are not in disabled are valid.
@ -70,7 +70,7 @@ hypertext_type = settings
hypertext_settings_opt = infill_every_layers
hypertext_settings_type = 1
hypertext_settings_category = Infill
disabled_modes = SLA; simple
disabled_tags = SLA; simple
[hint:Hiding sidebar]
text = Hiding sidebar\nDid you know that you can hide the right sidebar using the shortcut <b>Shift+Tab</b>? You can also enable the icon for this from the<a>Preferences.</a>
@ -81,7 +81,7 @@ hypertext_preferences_page = 2
text = Variable layer height\nDid you know that you can print different regions of your model with a different layer height and smooth the transitions between them? Try the<a>Variable layer height tool.</a>(Not available for SLA printers.)
hypertext_type = plater
hypertext_plater_item = layersediting
disabled_modes = SLA
disabled_tags = SLA
[hint:Undo/redo history]
text = Undo/redo history\nDid you know that you can right-click the<a>undo/redo arrows</a>to see the history of changes and to undo or redo several actions at once?
@ -94,12 +94,12 @@ hypertext_type = plater
hypertext_plater_item = arrange
[hint:Reload from disk]
text = Reload from disk\nDid you know that if you created a newer version of your model, you can simply reload it in PrusaSlicer? Right-click the model in the 3D view and choose Reload from disk. Read more in the<a>documentation.</a>
text = Reload from disk\nDid you know that if you created a newer version of your model, you can simply reload it in PrusaSlicer? Right-click the model in the 3D view and choose Reload from disk. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/reload-from-disk_120427
[hint:Different layer height for each model]
text = Different layer height for each model\nDid you know that you can print each model on the plater with a different layer height? Right-click the model in the 3D view, choose Layers and Perimeters and adjust the values in the right panel. Read more in the<a>documentation.</a>
text = Different layer height for each model\nDid you know that you can print each model on the plater with a different layer height? Right-click the model in the 3D view, choose Layers and Perimeters and adjust the values in the right panel. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/per-model-settings_1674
@ -109,7 +109,7 @@ hypertext_type = settings
hypertext_settings_opt = solid_infill_below_area
hypertext_settings_type = 1
hypertext_settings_category = Infill
disabled_modes = SLA; simple; advanced
enabled_tags = FFF; expert
[hint:Search functionality]
text = Search functionality\n Did you know that you use the<a>Search</a>tool to quickly find a specific PrusaSlicer setting? Or use the familiar shortcut <b>Ctrl+F</b>.
@ -140,10 +140,10 @@ text = PageUp / PageDown quick rotation by 45 degrees\nDid you know that you can
text = Load config from G-code\nDid you know that you can use File-Import Config to load print, filament and printer profiles from an existing G-code file? Similarly, you can use File-Import SL1 archive, which also lets you reconstruct 3D models from the voxel data.
[hint:Ironing]
text = Ironing\nDid you know that you can smooth top surfaces of prints using Ironing? The nozzle will run a special second infill phase at the same layer to fill in holes and flatten any lifted plastic. Read more in the<a>documentation.</a> (Requires Advanced or Expert mode.)
text = Ironing\nDid you know that you can smooth top surfaces of prints using Ironing? The nozzle will run a special second infill phase at the same layer to fill in holes and flatten any lifted plastic. Read more in the documentation. (Requires Advanced or Expert mode.)
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/ironing_177488
disabled_modes = SLA; simple
disabled_tags = SLA; simple
[hint:Fuzzy skin]
text = Fuzzy skin\nDid you know that you can create rough fibre-like texture on the sides of your models using the<a>Fuzzy skin</a>feature? You can also use modifiers to apply fuzzy-skin only to a portion of your model.
@ -151,38 +151,38 @@ hypertext_type = settings
hypertext_settings_opt = fuzzy_skin
hypertext_settings_type = 1
hypertext_settings_category = Layers and perimeters
disabled_modes = SLA
disabled_tags = SLA
[hint:Negative volume]
text = Negative volume\nDid you know that you can subtract one mesh from another using the Negative volume modifier? That way you can, for example, create easily resizable holes directly in PrusaSlicer. Read more in the<a>documentation.</a>(Requires Advanced or Expert mode.)
text = Negative volume\nDid you know that you can subtract one mesh from another using the Negative volume modifier? That way you can, for example, create easily resizable holes directly in PrusaSlicer. Read more in the documentation. (Requires Advanced or Expert mode.)
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/negative-volume_238503
disabled_modes = SLA; simple
disabled_tags = SLA; simple
[hint:Paint-on supports]
text = Paint-on supports\nDid you know that you can paint directly on the object and select areas, where supports should be enforced or blocked? Try the<a>Paint-on supports</a>feature. (Requires Advanced or Expert mode.)
hypertext_type = gizmo
hypertext_gizmo_item = fdm_supports
disabled_modes = SLA; simple
disabled_tags = SLA; simple
[hint:Paint-on seam]
text = Paint-on seam\nDid you know that you can paint directly on the object and select where to place the start/endpoint of each perimeter loop? Try the<a>Seam painting</a>feature. (Requires Advanced or Expert mode.)
hypertext_type = gizmo
hypertext_gizmo_item = seam
disabled_modes = SLA; simple
disabled_tags = SLA; simple
[hint:Insert Pause]
text = Insert Pause\nDid you know that you can schedule the print to pause at a specific layer? Right-click the layer slider in the Preview and select Add pause print (M601). This can be used to insert magnets, weights or nuts into your prints. Read more in the<a>documentation.</a>
text = Insert Pause\nDid you know that you can schedule the print to pause at a specific layer? Right-click the layer slider in the Preview and select Add pause print (M601). This can be used to insert magnets, weights or nuts into your prints. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/insert-pause-or-custom-g-code-at-layer_120490#insert-pause-at-layer
[hint:Insert Custom G-code]
text = Insert Custom G-code\nDid you know that you can insert a custom G-code at a specific layer? Right-click the layer in the Preview and select Add custom G-code. With this function you can, for example, create a temperature tower. Read more in the<a>documentation.</a>
text = Insert Custom G-code\nDid you know that you can insert a custom G-code at a specific layer? Right-click the layer in the Preview and select Add custom G-code. With this function you can, for example, create a temperature tower. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/insert-pause-or-custom-g-code-at-layer_120490#insert-custom-g-code-at-layer
[hint:Configuration snapshots]
text = Configuration snapshots\nDid you know that roll back to a complete backup of all system and user profiles? You can view and move back and forth between snapshots using the Configuration - Configuration snapshots menu. Read more in the<a>documentation.</a>
text = Configuration snapshots\nDid you know that roll back to a complete backup of all system and user profiles? You can view and move back and forth between snapshots using the Configuration - Configuration snapshots menu. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/configuration-snapshots_1776
@ -192,7 +192,7 @@ hypertext_type = settings
hypertext_settings_opt = top_solid_min_thickness
hypertext_settings_type = 1
hypertext_settings_category = Layers and perimeters
disabled_modes = SLA
disabled_tags = SLA
[hint:Settings in non-modal window]
text = Settings in non-modal window\nDid you know that you can open the Settings in a new non-modal window? This means you can have settings open on one screen and the G-code Preview on the other. Go to the<a>Preferences</a>and select Settings in non-modal window.
@ -200,7 +200,7 @@ hypertext_type = preferences
hypertext_preferences_page = 2
[hint:Adaptive infills]
text = Adaptive infills\nDid you know that you can use the Adaptive cubic and Support cubic infills to decrease the print time and lower the filament consumption? Read more in the<a>documentation.</a>
text = Adaptive infills\nDid you know that you can use the Adaptive cubic and Support cubic infills to decrease the print time and lower the filament consumption? Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/infill-patterns_177130
@ -208,7 +208,7 @@ documentation_link = https://help.prusa3d.com/en/article/infill-patterns_177130
text = Fullscreen mode\nDid you know that you can switch PrusaSlicer to fullscreen mode? Use the <b>F11</b> hotkey.
[hint:Simplify mesh]
text = Simplify mesh\nDid you know that you can reduce the number of triangles in a mesh using the Simplify mesh feature? Right-click the model and select Simplify model. Read more in the<a>documentation.</a>
text = Simplify mesh\nDid you know that you can reduce the number of triangles in a mesh using the Simplify mesh feature? Right-click the model and select Simplify model. Read more in the documentation.
hypertext_type = link
documentation_link = https://help.prusa3d.com/en/article/simplify-mesh_238941

View File

@ -664,7 +664,7 @@ void GUI_App::post_init()
// show "Did you know" notification
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer())
plater_->get_notification_manager()->push_hint_notification();
plater_->get_notification_manager()->push_hint_notification(true);
// The extra CallAfter() is needed because of Mac, where this is the only way
// to popup a modal dialog on start without screwing combo boxes.

View File

@ -30,52 +30,116 @@ inline void push_style_color(ImGuiCol idx, const ImVec4& col, bool fading_out, f
else
ImGui::PushStyleColor(idx, col);
}
// return true if NOT in disabled mode.
inline bool mode_and_tech_check(const std::string& disabled_mode, const std::string& preferred_mode, const std::string& disabled_tech, const std::string& preferred_tech)
enum TagCheckResult
{
if (disabled_mode.empty() && preferred_mode.empty() && disabled_tech.empty() && preferred_tech.empty())
return true;
TagCheckAffirmative,
TagCheckNegative,
TagCheckNotCompatible
};
// returns if in mode defined by tag
inline TagCheckResult tag_check_mode(const std::string& tag)
{
std::vector<std::string> allowed_tags = {"simple", "advanced", "expert"};
if (std::find(allowed_tags.begin(), allowed_tags.end(), tag) != allowed_tags.end())
{
ConfigOptionMode config_mode = wxGetApp().get_mode();
if (config_mode == ConfigOptionMode::comSimple) return (tag == "simple" ? TagCheckAffirmative : TagCheckNegative);
else if (config_mode == ConfigOptionMode::comAdvanced) return (tag == "advanced" ? TagCheckAffirmative : TagCheckNegative);
else if (config_mode == ConfigOptionMode::comExpert) return (tag == "expert" ? TagCheckAffirmative : TagCheckNegative);
}
return TagCheckNotCompatible;
}
// simple / advanced / expert
ConfigOptionMode config_mode = wxGetApp().get_mode();
std::string mode_name;
if (config_mode == ConfigOptionMode::comSimple) mode_name = "simple";
else if (config_mode == ConfigOptionMode::comAdvanced) mode_name = "advanced";
else if (config_mode == ConfigOptionMode::comExpert) mode_name = "expert";
if (!preferred_mode.empty() && !mode_name.empty() && preferred_mode.find(mode_name) == std::string::npos)
return false;
if (!mode_name.empty() && disabled_mode.find(mode_name) != std::string::npos)
return false;
// tchnology
const PrinterTechnology tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
if (tech == ptFFF) {
// MMU
bool is_mmu = wxGetApp().extruders_edited_cnt() > 1;
if (is_mmu)
{
if (!preferred_tech.empty() && preferred_tech.find("MMU") == std::string::npos)
return false;
if (is_mmu && disabled_tech.find("MMU") != std::string::npos)
return false;
inline TagCheckResult tag_check_tech(const std::string& tag)
{
std::vector<std::string> allowed_tags = { "FFF", "MMU", "SLA" };
if (std::find(allowed_tags.begin(), allowed_tags.end(), tag) != allowed_tags.end()) {
const PrinterTechnology tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
if (tech == ptFFF) {
// MMU / FFF
bool is_mmu = wxGetApp().extruders_edited_cnt() > 1;
if (tag == "MMU") return (is_mmu ? TagCheckAffirmative : TagCheckNegative);
return (tag == "FFF" ? TagCheckAffirmative : TagCheckNegative);
} else {
// only FFF - does not show if MMU preffered
if (!preferred_tech.empty() && preferred_tech.find("FFF") == std::string::npos)
return false;
if (disabled_tech.find("FFF") != std::string::npos)
return false;
// SLA
return (tag == "SLA" ? TagCheckAffirmative : TagCheckNegative);
}
}
return TagCheckNotCompatible;
}
// return true if NOT in disabled mode.
inline bool tags_check(const std::string& disabled_tags, const std::string& enabled_tags)
{
if (disabled_tags.empty() && enabled_tags.empty())
return true;
// enabled tags must ALL return affirmative or check fails
if (!enabled_tags.empty()) {
std::string tag;
for (size_t i = 0; i < enabled_tags.size(); i++) {
if (enabled_tags[i] == ' ') {
tag.erase();
continue;
}
if (enabled_tags[i] != ';') {
tag += enabled_tags[i];
}
if (enabled_tags[i] == ';' || i == enabled_tags.size() - 1) {
if (!tag.empty()) {
TagCheckResult result;
result = tag_check_mode(tag);
if (result == TagCheckResult::TagCheckNegative)
return false;
if (result == TagCheckResult::TagCheckAffirmative)
continue;
result = tag_check_tech(tag);
if (result == TagCheckResult::TagCheckNegative)
return false;
if (result == TagCheckResult::TagCheckAffirmative)
continue;
BOOST_LOG_TRIVIAL(error) << "Hint Notification: Tag " << tag << " in enabled_tags not compatible.";
// non compatible in enabled means return false since all enabled must be affirmative.
return false;
}
}
}
}
// disabled tags must all NOT return affirmative or check fails
if (!disabled_tags.empty()) {
std::string tag;
for (size_t i = 0; i < disabled_tags.size(); i++) {
if (disabled_tags[i] == ' ') {
tag.erase();
continue;
}
if (disabled_tags[i] != ';') {
tag += disabled_tags[i];
}
if (disabled_tags[i] == ';' || i == disabled_tags.size() - 1) {
if (!tag.empty()) {
TagCheckResult result;
result = tag_check_mode(tag);
if (result == TagCheckResult::TagCheckNegative)
continue;
if (result == TagCheckResult::TagCheckAffirmative)
return false;
result = tag_check_tech(tag);
if (result == TagCheckResult::TagCheckNegative)
continue;
if (result == TagCheckResult::TagCheckAffirmative)
return false;
BOOST_LOG_TRIVIAL(error) << "Hint Notification: Tag " << tag << " in disabled_tags not compatible.";
}
}
}
} else {
// SLA
if (!preferred_tech.empty() && preferred_tech.find("SLA") == std::string::npos)
return false;
if (disabled_tech.find("SLA") != std::string::npos)
return false;
}
return true;
}
inline void launch_browser_if_allowed(const std::string& url)
{
if (wxGetApp().app_config->get("suppress_hyperlinks") != "1")
wxLaunchDefaultBrowser(url);
}
} //namespace
void HintDatabase::init()
@ -108,17 +172,15 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
dict.emplace(data.first, data.second.data());
}
//unescaping a translating all texts
//unescape text1
//unescaping and translating all texts and saving all data common for all hint types
std::string fulltext;
std::string text1;
std::string hypertext_text;
std::string follow_text;
std::string disabled_mode;
std::string preferred_mode;
std::string disabled_tech;
std::string preferred_tech;
std::string disabled_tags;
std::string enabled_tags;
std::string documentation_link;
//unescape text1
unescape_string_cstyle(_utf8(dict["text"]), fulltext);
// replace <b> and </b> for imgui markers
std::string marker_s(1, ImGui::ColorMarkerStart);
@ -165,17 +227,11 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
text1 = fulltext;
}
if (dict.find("disabled_mode") != dict.end()) {
disabled_mode = dict["disabled_mode"];
if (dict.find("disabled_tags") != dict.end()) {
disabled_tags = dict["disabled_tags"];
}
if (dict.find("preferred_mode") != dict.end()) {
preferred_mode = dict["preferred_mode"];
}
if (dict.find("disabled_tech") != dict.end()) {
disabled_tech = dict["disabled_tech"];
}
if (dict.find("preferred_tech") != dict.end()) {
preferred_tech = dict["preferred_tech"];
if (dict.find("enabled_tags") != dict.end()) {
enabled_tags = dict["enabled_tags"];
}
if (dict.find("documentation_link") != dict.end()) {
documentation_link = dict["documentation_link"];
@ -186,37 +242,37 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
//link to internet
if(dict["hypertext_type"] == "link") {
std::string hypertext_link = dict["hypertext_link"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, [hypertext_link]() { wxLaunchDefaultBrowser(hypertext_link); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, false, documentation_link, [hypertext_link]() { launch_browser_if_allowed(hypertext_link); } };
m_loaded_hints.emplace_back(hint_data);
// highlight settings
} else if (dict["hypertext_type"] == "settings") {
std::string opt = dict["hypertext_settings_opt"];
Preset::Type type = static_cast<Preset::Type>(std::atoi(dict["hypertext_settings_type"].c_str()));
std::wstring category = boost::nowide::widen(dict["hypertext_settings_category"]);
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [opt, type, category]() { GUI::wxGetApp().sidebar().jump_to_option(opt, type, category); } };
m_loaded_hints.emplace_back(hint_data);
// open preferences
} else if(dict["hypertext_type"] == "preferences") {
int page = static_cast<Preset::Type>(std::atoi(dict["hypertext_preferences_page"].c_str()));
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, [page]() { wxGetApp().open_preferences(page); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, false, documentation_link, [page]() { wxGetApp().open_preferences(page); } };
m_loaded_hints.emplace_back(hint_data);
} else if (dict["hypertext_type"] == "plater") {
std::string item = dict["hypertext_plater_item"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_toolbar_item(item); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_toolbar_item(item); } };
m_loaded_hints.emplace_back(hint_data);
} else if (dict["hypertext_type"] == "gizmo") {
std::string item = dict["hypertext_gizmo_item"];
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_gizmo(item); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, true, documentation_link, [item]() { wxGetApp().plater()->canvas3D()->highlight_gizmo(item); } };
m_loaded_hints.emplace_back(hint_data);
}
else if (dict["hypertext_type"] == "gallery") {
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link, []() { wxGetApp().obj_list()->load_shape_object_from_gallery(); } };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, false, documentation_link, []() { wxGetApp().obj_list()->load_shape_object_from_gallery(); } };
m_loaded_hints.emplace_back(hint_data);
}
} else {
// plain text without hypertext
HintData hint_data{ text1, hypertext_text, follow_text, disabled_mode, preferred_mode, disabled_tech, preferred_tech, false, documentation_link };
HintData hint_data{ text1, hypertext_text, follow_text, disabled_tags, enabled_tags, false, documentation_link };
m_loaded_hints.emplace_back(hint_data);
}
}
@ -235,7 +291,7 @@ HintData* HintDatabase::get_hint(bool up)
}
// shift id
m_hint_id = (up ? m_hint_id + 1 : (m_hint_id == 0 ? m_loaded_hints.size() - 1 : m_hint_id - 1));
m_hint_id = (up ? m_hint_id + 1 : m_hint_id );
m_hint_id %= m_loaded_hints.size();
AppConfig* app_config = wxGetApp().app_config;
@ -307,7 +363,7 @@ void NotificationManager::HintNotification::count_lines()
}
// when one word longer than line.
if (ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x > m_window_width - m_window_width_offset ||
ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x < (m_window_width - m_window_width_offset) / 4 * 3
ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x < (m_window_width - m_window_width_offset) / 5 * 3
) {
float width_of_a = ImGui::CalcTextSize("a").x;
int letter_count = (int)((m_window_width - m_window_width_offset) / width_of_a);
@ -377,7 +433,7 @@ void NotificationManager::HintNotification::count_lines()
}
// when one word longer than line.
if (ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x > m_window_width - m_window_width_offset - size_of_last_line ||
ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x + size_of_last_line < (m_window_width - m_window_width_offset) / 4 * 3
ImGui::CalcTextSize(text.substr(last_end, next_space - last_end).c_str()).x + size_of_last_line < (m_window_width - m_window_width_offset) / 5 * 3
) {
float width_of_a = ImGui::CalcTextSize("a").x;
int letter_count = (int)((m_window_width - m_window_width_offset - size_of_last_line) / width_of_a);
@ -436,7 +492,7 @@ void NotificationManager::HintNotification::set_next_window_size(ImGuiWrapper& i
bool NotificationManager::HintNotification::on_text_click()
{
if (m_hypertext_callback != nullptr && (!m_runtime_disable || mode_and_tech_check(m_disabled_mode, m_preferred_mode, m_disabled_tech, m_preferred_tech)))
if (m_hypertext_callback != nullptr && (!m_runtime_disable || tags_check(m_disabled_tags, m_enabled_tags)))
m_hypertext_callback();
return false;
}
@ -575,10 +631,10 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im
ImGui::PopStyleColor();
render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
//render_right_arrow_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_logo(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
render_preferences_button(imgui, win_pos_x, win_pos_y);
if (!m_documentation_link.empty())
if (!m_documentation_link.empty() && wxGetApp().app_config->get("suppress_hyperlinks") != "1")
{
render_documentation_button(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
}
@ -597,12 +653,24 @@ void NotificationManager::HintNotification::render_preferences_button(ImGuiWrapp
std::string button_text;
button_text = ImGui::PreferencesButton;
//hover
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 10.f, win_pos_y + m_window_height - 2 * m_line_height + 1),
if (ImGui::IsMouseHoveringRect(ImVec2(win_pos_x - m_window_width / 15.f, win_pos_y + m_window_height - 1.75f * m_line_height),
ImVec2(win_pos_x, win_pos_y + m_window_height),
true))
{
button_text = ImGui::PreferencesHoverButton;
}
// tooltip
long time_now = wxGetLocalTime();
if (m_prefe_hover_time > 0 && m_prefe_hover_time < time_now) {
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::BeginTooltip();
imgui.text(_u8L("Open Preferences."));
ImGui::EndTooltip();
ImGui::PopStyleColor();
}
if (m_prefe_hover_time == 0)
m_prefe_hover_time = time_now;
} else
m_prefe_hover_time = 0;
ImVec2 button_pic_size = ImGui::CalcTextSize(button_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
@ -710,21 +778,19 @@ void NotificationManager::HintNotification::render_documentation_button(ImGuiWra
{
button_text = ImGui::DocumentationHoverButton;
// tooltip
long time_now = wxGetLocalTime();
if (m_hover_time > 0 && m_hover_time < time_now) {
if (m_docu_hover_time > 0 && m_docu_hover_time < time_now) {
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
ImGui::BeginTooltip();
imgui.text(_u8L("Open Documentation in web browser"));
imgui.text(_u8L("Open Documentation in web browser."));
ImGui::EndTooltip();
ImGui::PopStyleColor();
}
if (m_hover_time == 0)
m_hover_time = time_now;
if (m_docu_hover_time == 0)
m_docu_hover_time = time_now;
}
else
m_hover_time = 0;
m_docu_hover_time = 0;
ImVec2 button_pic_size = ImGui::CalcTextSize(placeholder_text.c_str());
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
@ -754,16 +820,16 @@ void NotificationManager::HintNotification::open_documentation()
{
if (!m_documentation_link.empty())
{
wxLaunchDefaultBrowser(m_documentation_link);
launch_browser_if_allowed(m_documentation_link);
}
}
void NotificationManager::HintNotification::retrieve_data(size_t recursion_counter)
void NotificationManager::HintNotification::retrieve_data(int recursion_counter)
{
HintData* hint_data = HintDatabase::get_instance().get_hint(true);
HintData* hint_data = HintDatabase::get_instance().get_hint(recursion_counter >= 0 ? true : false);
if (hint_data == nullptr)
close();
if (hint_data != nullptr && !mode_and_tech_check(hint_data->disabled_mode, hint_data->preferred_mode, hint_data->disabled_tech, hint_data->preferred_tech))
if (hint_data != nullptr && !tags_check(hint_data->disabled_tags, hint_data->enabled_tags))
{
// Content for different user - retrieve another
size_t count = HintDatabase::get_instance().get_count();
@ -783,13 +849,11 @@ void NotificationManager::HintNotification::retrieve_data(size_t recursion_count
hint_data->hypertext, nullptr,
hint_data->follow_text };
m_hypertext_callback = hint_data->callback;
m_disabled_mode = hint_data->disabled_mode;
m_preferred_mode = hint_data->preferred_mode;
m_disabled_tech = hint_data->disabled_tech;
m_preferred_tech = hint_data->preferred_tech;
m_runtime_disable = hint_data->runtime_disable;
m_disabled_tags = hint_data->disabled_tags;
m_enabled_tags = hint_data->enabled_tags;
m_runtime_disable = hint_data->runtime_disable;
m_documentation_link = hint_data->documentation_link;
m_has_hint_data = true;
m_has_hint_data = true;
update(nd);
}
}

View File

@ -12,10 +12,8 @@ struct HintData
std::string text;
std::string hypertext;
std::string follow_text;
std::string disabled_mode;
std::string preferred_mode;
std::string disabled_tech;
std::string preferred_tech;
std::string disabled_tags;
std::string enabled_tags;
bool runtime_disable; // if true - hyperlink will check before every click if not in disabled mode
std::string documentation_link;
std::function<void(void)> callback { nullptr };
@ -57,12 +55,13 @@ private:
class NotificationManager::HintNotification : public NotificationManager::PopNotification
{
public:
HintNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler)
HintNotification(const NotificationData& n, NotificationIDProvider& id_provider, wxEvtHandler* evt_handler, bool new_hint)
: PopNotification(n, id_provider, evt_handler)
{
retrieve_data();
retrieve_data(new_hint ? 0 : -1);
}
virtual void init() override;
void open_next() { retrieve_data(0); }
protected:
virtual void set_next_window_size(ImGuiWrapper& imgui) override;
virtual void count_spaces() override;
@ -87,21 +86,21 @@ protected:
void render_logo(ImGuiWrapper& imgui,
const float win_size_x, const float win_size_y,
const float win_pos_x, const float win_pos_y);
void retrieve_data(size_t recursion_counter = 0);
// recursion counter -1 tells to retrieve same hint as last time
void retrieve_data(int recursion_counter = 0);
void open_documentation();
bool m_has_hint_data { false };
std::function<void(void)> m_hypertext_callback;
std::string m_disabled_mode;
std::string m_preferred_mode;
std::string m_disabled_tech;
std::string m_preferred_tech;
std::string m_disabled_tags;
std::string m_enabled_tags;
bool m_runtime_disable;
std::string m_documentation_link;
float m_close_b_y { 0 };
float m_close_b_w { 0 };
// hover of buttons
size_t m_hover_time { 0 };
size_t m_docu_hover_time { 0 };
size_t m_prefe_hover_time{ 0 };
};
} //namespace Slic3r

View File

@ -45,6 +45,7 @@
#include "GUI_Factories.hpp"
#include "GUI_ObjectList.hpp"
#include "GalleryDialog.hpp"
#include "NotificationManager.hpp"
#ifdef _WIN32
#include <dbt.h>
@ -1073,6 +1074,10 @@ static wxMenu* generate_help_menu()
else
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
[](wxCommandEvent&) { Slic3r::GUI::about(); });
append_menu_item(helpMenu, wxID_ANY, _L("Next Hint notification"), _L("Opens another Hint notification."),
[](wxCommandEvent&) { wxGetApp().plater()->get_notification_manager()->push_hint_notification(true); });
append_menu_item(helpMenu, wxID_ANY, _L("Reopen Hint notification"), _L("Opens Hint notification in bottom right corner."),
[](wxCommandEvent&) { wxGetApp().plater()->get_notification_manager()->push_hint_notification(false); });
helpMenu->AppendSeparator();
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
[](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });

View File

@ -1347,14 +1347,30 @@ void NotificationManager::upload_job_notification_show_error(int id, const std::
}
}
}
void NotificationManager::push_hint_notification()
void NotificationManager::push_hint_notification(bool open_next)
{
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::DidYouKnowHint) {
if (open_next)
(dynamic_cast<HintNotification*>(notification.get()))->open_next();
else
notification->set_hovered();
return;
}
}
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 300, "" };
push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 0);
}
bool NotificationManager::is_hint_notification_open()
{
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
if (notification->get_type() == NotificationType::DidYouKnowHint)
return;
return true;
}
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 0, "" };
push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler), 0);
return false;
}
void NotificationManager::push_updated_item_info_notification(InfoItemType type)

View File

@ -169,7 +169,8 @@ public:
void upload_job_notification_show_canceled(int id, const std::string& filename, const std::string& host);
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
// Hint (did you know) notification
void push_hint_notification();
void push_hint_notification(bool open_next);
bool is_hint_notification_open();
void push_updated_item_info_notification(InfoItemType type);
// Close old notification ExportFinished.
void new_export_began(bool on_removable);