mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	delayed notifications: custom condition function for showing and refactoring
This commit is contained in:
		
							parent
							
								
									86ddac7b1e
								
							
						
					
					
						commit
						04778e0fa5
					
				
					 2 changed files with 56 additions and 26 deletions
				
			
		|  | @ -1369,20 +1369,17 @@ void NotificationManager::push_hint_notification(bool open_next) | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 300, "" }; | 	NotificationData data{ NotificationType::DidYouKnowHint, NotificationLevel::RegularNotification, 300, "" }; | ||||||
| 	// from user
 | 	// from user - open now
 | ||||||
| 	if (!open_next) { | 	if (!open_next) { | ||||||
| 		push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 0); | 		push_notification_data(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 0); | ||||||
| 		// delete from delayed list
 | 		stop_delayed_notifications_of_type(NotificationType::DidYouKnowHint); | ||||||
| 		for (auto it = m_waiting_notifications.begin(); it != m_waiting_notifications.end();) { | 	// at startup - delay for half a second to let other notification pop up, than try every 30 seconds
 | ||||||
| 			if ((*it).notification->get_type() == NotificationType::DidYouKnowHint) { | 	// show only if no notifications are shown
 | ||||||
| 				it = m_waiting_notifications.erase(it); |  | ||||||
| 			} else { |  | ||||||
| 				++it; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	// at startup
 |  | ||||||
| 	} else {  | 	} else {  | ||||||
| 		push_delayed_notification(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), 500, 30000); | 		auto condition = [this]() { | ||||||
|  | 			return this->get_notification_count() == 0; | ||||||
|  | 		}; | ||||||
|  | 		push_delayed_notification(std::make_unique<NotificationManager::HintNotification>(data, m_id_provider, m_evt_handler, open_next), condition, 500, 30000); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1439,13 +1436,25 @@ bool NotificationManager::push_notification_data(std::unique_ptr<NotificationMan | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void NotificationManager::push_delayed_notification(std::unique_ptr<NotificationManager::PopNotification> notification, int64_t initial_delay, int64_t delay_interval) | void NotificationManager::push_delayed_notification(std::unique_ptr<NotificationManager::PopNotification> notification, std::function<bool(void)> condition_callback, int64_t initial_delay, int64_t delay_interval) | ||||||
| { | { | ||||||
| 	if (initial_delay == 0 && m_pop_notifications.empty()) { | 	if (initial_delay == 0 && condition_callback()) { | ||||||
| 		push_notification_data(std::move(notification), 0); | 		if( push_notification_data(std::move(notification), 0)) | ||||||
| 	} else { | 			return; | ||||||
| 		m_waiting_notifications.emplace_back(std::move(notification), initial_delay, delay_interval); | 	}  | ||||||
| 		wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(initial_delay); | 	m_waiting_notifications.emplace_back(std::move(notification), condition_callback, initial_delay == 0 ? delay_interval : initial_delay, delay_interval); | ||||||
|  | 	wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(initial_delay == 0 ? delay_interval : initial_delay); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void NotificationManager::stop_delayed_notifications_of_type(const NotificationType type) | ||||||
|  | { | ||||||
|  | 	for (auto it = m_waiting_notifications.begin(); it != m_waiting_notifications.end();) { | ||||||
|  | 		if ((*it).notification->get_type() == type) { | ||||||
|  | 			it = m_waiting_notifications.erase(it); | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			++it; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1507,14 +1516,15 @@ bool NotificationManager::update_notifications(GLCanvas3D& canvas) | ||||||
| 		if ((*it).remaining_time > 0) | 		if ((*it).remaining_time > 0) | ||||||
| 			(*it).remaining_time -= time_since_render; | 			(*it).remaining_time -= time_since_render; | ||||||
| 		if ((*it).remaining_time <= 0) { | 		if ((*it).remaining_time <= 0) { | ||||||
| 			if (m_pop_notifications.empty()) { // push notification, erase it from waiting list (frame is scheduled by push)
 | 			if ((*it).condition_callback()) { // push notification, erase it from waiting list (frame is scheduled by push)
 | ||||||
| 				(*it).notification->reset_timer(); | 				(*it).notification->reset_timer(); | ||||||
| 				push_notification_data(std::move((*it).notification), 0); | 				if (push_notification_data(std::move((*it).notification), 0)) { | ||||||
| 				it = m_waiting_notifications.erase(it); | 					it = m_waiting_notifications.erase(it); | ||||||
| 				continue; | 					continue; | ||||||
| 			} else { // not possible to push, delay for delay_interval
 | 				} | ||||||
| 				(*it).remaining_time = (*it).delay_interval; |  | ||||||
| 			} | 			} | ||||||
|  | 			// not possible to push, delay for delay_interval
 | ||||||
|  | 			(*it).remaining_time = (*it).delay_interval; | ||||||
| 		} | 		} | ||||||
| 		next_render = std::min<int64_t>(next_render, (*it).remaining_time); | 		next_render = std::min<int64_t>(next_render, (*it).remaining_time); | ||||||
| 		++it; | 		++it; | ||||||
|  | @ -1612,6 +1622,15 @@ void NotificationManager::device_ejected() | ||||||
| 			notification->close(); | 			notification->close(); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | size_t NotificationManager::get_notification_count() const | ||||||
|  | { | ||||||
|  | 	size_t ret = 0; | ||||||
|  | 	for (const std::unique_ptr<PopNotification>& notification : m_pop_notifications) { | ||||||
|  | 		if (notification->get_state() != PopNotification::EState::Hidden) | ||||||
|  | 			ret++; | ||||||
|  | 	} | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| }//namespace GUI
 | }//namespace GUI
 | ||||||
| }//namespace Slic3r
 | }//namespace Slic3r
 | ||||||
|  |  | ||||||
|  | @ -190,6 +190,8 @@ public: | ||||||
| 	void set_move_from_overlay(bool move) { m_move_from_overlay = move; } | 	void set_move_from_overlay(bool move) { m_move_from_overlay = move; } | ||||||
| 	// perform update_state on each notification and ask for more frames if needed, return true for render needed
 | 	// perform update_state on each notification and ask for more frames if needed, return true for render needed
 | ||||||
| 	bool update_notifications(GLCanvas3D& canvas); | 	bool update_notifications(GLCanvas3D& canvas); | ||||||
|  | 	// returns number of all notifications shown
 | ||||||
|  | 	size_t get_notification_count() const; | ||||||
| private: | private: | ||||||
| 	// duration 0 means not disapearing
 | 	// duration 0 means not disapearing
 | ||||||
| 	struct NotificationData { | 	struct NotificationData { | ||||||
|  | @ -521,10 +523,13 @@ private: | ||||||
| 	struct DelayedNotification | 	struct DelayedNotification | ||||||
| 	{ | 	{ | ||||||
| 		std::unique_ptr<PopNotification>	notification; | 		std::unique_ptr<PopNotification>	notification; | ||||||
|  | 		std::function<bool(void)>           condition_callback; | ||||||
| 		int64_t								remaining_time; | 		int64_t								remaining_time; | ||||||
| 		int64_t                             delay_interval; | 		int64_t                             delay_interval; | ||||||
| 		DelayedNotification(std::unique_ptr<PopNotification> n, int64_t r, int64_t d) | 		 | ||||||
|  | 		DelayedNotification(std::unique_ptr<PopNotification> n, std::function<bool(void)> cb, int64_t r, int64_t d) | ||||||
| 		: notification(std::move(n)) | 		: notification(std::move(n)) | ||||||
|  | 	    , condition_callback(cb) | ||||||
| 		, remaining_time(r) | 		, remaining_time(r) | ||||||
| 		, delay_interval(d) | 		, delay_interval(d) | ||||||
| 		{} | 		{} | ||||||
|  | @ -534,8 +539,14 @@ private: | ||||||
| 	//can be used to create custom notification
 | 	//can be used to create custom notification
 | ||||||
| 	bool push_notification_data(const NotificationData& notification_data, int timestamp); | 	bool push_notification_data(const NotificationData& notification_data, int timestamp); | ||||||
| 	bool push_notification_data(std::unique_ptr<NotificationManager::PopNotification> notification, int timestamp); | 	bool push_notification_data(std::unique_ptr<NotificationManager::PopNotification> notification, int timestamp); | ||||||
| 	// Delayed notifications goes first to the m_waiting_notifications vector and only after remaining time is <= 0 and m_pop_notifications are empty, notification is regular pushed. Otherwise another delay interval waiting. Timestamp is 0. 
 | 	// Delayed notifications goes first to the m_waiting_notifications vector and only after remaining time is <= 0
 | ||||||
| 	void push_delayed_notification(std::unique_ptr<NotificationManager::PopNotification> notification, int64_t initial_delay, int64_t delay_interval); | 	// and condition callback is success, notification is regular pushed from update function.
 | ||||||
|  | 	// Otherwise another delay interval waiting. Timestamp is 0. 
 | ||||||
|  | 	// Note that notification object is constructed when being added to the waiting list, but there are no updates called on it and its timer is reset at regular push.
 | ||||||
|  | 	// Also note that no control of same notification is done during push_delayed_notification but if waiting notif fails to push, it continues waiting.
 | ||||||
|  | 	void push_delayed_notification(std::unique_ptr<NotificationManager::PopNotification> notification, std::function<bool(void)> condition_callback, int64_t initial_delay, int64_t delay_interval); | ||||||
|  | 	// Removes all notifications of type from m_waiting_notifications
 | ||||||
|  | 	void stop_delayed_notifications_of_type(const NotificationType type); | ||||||
| 	//finds older notification of same type and moves it to the end of queue. returns true if found
 | 	//finds older notification of same type and moves it to the end of queue. returns true if found
 | ||||||
| 	bool activate_existing(const NotificationManager::PopNotification* notification); | 	bool activate_existing(const NotificationManager::PopNotification* notification); | ||||||
| 	// Put the more important notifications to the bottom of the list.
 | 	// Put the more important notifications to the bottom of the list.
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 David Kocik
						David Kocik