2020-08-03 13:36:55 +00:00
# ifndef slic3r_GUI_NotificationManager_hpp_
# define slic3r_GUI_NotificationManager_hpp_
# include "Event.hpp"
# include "I18N.hpp"
# include <string>
# include <vector>
# include <deque>
# include <unordered_set>
namespace Slic3r {
namespace GUI {
using EjectDriveNotificationClickedEvent = SimpleEvent ;
wxDECLARE_EVENT ( EVT_EJECT_DRIVE_NOTIFICAION_CLICKED , EjectDriveNotificationClickedEvent ) ;
using ExportGcodeNotificationClickedEvent = SimpleEvent ;
wxDECLARE_EVENT ( EVT_EXPORT_GCODE_NOTIFICAION_CLICKED , ExportGcodeNotificationClickedEvent ) ;
using PresetUpdateAviableClickedEvent = SimpleEvent ;
wxDECLARE_EVENT ( EVT_PRESET_UPDATE_AVIABLE_CLICKED , PresetUpdateAviableClickedEvent ) ;
class GLCanvas3D ;
class ImGuiWrapper ;
enum class NotificationType
{
CustomNotification ,
SlicingComplete ,
SlicingNotPossible ,
ExportToRemovableFinished ,
Mouse3dDisconnected ,
Mouse3dConnected ,
NewPresetsAviable ,
NewAppAviable ,
PresetUpdateAviable ,
LoadingFailed ,
ValidateError , // currently not used - instead Slicing error is used for both slicing and validate errors
SlicingError ,
SlicingWarning ,
PlaterError ,
PlaterWarning ,
ApplyError
} ;
class NotificationManager
{
public :
enum class NotificationLevel : int
{
ErrorNotification = 4 ,
WarningNotification = 3 ,
ImportantNotification = 2 ,
RegularNotification = 1 ,
} ;
// duration 0 means not disapearing
struct NotificationData {
NotificationType type ;
NotificationLevel level ;
const int duration ;
const std : : string text1 ;
const std : : string hypertext = std : : string ( ) ;
const std : : string text2 = std : : string ( ) ;
} ;
//Pop notification - shows only once to user.
class PopNotification
{
public :
enum class RenderResult
{
Finished ,
ClosePending ,
Static ,
Countdown ,
Hovered
} ;
PopNotification ( const NotificationData & n , const int id , wxEvtHandler * evt_handler ) ;
virtual ~ PopNotification ( ) ;
RenderResult render ( GLCanvas3D & canvas , const float & initial_y ) ;
// close will dissapear notification on next render
void close ( ) { m_close_pending = true ; }
// data from newer notification of same type
void update ( const NotificationData & n ) ;
bool get_finished ( ) const { return m_finished ; }
// returns top after movement
float get_top ( ) const { return m_top_y ; }
//returns top in actual frame
float get_current_top ( ) const { return m_top_y ; }
const NotificationType get_type ( ) const { return m_data . type ; }
const NotificationData get_data ( ) const { return m_data ; }
const bool get_is_gray ( ) const { return m_is_gray ; }
// Call equals one second down
void substract_remaining_time ( ) { m_remaining_time - - ; }
void set_gray ( bool g ) { m_is_gray = g ; }
void set_paused ( bool p ) { m_paused = p ; }
bool compare_text ( const std : : string & text ) ;
2020-08-25 07:55:29 +00:00
void hide ( bool h ) { m_hidden = h ; }
2020-08-03 13:36:55 +00:00
protected :
// Call after every size change
void init ( ) ;
// Calculetes correct size but not se it in imgui!
virtual void set_next_window_size ( ImGuiWrapper & imgui ) ;
virtual void render_text ( ImGuiWrapper & imgui ,
const float win_size_x , const float win_size_y ,
const float win_pos_x , const float win_pos_y ) ;
void render_close_button ( ImGuiWrapper & imgui ,
const float win_size_x , const float win_size_y ,
const float win_pos_x , const float win_pos_y ) ;
void render_countdown ( ImGuiWrapper & imgui ,
const float win_size_x , const float win_size_y ,
const float win_pos_x , const float win_pos_y ) ;
void render_hypertext ( ImGuiWrapper & imgui ,
const float text_x , const float text_y ,
const std : : string text ,
bool more = false ) ;
void render_left_sign ( ImGuiWrapper & imgui ) ;
void render_minimize_button ( ImGuiWrapper & imgui ,
const float win_pos_x , const float win_pos_y ) ;
void on_text_click ( ) ;
const NotificationData m_data ;
int m_id ;
// Main text
std : : string m_text1 ;
// Clickable text
std : : string m_hypertext ;
// Aditional text after hypertext - currently not used
std : : string m_text2 ;
// Countdown variables
long m_remaining_time ;
bool m_counting_down ;
long m_last_remaining_time ;
bool m_paused { false } ;
int m_countdown_frame { 0 } ;
bool m_fading_out { false } ;
// total time left when fading beggins
float m_fading_time { 0.0f } ;
float m_current_fade_opacity { 1.f } ;
// If hidden the notif is alive but not visible to user
bool m_hidden { false } ;
// m_finished = true - does not render, marked to delete
bool m_finished { false } ;
// Will go to m_finished next render
bool m_close_pending { false } ;
// variables to count positions correctly
float m_window_width_offset ;
float m_left_indentation ;
// Total size of notification window - varies based on monitor
float m_window_height { 56.0f } ;
float m_window_width { 450.0f } ;
//Distance from bottom of notifications to top of this notification
float m_top_y { 0.0f } ;
// Height of text
// Used as basic scaling unit!
float m_line_height ;
std : : vector < int > m_endlines ;
// Gray are f.e. eorrors when its uknown if they are still valid
bool m_is_gray { false } ;
//if multiline = true, notification is showing all lines(>2)
bool m_multiline { false } ;
int m_lines_count { 1 } ;
wxEvtHandler * m_evt_handler ;
} ;
class SlicingCompleteLargeNotification : public PopNotification
{
public :
SlicingCompleteLargeNotification ( const NotificationData & n , const int id , wxEvtHandler * evt_handler , bool largeds ) ;
void set_large ( bool l ) ;
bool get_large ( ) { return m_is_large ; }
void set_print_info ( std : : string info ) ;
protected :
virtual void render_text ( ImGuiWrapper & imgui ,
const float win_size_x , const float win_size_y ,
const float win_pos_x , const float win_pos_y )
override ;
bool m_is_large ;
bool m_has_print_info { false } ;
std : : string m_print_info { std : : string ( ) } ;
} ;
class SlicingWarningNotification : public PopNotification
{
public :
SlicingWarningNotification ( const NotificationData & n , const int id , wxEvtHandler * evt_handler ) : PopNotification ( n , id , evt_handler ) { }
void set_object_id ( size_t id ) { object_id = id ; }
const size_t get_object_id ( ) { return object_id ; }
void set_warning_step ( int ws ) { warning_step = ws ; }
const int get_warning_step ( ) { return warning_step ; }
protected :
size_t object_id ;
int warning_step ;
} ;
NotificationManager ( wxEvtHandler * evt_handler ) ;
~ NotificationManager ( ) ;
// only type means one of basic_notification (see below)
void push_notification ( const NotificationType type , GLCanvas3D & canvas , int timestamp = 0 ) ;
// only text means Undefined type
void push_notification ( const std : : string & text , GLCanvas3D & canvas , int timestamp = 0 ) ;
void push_notification ( const std : : string & text , NotificationLevel level , GLCanvas3D & canvas , int timestamp = 0 ) ;
// creates Slicing Error notification with custom text
void push_slicing_error_notification ( const std : : string & text , GLCanvas3D & canvas ) ;
// creates Slicing Warning notification with custom text
void push_slicing_warning_notification ( const std : : string & text , bool gray , GLCanvas3D & canvas , size_t oid , int warning_step ) ;
// marks slicing errors as gray
void set_all_slicing_errors_gray ( bool g ) ;
// marks slicing warings as gray
void set_all_slicing_warnings_gray ( bool g ) ;
void set_slicing_warning_gray ( const std : : string & text , bool g ) ;
// imidietly stops showing slicing errors
void close_slicing_errors_and_warnings ( ) ;
void compare_warning_oids ( const std : : vector < size_t > & living_oids ) ;
void push_plater_error_notification ( const std : : string & text , GLCanvas3D & canvas ) ;
void push_plater_warning_notification ( const std : : string & text , GLCanvas3D & canvas ) ;
void close_plater_error_notification ( ) ;
void close_plater_warning_notification ( const std : : string & text ) ;
// creates special notification slicing complete
// if large = true prints printing time and export button
void push_slicing_complete_notification ( GLCanvas3D & canvas , int timestamp , bool large ) ;
void set_slicing_complete_print_time ( std : : string info ) ;
void set_slicing_complete_large ( bool large ) ;
// renders notifications in queue and deletes expired ones
void render_notifications ( GLCanvas3D & canvas ) ;
// finds and closes all notifications of given type
void close_notification_of_type ( const NotificationType type ) ;
void dpi_changed ( ) ;
2020-08-25 07:55:29 +00:00
void set_in_preview ( bool preview ) ;
2020-08-03 13:36:55 +00:00
private :
//pushes notification into the queue of notifications that are rendered
//can be used to create custom notification
bool push_notification_data ( const NotificationData & notification_data , GLCanvas3D & canvas , int timestamp ) ;
bool push_notification_data ( NotificationManager : : PopNotification * notification , GLCanvas3D & canvas , int timestamp ) ;
//finds older notification of same type and moves it to the end of queue. returns true if found
bool find_older ( NotificationManager : : PopNotification * notification ) ;
void sort_notifications ( ) ;
2020-08-25 15:59:51 +00:00
bool has_error_notification ( ) ;
2020-08-03 13:36:55 +00:00
wxEvtHandler * m_evt_handler ;
std : : deque < PopNotification * > m_pop_notifications ;
int m_next_id { 1 } ;
long m_last_time { 0 } ;
bool m_hovered { false } ;
//timestamps used for slining finished - notification could be gone so it needs to be stored here
std : : unordered_set < int > m_used_timestamps ;
2020-08-25 07:55:29 +00:00
bool m_in_preview ;
2020-08-03 13:36:55 +00:00
//prepared (basic) notifications
const std : : vector < NotificationData > basic_notifications = {
{ NotificationType : : SlicingNotPossible , NotificationLevel : : RegularNotification , 10 , _u8L ( " Slicing is not possible. " ) } ,
{ NotificationType : : ExportToRemovableFinished , NotificationLevel : : ImportantNotification , 0 , _u8L ( " Exporting finished. " ) , _u8L ( " Eject drive. " ) } ,
{ NotificationType : : Mouse3dDisconnected , NotificationLevel : : RegularNotification , 10 , _u8L ( " 3D Mouse disconnected. " ) } ,
{ NotificationType : : Mouse3dConnected , NotificationLevel : : RegularNotification , 5 , _u8L ( " 3D Mouse connected. " ) } ,
{ NotificationType : : NewPresetsAviable , NotificationLevel : : ImportantNotification , 20 , _u8L ( " New Presets are available. " ) , _u8L ( " See here. " ) } ,
{ NotificationType : : PresetUpdateAviable , NotificationLevel : : ImportantNotification , 20 , _u8L ( " Configuration update is available. " ) , _u8L ( " See more. " ) } ,
{ NotificationType : : NewAppAviable , NotificationLevel : : ImportantNotification , 20 , _u8L ( " New version is available. " ) , _u8L ( " See Releases page. " ) } ,
//{NotificationType::NewAppAviable, NotificationLevel::ImportantNotification, 20, _u8L("New vesion of PrusaSlicer is available.", _u8L("Download page.") },
//{NotificationType::LoadingFailed, NotificationLevel::RegularNotification, 20, _u8L("Loading of model has Failed") },
//{NotificationType::DeviceEjected, NotificationLevel::RegularNotification, 10, _u8L("Removable device has been safely ejected")} // if we want changeble text (like here name of device), we need to do it as CustomNotification
} ;
} ;
} //namespace GUI
} //namespace Slic3r
# endif //slic3r_GUI_NotificationManager_hpp_