Hints notification
Hints notification: enabled / disabled tags Hints notification: suppress opening url due to preferences. Hint notification: close after 5 minutes and button in Help menu
This commit is contained in:
parent
ed25d5c53d
commit
06d27bcb3c
7 changed files with 215 additions and 130 deletions
|
@ -40,13 +40,13 @@
|
||||||
# hypertext_type = gallery
|
# hypertext_type = gallery
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Each notification can have disabled and preferred modes and techs - divided by ;
|
# Each notification can have disabled and enabled modes and techs - divided by ; and space
|
||||||
# preferred_mode = simple
|
# enabled_tags = ...
|
||||||
# disabled_mode = advanced; expert
|
# disabled_tags = ...
|
||||||
# preferred_tech = SLA
|
# supported tags are: simple; advanced; expert; FFF; MMU; SLA
|
||||||
# disabled_tech = FFF; MMU
|
# FFF is affirmative for both one or more extruder printers.
|
||||||
# Algorithm shows hint only if in preffered mode / tech.
|
# Algorithm shows hint only if ALL enabled tags are affirmative. (so never do enabled_tags = FFF; SLA;)
|
||||||
# Algorithm shows hint only if not in disabled mode / tech.
|
# 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.
|
# 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_opt = infill_every_layers
|
||||||
hypertext_settings_type = 1
|
hypertext_settings_type = 1
|
||||||
hypertext_settings_category = Infill
|
hypertext_settings_category = Infill
|
||||||
disabled_modes = SLA; simple
|
disabled_tags = SLA; simple
|
||||||
|
|
||||||
[hint:Hiding sidebar]
|
[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>
|
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.)
|
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_type = plater
|
||||||
hypertext_plater_item = layersediting
|
hypertext_plater_item = layersediting
|
||||||
disabled_modes = SLA
|
disabled_tags = SLA
|
||||||
|
|
||||||
[hint:Undo/redo history]
|
[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?
|
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
|
hypertext_plater_item = arrange
|
||||||
|
|
||||||
[hint:Reload from disk]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/reload-from-disk_120427
|
documentation_link = https://help.prusa3d.com/en/article/reload-from-disk_120427
|
||||||
|
|
||||||
[hint:Different layer height for each model]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/per-model-settings_1674
|
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_opt = solid_infill_below_area
|
||||||
hypertext_settings_type = 1
|
hypertext_settings_type = 1
|
||||||
hypertext_settings_category = Infill
|
hypertext_settings_category = Infill
|
||||||
disabled_modes = SLA; simple; advanced
|
enabled_tags = FFF; expert
|
||||||
|
|
||||||
[hint:Search functionality]
|
[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>.
|
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.
|
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]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/ironing_177488
|
documentation_link = https://help.prusa3d.com/en/article/ironing_177488
|
||||||
disabled_modes = SLA; simple
|
disabled_tags = SLA; simple
|
||||||
|
|
||||||
[hint:Fuzzy skin]
|
[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.
|
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_opt = fuzzy_skin
|
||||||
hypertext_settings_type = 1
|
hypertext_settings_type = 1
|
||||||
hypertext_settings_category = Layers and perimeters
|
hypertext_settings_category = Layers and perimeters
|
||||||
disabled_modes = SLA
|
disabled_tags = SLA
|
||||||
|
|
||||||
[hint:Negative volume]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/negative-volume_238503
|
documentation_link = https://help.prusa3d.com/en/article/negative-volume_238503
|
||||||
disabled_modes = SLA; simple
|
disabled_tags = SLA; simple
|
||||||
|
|
||||||
[hint:Paint-on supports]
|
[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.)
|
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_type = gizmo
|
||||||
hypertext_gizmo_item = fdm_supports
|
hypertext_gizmo_item = fdm_supports
|
||||||
disabled_modes = SLA; simple
|
disabled_tags = SLA; simple
|
||||||
|
|
||||||
[hint:Paint-on seam]
|
[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.)
|
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_type = gizmo
|
||||||
hypertext_gizmo_item = seam
|
hypertext_gizmo_item = seam
|
||||||
disabled_modes = SLA; simple
|
disabled_tags = SLA; simple
|
||||||
|
|
||||||
[hint:Insert Pause]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/insert-pause-or-custom-g-code-at-layer_120490#insert-pause-at-layer
|
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]
|
[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
|
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
|
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]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/configuration-snapshots_1776
|
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_opt = top_solid_min_thickness
|
||||||
hypertext_settings_type = 1
|
hypertext_settings_type = 1
|
||||||
hypertext_settings_category = Layers and perimeters
|
hypertext_settings_category = Layers and perimeters
|
||||||
disabled_modes = SLA
|
disabled_tags = SLA
|
||||||
|
|
||||||
[hint:Settings in non-modal window]
|
[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.
|
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
|
hypertext_preferences_page = 2
|
||||||
|
|
||||||
[hint:Adaptive infills]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/infill-patterns_177130
|
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.
|
text = Fullscreen mode\nDid you know that you can switch PrusaSlicer to fullscreen mode? Use the <b>F11</b> hotkey.
|
||||||
|
|
||||||
[hint:Simplify mesh]
|
[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
|
hypertext_type = link
|
||||||
documentation_link = https://help.prusa3d.com/en/article/simplify-mesh_238941
|
documentation_link = https://help.prusa3d.com/en/article/simplify-mesh_238941
|
||||||
|
|
||||||
|
|
|
@ -664,7 +664,7 @@ void GUI_App::post_init()
|
||||||
|
|
||||||
// show "Did you know" notification
|
// show "Did you know" notification
|
||||||
if (app_config->get("show_hints") == "1" && ! is_gcode_viewer())
|
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
|
// 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.
|
// to popup a modal dialog on start without screwing combo boxes.
|
||||||
|
|
|
@ -30,52 +30,116 @@ inline void push_style_color(ImGuiCol idx, const ImVec4& col, bool fading_out, f
|
||||||
else
|
else
|
||||||
ImGui::PushStyleColor(idx, col);
|
ImGui::PushStyleColor(idx, col);
|
||||||
}
|
}
|
||||||
// return true if NOT in disabled mode.
|
enum TagCheckResult
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (disabled_mode.empty() && preferred_mode.empty() && disabled_tech.empty() && preferred_tech.empty())
|
TagCheckAffirmative,
|
||||||
return true;
|
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
|
inline TagCheckResult tag_check_tech(const std::string& tag)
|
||||||
ConfigOptionMode config_mode = wxGetApp().get_mode();
|
{
|
||||||
std::string mode_name;
|
std::vector<std::string> allowed_tags = { "FFF", "MMU", "SLA" };
|
||||||
if (config_mode == ConfigOptionMode::comSimple) mode_name = "simple";
|
if (std::find(allowed_tags.begin(), allowed_tags.end(), tag) != allowed_tags.end()) {
|
||||||
else if (config_mode == ConfigOptionMode::comAdvanced) mode_name = "advanced";
|
const PrinterTechnology tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
|
||||||
else if (config_mode == ConfigOptionMode::comExpert) mode_name = "expert";
|
if (tech == ptFFF) {
|
||||||
|
// MMU / FFF
|
||||||
if (!preferred_mode.empty() && !mode_name.empty() && preferred_mode.find(mode_name) == std::string::npos)
|
bool is_mmu = wxGetApp().extruders_edited_cnt() > 1;
|
||||||
return false;
|
if (tag == "MMU") return (is_mmu ? TagCheckAffirmative : TagCheckNegative);
|
||||||
if (!mode_name.empty() && disabled_mode.find(mode_name) != std::string::npos)
|
return (tag == "FFF" ? TagCheckAffirmative : TagCheckNegative);
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
// only FFF - does not show if MMU preffered
|
// SLA
|
||||||
if (!preferred_tech.empty() && preferred_tech.find("FFF") == std::string::npos)
|
return (tag == "SLA" ? TagCheckAffirmative : TagCheckNegative);
|
||||||
return false;
|
}
|
||||||
if (disabled_tech.find("FFF") != std::string::npos)
|
}
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
inline void launch_browser_if_allowed(const std::string& url)
|
||||||
|
{
|
||||||
|
if (wxGetApp().app_config->get("suppress_hyperlinks") != "1")
|
||||||
|
wxLaunchDefaultBrowser(url);
|
||||||
|
}
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
void HintDatabase::init()
|
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());
|
dict.emplace(data.first, data.second.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
//unescaping a translating all texts
|
//unescaping and translating all texts and saving all data common for all hint types
|
||||||
//unescape text1
|
|
||||||
std::string fulltext;
|
std::string fulltext;
|
||||||
std::string text1;
|
std::string text1;
|
||||||
std::string hypertext_text;
|
std::string hypertext_text;
|
||||||
std::string follow_text;
|
std::string follow_text;
|
||||||
std::string disabled_mode;
|
std::string disabled_tags;
|
||||||
std::string preferred_mode;
|
std::string enabled_tags;
|
||||||
std::string disabled_tech;
|
|
||||||
std::string preferred_tech;
|
|
||||||
std::string documentation_link;
|
std::string documentation_link;
|
||||||
|
//unescape text1
|
||||||
unescape_string_cstyle(_utf8(dict["text"]), fulltext);
|
unescape_string_cstyle(_utf8(dict["text"]), fulltext);
|
||||||
// replace <b> and </b> for imgui markers
|
// replace <b> and </b> for imgui markers
|
||||||
std::string marker_s(1, ImGui::ColorMarkerStart);
|
std::string marker_s(1, ImGui::ColorMarkerStart);
|
||||||
|
@ -165,17 +227,11 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
|
||||||
text1 = fulltext;
|
text1 = fulltext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict.find("disabled_mode") != dict.end()) {
|
if (dict.find("disabled_tags") != dict.end()) {
|
||||||
disabled_mode = dict["disabled_mode"];
|
disabled_tags = dict["disabled_tags"];
|
||||||
}
|
}
|
||||||
if (dict.find("preferred_mode") != dict.end()) {
|
if (dict.find("enabled_tags") != dict.end()) {
|
||||||
preferred_mode = dict["preferred_mode"];
|
enabled_tags = dict["enabled_tags"];
|
||||||
}
|
|
||||||
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("documentation_link") != dict.end()) {
|
if (dict.find("documentation_link") != dict.end()) {
|
||||||
documentation_link = dict["documentation_link"];
|
documentation_link = dict["documentation_link"];
|
||||||
|
@ -186,37 +242,37 @@ void HintDatabase::load_hints_from_file(const boost::filesystem::path& path)
|
||||||
//link to internet
|
//link to internet
|
||||||
if(dict["hypertext_type"] == "link") {
|
if(dict["hypertext_type"] == "link") {
|
||||||
std::string hypertext_link = dict["hypertext_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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
// highlight settings
|
// highlight settings
|
||||||
} else if (dict["hypertext_type"] == "settings") {
|
} else if (dict["hypertext_type"] == "settings") {
|
||||||
std::string opt = dict["hypertext_settings_opt"];
|
std::string opt = dict["hypertext_settings_opt"];
|
||||||
Preset::Type type = static_cast<Preset::Type>(std::atoi(dict["hypertext_settings_type"].c_str()));
|
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"]);
|
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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
// open preferences
|
// open preferences
|
||||||
} else if(dict["hypertext_type"] == "preferences") {
|
} else if(dict["hypertext_type"] == "preferences") {
|
||||||
int page = static_cast<Preset::Type>(std::atoi(dict["hypertext_preferences_page"].c_str()));
|
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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
|
|
||||||
} else if (dict["hypertext_type"] == "plater") {
|
} else if (dict["hypertext_type"] == "plater") {
|
||||||
std::string item = dict["hypertext_plater_item"];
|
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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
} else if (dict["hypertext_type"] == "gizmo") {
|
} else if (dict["hypertext_type"] == "gizmo") {
|
||||||
std::string item = dict["hypertext_gizmo_item"];
|
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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
}
|
}
|
||||||
else if (dict["hypertext_type"] == "gallery") {
|
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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// plain text without hypertext
|
// 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);
|
m_loaded_hints.emplace_back(hint_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +291,7 @@ HintData* HintDatabase::get_hint(bool up)
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift id
|
// 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();
|
m_hint_id %= m_loaded_hints.size();
|
||||||
|
|
||||||
AppConfig* app_config = wxGetApp().app_config;
|
AppConfig* app_config = wxGetApp().app_config;
|
||||||
|
@ -307,7 +363,7 @@ void NotificationManager::HintNotification::count_lines()
|
||||||
}
|
}
|
||||||
// when one word longer than line.
|
// 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 ||
|
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;
|
float width_of_a = ImGui::CalcTextSize("a").x;
|
||||||
int letter_count = (int)((m_window_width - m_window_width_offset) / width_of_a);
|
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.
|
// 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 ||
|
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;
|
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);
|
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()
|
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();
|
m_hypertext_callback();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -575,10 +631,10 @@ void NotificationManager::HintNotification::render_close_button(ImGuiWrapper& im
|
||||||
ImGui::PopStyleColor();
|
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_logo(imgui, win_size_x, win_size_y, win_pos_x, win_pos_y);
|
||||||
render_preferences_button(imgui, 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);
|
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;
|
std::string button_text;
|
||||||
button_text = ImGui::PreferencesButton;
|
button_text = ImGui::PreferencesButton;
|
||||||
//hover
|
//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),
|
ImVec2(win_pos_x, win_pos_y + m_window_height),
|
||||||
true))
|
true))
|
||||||
{
|
{
|
||||||
button_text = ImGui::PreferencesHoverButton;
|
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_pic_size = ImGui::CalcTextSize(button_text.c_str());
|
||||||
ImVec2 button_size(button_pic_size.x * 1.25f, button_pic_size.y * 1.25f);
|
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;
|
button_text = ImGui::DocumentationHoverButton;
|
||||||
// tooltip
|
// tooltip
|
||||||
|
|
||||||
long time_now = wxGetLocalTime();
|
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::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
imgui.text(_u8L("Open Documentation in web browser"));
|
imgui.text(_u8L("Open Documentation in web browser."));
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
if (m_hover_time == 0)
|
if (m_docu_hover_time == 0)
|
||||||
m_hover_time = time_now;
|
m_docu_hover_time = time_now;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_hover_time = 0;
|
m_docu_hover_time = 0;
|
||||||
|
|
||||||
ImVec2 button_pic_size = ImGui::CalcTextSize(placeholder_text.c_str());
|
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);
|
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())
|
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)
|
if (hint_data == nullptr)
|
||||||
close();
|
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
|
// Content for different user - retrieve another
|
||||||
size_t count = HintDatabase::get_instance().get_count();
|
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->hypertext, nullptr,
|
||||||
hint_data->follow_text };
|
hint_data->follow_text };
|
||||||
m_hypertext_callback = hint_data->callback;
|
m_hypertext_callback = hint_data->callback;
|
||||||
m_disabled_mode = hint_data->disabled_mode;
|
m_disabled_tags = hint_data->disabled_tags;
|
||||||
m_preferred_mode = hint_data->preferred_mode;
|
m_enabled_tags = hint_data->enabled_tags;
|
||||||
m_disabled_tech = hint_data->disabled_tech;
|
m_runtime_disable = hint_data->runtime_disable;
|
||||||
m_preferred_tech = hint_data->preferred_tech;
|
|
||||||
m_runtime_disable = hint_data->runtime_disable;
|
|
||||||
m_documentation_link = hint_data->documentation_link;
|
m_documentation_link = hint_data->documentation_link;
|
||||||
m_has_hint_data = true;
|
m_has_hint_data = true;
|
||||||
update(nd);
|
update(nd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,8 @@ struct HintData
|
||||||
std::string text;
|
std::string text;
|
||||||
std::string hypertext;
|
std::string hypertext;
|
||||||
std::string follow_text;
|
std::string follow_text;
|
||||||
std::string disabled_mode;
|
std::string disabled_tags;
|
||||||
std::string preferred_mode;
|
std::string enabled_tags;
|
||||||
std::string disabled_tech;
|
|
||||||
std::string preferred_tech;
|
|
||||||
bool runtime_disable; // if true - hyperlink will check before every click if not in disabled mode
|
bool runtime_disable; // if true - hyperlink will check before every click if not in disabled mode
|
||||||
std::string documentation_link;
|
std::string documentation_link;
|
||||||
std::function<void(void)> callback { nullptr };
|
std::function<void(void)> callback { nullptr };
|
||||||
|
@ -57,12 +55,13 @@ private:
|
||||||
class NotificationManager::HintNotification : public NotificationManager::PopNotification
|
class NotificationManager::HintNotification : public NotificationManager::PopNotification
|
||||||
{
|
{
|
||||||
public:
|
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)
|
: PopNotification(n, id_provider, evt_handler)
|
||||||
{
|
{
|
||||||
retrieve_data();
|
retrieve_data(new_hint ? 0 : -1);
|
||||||
}
|
}
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
|
void open_next() { retrieve_data(0); }
|
||||||
protected:
|
protected:
|
||||||
virtual void set_next_window_size(ImGuiWrapper& imgui) override;
|
virtual void set_next_window_size(ImGuiWrapper& imgui) override;
|
||||||
virtual void count_spaces() override;
|
virtual void count_spaces() override;
|
||||||
|
@ -87,21 +86,21 @@ protected:
|
||||||
void render_logo(ImGuiWrapper& imgui,
|
void render_logo(ImGuiWrapper& imgui,
|
||||||
const float win_size_x, const float win_size_y,
|
const float win_size_x, const float win_size_y,
|
||||||
const float win_pos_x, const float win_pos_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();
|
void open_documentation();
|
||||||
|
|
||||||
bool m_has_hint_data { false };
|
bool m_has_hint_data { false };
|
||||||
std::function<void(void)> m_hypertext_callback;
|
std::function<void(void)> m_hypertext_callback;
|
||||||
std::string m_disabled_mode;
|
std::string m_disabled_tags;
|
||||||
std::string m_preferred_mode;
|
std::string m_enabled_tags;
|
||||||
std::string m_disabled_tech;
|
|
||||||
std::string m_preferred_tech;
|
|
||||||
bool m_runtime_disable;
|
bool m_runtime_disable;
|
||||||
std::string m_documentation_link;
|
std::string m_documentation_link;
|
||||||
float m_close_b_y { 0 };
|
float m_close_b_y { 0 };
|
||||||
float m_close_b_w { 0 };
|
float m_close_b_w { 0 };
|
||||||
// hover of buttons
|
// 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
|
} //namespace Slic3r
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "GUI_Factories.hpp"
|
#include "GUI_Factories.hpp"
|
||||||
#include "GUI_ObjectList.hpp"
|
#include "GUI_ObjectList.hpp"
|
||||||
#include "GalleryDialog.hpp"
|
#include "GalleryDialog.hpp"
|
||||||
|
#include "NotificationManager.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
|
@ -1073,6 +1074,10 @@ static wxMenu* generate_help_menu()
|
||||||
else
|
else
|
||||||
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
|
append_menu_item(helpMenu, wxID_ANY, wxString::Format(_L("&About %s"), GCODEVIEWER_APP_NAME), _L("Show about dialog"),
|
||||||
[](wxCommandEvent&) { Slic3r::GUI::about(); });
|
[](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();
|
helpMenu->AppendSeparator();
|
||||||
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
|
append_menu_item(helpMenu, wxID_ANY, _L("Keyboard Shortcuts") + sep + "&?", _L("Show the list of the keyboard shortcuts"),
|
||||||
[](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });
|
[](wxCommandEvent&) { wxGetApp().keyboard_shortcuts(); });
|
||||||
|
|
|
@ -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) {
|
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||||
if (notification->get_type() == NotificationType::DidYouKnowHint)
|
if (notification->get_type() == NotificationType::DidYouKnowHint)
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 0, "" };
|
return false;
|
||||||
push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::push_updated_item_info_notification(InfoItemType type)
|
void NotificationManager::push_updated_item_info_notification(InfoItemType type)
|
||||||
|
|
|
@ -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_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);
|
void upload_job_notification_show_error(int id, const std::string& filename, const std::string& host);
|
||||||
// Hint (did you know) notification
|
// 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);
|
void push_updated_item_info_notification(InfoItemType type);
|
||||||
// Close old notification ExportFinished.
|
// Close old notification ExportFinished.
|
||||||
void new_export_began(bool on_removable);
|
void new_export_began(bool on_removable);
|
||||||
|
|
Loading…
Reference in a new issue