notifications.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 
4 #ifdef _MSC_VER
5 #ifndef NOMINMAX
6 #define NOMINMAX
7 #endif
8 #endif
9 
10 #include <thread>
11 #include <algorithm>
12 #include <regex>
13 #include <cmath>
14 
15 #include <opengl3.h>
16 
17 #include "notifications.h"
18 #include <imgui_internal.h>
19 
20 #include "model-views.h"
21 
22 #include "os.h"
23 
24 #include "viewer.h"
25 
26 #include "metadata-helper.h"
27 
28 using namespace std;
29 using namespace chrono;
30 
31 namespace rs2
32 {
33  notification_data::notification_data(std::string description,
36  : _description(description),
37  _severity(severity),
38  _category(category)
39  {
40  _timestamp = (double)std::chrono::high_resolution_clock::now().time_since_epoch().count();
41  }
42 
44  {
45  return _category;
46  }
47 
49  {
50  return _description;
51  }
52 
53 
55  {
56  return _timestamp;
57  }
58 
60  {
61  return _severity;
62  }
63 
65  {
66  custom_action = []{};
67  last_x = 500000;
68  last_y = 200;
69  message = "";
70  last_moved = std::chrono::system_clock::now();
71 
72  created_time = std::chrono::system_clock::now();
73  last_interacted = std::chrono::system_clock::now() - std::chrono::milliseconds(500);
74  }
75 
78  {
81  severity = n.get_severity();
83  last_interacted = std::chrono::system_clock::now() - std::chrono::milliseconds(500);
84  category = n.get_category();
85  }
86 
87  double notification_model::get_age_in_ms(bool total) const
88  {
89  auto interacted = duration<double, milli>(last_interacted - created_time).count();
90  return duration<double, milli>(system_clock::now() - created_time).count() - (total ? 0.0 : interacted);
91  }
92 
94  {
95  return duration<double, milli>(system_clock::now() - last_interacted).count() < 100;
96  }
97 
98  // Pops the N colors that were pushed in set_color_scheme
100  {
102  }
103 
104  void progress_bar::draw(ux_window & win, int bar_width, int progress)
105  {
106  auto now = system_clock::now();
107  auto ellapsed = duration_cast<milliseconds>(now - last_progress_time).count() / 1000.f;
108 
109  auto new_progress = last_progress + ellapsed * progress_speed;
110  curr_progress_value = std::min(threshold_progress, new_progress);
111 
112  if (last_progress != progress)
113  {
114  last_progress_time = system_clock::now();
115 
116  int delta = progress - last_progress;
117 
118  if (ellapsed > 0.f) progress_speed = delta / ellapsed;
119 
120  threshold_progress = float(std::min(100, progress + delta));
121 
122  last_progress = progress;
123  }
124 
125  auto filled_w = (curr_progress_value * (bar_width - 4)) / 100.f;
126 
128  ImGui::GetWindowDrawList()->AddRectFilled({ float(pos.x), float(pos.y) },
129  { float(pos.x + bar_width), float(pos.y + 20) }, ImColor(black));
130 
131  if (curr_progress_value > 0.f)
132  {
133  for (int i = 20; i >= 0; i -= 2)
134  {
135  auto a = curr_progress_value / 100.f;
136  ImGui::GetWindowDrawList()->AddRectFilled({ float(pos.x + 3 - i), float(pos.y + 3 - i) },
137  { float(pos.x + filled_w + i), float(pos.y + 17 + i) },
138  ImColor(alpha(light_blue, sqrt(a) * 0.02f)), float(i));
139  }
140 
141  ImGui::GetWindowDrawList()->AddRectFilled({ float(pos.x + 3), float(pos.y + 3) },
142  { float(pos.x + filled_w), float(pos.y + 17) }, ImColor(light_blue));
143 
144  ImGui::GetWindowDrawList()->AddRectFilledMultiColor({ float(pos.x + 5), float(pos.y + 5) },
145  { float(pos.x + filled_w), float(pos.y + 15) },
148 
149  rs2::rect pbar{ float(pos.x + 3), float(pos.y + 3), float(bar_width), 17.f };
150  auto mouse = win.get_mouse();
151  if (pbar.contains(mouse.cursor))
152  {
153  std::string progress_str = to_string() << progress << "%";
154  ImGui::SetTooltip("%s", progress_str.c_str());
155  }
156  }
157 
158  ImGui::SetCursorScreenPos({ float(pos.x), float(pos.y + 25) });
159  }
160 
162  {
163  auto progress = update_manager->get_progress();
164  _progress_bar.draw(win, bar_width, progress);
165  }
166 
167  /* Sets color scheme for notifications, must be used with unset_color_scheme to pop all colors in the end
168  Parameter t indicates the transparency of the nofication interface */
170  {
171  ImVec4 c;
172 
177  c = alpha(white, 1 - t);
179 
182  {
183  c = alpha(dark_red, 1 - t);
185  }
186  else
187  {
188  c = alpha(saturate(grey, 0.7f), 1 - t);
190  }
191  }
192 
194  {
195  return 10000;
196  }
197 
198  void notification_model::draw_text(const char* msg, int x, int y, int h)
199  {
200  std::string text_name = to_string() << "##notification_text_" << index;
201  ImGui::PushTextWrapPos(x + width - 100.f);
208  if (enable_click) ImGui::Text("%s", msg);
209  else ImGui::InputTextMultiline(text_name.c_str(), const_cast<char*>(msg),
210  strlen(msg) + 1, { float(width - (count > 1 ? 40 : 10)), float(h) },
214 
215  if (ImGui::IsItemHovered())
216  {
218  }
219  }
220 
222  {
223  auto title = message;
224 
225  auto parts = split_string(title, '`');
226  if (parts.size() > 1) title = parts[0];
227 
228  return title;
229  }
230 
232  {
233  auto title = get_title();
234  auto lines = static_cast<int>(std::count(title.begin(), title.end(), '\n') + 1);
235  return int((lines + 1) * ImGui::GetTextLineHeight() + 5);
236  }
237 
239  {
240  // TODO: Make polymorphic
241  if (update_state == 2)
242  {
243  auto k = duration_cast<milliseconds>(system_clock::now() - _progress_bar.last_progress_time).count() / 500.f;
244  if (k <= 1.f)
245  {
246  auto size = 100;
247  k = pow(1.f - smoothstep(static_cast<float>(k), 0.f, 1.f), 2.f);
248  ImGui::GetWindowDrawList()->AddRectFilled({ float(x - size * k), float(y - size * k) },
249  { float(x + width + size * k), float(y + height + size * k) },
250  ImColor(alpha(white, (1.f - k) / 2)), (size * k) / 2);
251  }
252  }
253  }
254 
255  void notification_model::draw_content(ux_window& win, int x, int y, float t, std::string& error_message)
256  {
257  draw_text(get_title().c_str(), x, y, height - 35);
258  }
259 
261  {
262  ImGui::SetCursorScreenPos({ float(x + width - 105), float(y + height - 25) });
263 
264  string id = to_string() << "Dismiss" << "##" << index;
265 
270 
271  ImGui::PushFont(win.get_font());
272 
273  ImGui::SetNextWindowPos({ float(x + width - 125), float(y + height - 25) });
274  ImGui::SetNextWindowSize({ 120, 70 });
275 
276  std::string dismiss_popup = to_string() << "Dismiss Options" << "##" << index;
277  if (ImGui::BeginPopup(dismiss_popup.c_str()))
278  {
279  if (ImGui::Selectable("Just this time"))
280  {
281  dismiss(true);
282  }
283 
284  if (ImGui::Selectable("Remind me later"))
285  {
286  delay(7);
287  dismiss(true);
288  }
289 
290  if (ImGui::Selectable("Don't show again"))
291  {
292  delay(1000);
293  dismiss(true);
294  }
295 
296  ImGui::EndPopup();
297  }
298 
299  ImGui::PopFont();
301 
302  if (ImGui::Button(id.c_str(), { 100, 20 }))
303  {
305  ImGui::OpenPopup(dismiss_popup.c_str());
306  else dismiss(true);
307  }
308  if (ImGui::IsItemHovered())
309  {
310  win.link_hovered();
311  }
312  }
313 
314  std::function<void()> notification_model::draw(ux_window& win, int w, int y,
315  std::shared_ptr<notification_model>& selected, std::string& error_message)
316  {
317  std::function<void()> action;
318  while(dispatch_queue.try_dequeue(&action)) action();
319 
320  std::function<void()> follow_up = []{};
321 
322  if (visible)
323  {
324  auto stack = std::min(count, max_stack);
325  auto x = w - width - 10;
326 
327  if (dismissed)
328  {
329  x = w + width;
330  }
331 
332  if (!animating && (fabs(x - last_x) > 1.f || fabs(y - last_y) > 1.f))
333  {
334  if (last_x > 100000)
335  {
336  last_x = x + 500.f;
337  last_y = float(y);
338  }
340  animating = true;
341  }
342 
343  auto elapsed = duration<double, milli>(system_clock::now() - last_moved).count();
344  auto s = smoothstep(static_cast<float>(elapsed / 250.f), 0.0f, 1.0f);
345 
346  if (s < 1.f)
347  {
348  x = int(s * x + (1 - s) * last_x);
349  y = int(s * y + (1 - s) * last_y);
350  }
351  else
352  {
353  last_x = float(x); last_y = float(y);
354  animating = false;
355  if (dismissed && !expanded) to_close = true;
356  }
357 
358  auto ms = get_age_in_ms() / get_max_lifetime_ms();
359  auto t = smoothstep(static_cast<float>(ms), 0.8f, 1.f);
360  if (pinned) t = 0.f;
361 
363 
364  height = calc_height();
365 
367  c.w = smoothstep(static_cast<float>(get_age_in_ms(true) / 200.f), 0.0f, 1.0f);
368  c.w = std::min(c.w, 1.f - t);
369 
370  draw_pre_effect(x, y);
371 
372  for (int i = stack - 1; i >= 0; i--)
373  {
374  auto ccopy = alpha(c, (0.9f * c.w) / (i + 1));
375 
376  ImVec4 shadow{ 0.1f, 0.1f, 0.1f, 0.1f };
377 
378  ImGui::GetWindowDrawList()->AddRectFilled({ float(x + 2 + i * stack_offset), float(y + 2 + i * stack_offset) },
379  { float(x + 2 + width + i * stack_offset), float(y + 2 + height + i * stack_offset) }, ImColor(shadow));
380 
381  ImGui::GetWindowDrawList()->AddRectFilledMultiColor({ float(x + i * stack_offset), float(y + i * stack_offset) },
382  { float(x + width + i * stack_offset), float(y + height + i * stack_offset) },
383  ImColor(saturate(ccopy, 0.9f)), ImColor(saturate(ccopy, 0.95f)),
384  ImColor(saturate(ccopy, 1.2f)), ImColor(saturate(ccopy, 1.1f)));
385 
386  ImGui::GetWindowDrawList()->AddRect({ float(x + i * stack_offset), float(y + i * stack_offset) },
387  { float(x + width + i * stack_offset), float(y + height + i * stack_offset) }, ImColor(saturate(ccopy, 0.5f)));
388  }
389 
390  ImGui::SetCursorScreenPos({ float(x), float(y) });
391 
392  if (enable_click)
393  {
394  std::string button_name = to_string() << "##" << index;
395 
397 
398  if (ImGui::Button(button_name.c_str(), { (float)width, (float)height }))
399  {
400  follow_up = custom_action;
401  dismiss(false);
402  }
403  if (ImGui::IsItemHovered())
404  win.link_hovered();
405 
407  }
408 
409  if (count > 1)
410  {
411  std::string count_str = to_string() << "x " << count;
412  ImGui::SetCursorScreenPos({ float(x + width - 22 - count_str.size() * 5), float(y + 7) });
413  ImGui::Text("%s", count_str.c_str());
414  }
415 
416  ImGui::SetCursorScreenPos({ float(x + 5), float(y + 5) });
417 
418  draw_content(win, x, y, t, error_message);
419 
420  if (enable_expand)
421  {
422  ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) });
423 
425 
429  string id = to_string() << textual_icons::dotdotdot << "##" << index;
430  if (ImGui::Button(id.c_str()))
431  {
432  selected = shared_from_this();
433  }
434 
435  if (ImGui::IsItemHovered())
436  win.link_hovered();
437 
439  ImGui::PopFont();
440  }
441 
442  if (enable_dismiss)
443  {
444  draw_dismiss(win, x, y);
445  }
446 
448  }
449 
450  if (expanded)
451  {
452  draw_expanded(win, error_message);
453  }
454 
455 
456  return follow_up;
457  }
458 
459  std::shared_ptr<notification_model> notifications_model::add_notification(const notification_data& n)
460  {
461  return add_notification(n, []{}, false);
462  }
463 
464  std::shared_ptr<notification_model> notifications_model::add_notification(const notification_data& n,
465  std::function<void()> custom_action, bool use_custom_action)
466  {
467  std::shared_ptr<notification_model> result = nullptr;
468  {
469  using namespace std;
470  using namespace chrono;
471  lock_guard<recursive_mutex> lock(m); // need to protect the pending_notifications queue because the insertion of notifications
472  // done from the notifications callback and proccesing and removing of old notifications done from the main thread
473 
474  for (auto&& nm : pending_notifications)
475  {
476  if (nm->category == n.get_category() && nm->message == n.get_description())
477  {
478  nm->last_interacted = std::chrono::system_clock::now();
479  nm->count++;
480  return nm;
481  }
482  }
483 
484  auto m = std::make_shared<notification_model>(n);
485  m->index = index++;
486  result = m;
487  m->timestamp = duration<double, milli>(system_clock::now().time_since_epoch()).count();
488 
490  {
491  m->pinned = true;
492  }
493 
494  if (use_custom_action)
495  {
496  m->custom_action = custom_action;
497  m->enable_click = true;
498  m->enable_expand = false;
499  m->enable_dismiss = false;
500  }
501 
502  pending_notifications.push_back(m);
503 
504  if (pending_notifications.size() > (size_t)MAX_SIZE)
505  {
506  auto it = pending_notifications.begin();
507  while (it != pending_notifications.end() && (*it)->pinned) it++;
508 
509  if (it != pending_notifications.end())
510  pending_notifications.erase(it);
511  }
512  }
513 
514  output.add_log(n.get_severity(), __FILE__, __LINE__, n.get_description());
515  return result;
516  }
517 
518  void notifications_model::add_notification(std::shared_ptr<notification_model> model)
519  {
520  {
521  using namespace std;
522  using namespace chrono;
523  lock_guard<recursive_mutex> lock(m); // need to protect the pending_notifications queue because the insertion of notifications
524  // done from the notifications callback and proccesing and removing of old notifications done from the main thread
525 
526  model->index = index++;
527  model->timestamp = duration<double, milli>(system_clock::now().time_since_epoch()).count();
528 
529  pending_notifications.push_back(model);
530 
531  if (pending_notifications.size() > (size_t)MAX_SIZE)
532  {
533  auto it = pending_notifications.begin();
534  while (it != pending_notifications.end() && (*it)->pinned) it++;
535 
536  if (it != pending_notifications.end())
537  pending_notifications.erase(it);
538  }
539  }
540 
541  output.add_log(model->severity, __FILE__, __LINE__, model->get_title());
542  }
543 
544  bool notifications_model::draw(ux_window& win, int w, int h, std::string& error_message)
545  {
546  bool modal_notification_found = false;
547  ImGui::PushFont(win.get_font());
548 
549  std::vector<std::function<void()>> follow_up;
550 
551  {
552  bool pinned_drawn = false;
553  std::lock_guard<std::recursive_mutex> lock(m);
554  if (pending_notifications.size() > 0)
555  {
556  // loop over all notifications, remove "old" ones
557  pending_notifications.erase(std::remove_if(std::begin(pending_notifications),
558  std::end(pending_notifications),
559  [&](std::shared_ptr<notification_model>& n)
560  {
561  if (n->snoozed && n->pinned)
562  {
563  n->dismissed = false;
564  n->to_close = false;
565  return true;
566  }
567  return ((n->get_age_in_ms() > n->get_max_lifetime_ms() &&
568  !n->pinned && !n->expanded) || n->to_close);
569  }), end(pending_notifications));
570 
571  auto height = 60;
572  for (auto& noti : pending_notifications)
573  {
574  modal_notification_found = modal_notification_found || noti->expanded;
575  if (pinned_drawn && noti->pinned && !noti->forced)
576  {
577  continue;
578  }
579 
580  follow_up.push_back(noti->draw(win, w, height, selected, error_message));
581 
582  if (noti->pinned) pinned_drawn = true;
583 
584  if (noti->visible)
585  height += noti->height + 4 +
586  std::min(noti->count, noti->max_stack) * noti->stack_offset;
587  }
588  }
589 
590 
591  ImGui::PushStyleColor(ImGuiCol_WindowBg, { 0, 0, 0, 0 });
592  //ImGui::Begin("Notification parent window", nullptr, flags);
593 
594  //selected.set_color_scheme(0.f);
598 
601 
602  if (selected && selected->message != "")
603  ImGui::OpenPopup("Notification from Hardware");
604  if (ImGui::BeginPopupModal("Notification from Hardware", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
605  {
606  ImGui::Text("Received the following notification:");
607 
608  auto parts = split_string(selected->message, '`');
609 
610  std::stringstream ss;
611  ss << "Timestamp: "
612  << std::fixed << selected->timestamp
613  << "\nSeverity: " << selected->severity
614  << "\nDescription: ";
615 
616  for (auto&& part : parts) ss << part << "\n";
617 
618  auto s = ss.str();
620  ImGui::InputTextMultiline("notification", const_cast<char*>(s.c_str()),
623 
624  if (ImGui::Button("OK", ImVec2(120, 0)))
625  {
626  selected->message = "";
627  selected = nullptr;
629  }
630  else
631  {
632  std::string clip = "";
633  auto lines = split_string(selected->message, '\n');
634  for (auto line : lines)
635  {
636  if (line.size() && line[0] == '$') clip += line.substr(2) + "\n";
637  }
638  if (clip != "")
639  {
640  ImGui::SameLine();
641  if (ImGui::Button(" Copy Commands "))
642  {
643  glfwSetClipboardString(win, clip.c_str());
644  }
645  if (ImGui::IsItemActive())
646  ImGui::SetTooltip("Paste the copied commands to a terminal and enter your password to run");
647  }
648  }
649 
650  ImGui::EndPopup();
651  }
652 
655 
657  }
658 
659  for (auto& action : follow_up)
660  {
661  try
662  {
663  action();
664  }
665  catch (...) {}
666  }
667 
668  ImGui::PopFont();
669 
670  return modal_notification_found;
671  }
672 
674  : process_notification_model(nullptr), _version(version)
675  {
676  enable_expand = false;
677  enable_dismiss = true;
678  update_state = 2;
679  //pinned = true;
681  }
682 
684  {
687  auto c = alpha(sensor_bg, 1 - t);
689  }
690 
691  void version_upgrade_model::draw_content(ux_window& win, int x, int y, float t, std::string& error_message)
692  {
693  if (_first)
694  {
696  _first = false;
697  }
698 
701 
702  ImGui::SetCursorScreenPos({ float(x + 20), float(y + 16) });
703  ImGui::Text("Welcome to"); ImGui::SameLine();
704  std::string txt = to_string() << "librealsense " << RS2_API_VERSION_STR << "!";
705 
707  ImGui::Text("%s", txt.c_str());
709  ImGui::PopFont();
710 
711  ImGui::SetCursorScreenPos({ float(x + 17), float(y + 41) });
712 
713  std::string link = to_string() << "https://github.com/IntelRealSense/librealsense/wiki/Release-Notes#release-" << _version;
714 
716  if (ImGui::Button("What's new"))
717  {
718  open_url(link.c_str());
719  }
721  if (ImGui::IsItemHovered())
722  {
723  win.link_hovered();
724  ImGui::SetTooltip("Open the Release Notes. Internet connection is required");
725  }
726  ImGui::SameLine();
728  ImGui::Text("in this release?");
730  }
731 
733  {
734  return 80;
735  }
736 
738  {
739  std::lock_guard<std::mutex> lock(_log_lock);
740  _log += line + "\n";
741  }
742 
744  {
745  _progress = 0;
746  _started = false;
747  _done = false;
748  _failed = false;
749  _last_error = "";
750  }
751 
753  {
754  _last_error = error;
755  _progress = 0;
756  log("\nERROR: " + error);
757  _failed = true;
758  }
759 
760  void notification_model::invoke(std::function<void()> action)
761  {
763  dispatch_queue.enqueue([&q, &action](){
764  try
765  {
766  action();
767  q.enqueue(true);
768  }
769  catch(...)
770  {
771  q.enqueue(false);
772  }
773  });
774  bool res;
775  if (!q.dequeue(&res, 100000) || !res)
776  throw std::runtime_error("Invoke operation failed!");
777  }
778 
780  {
781  auto cleanup = [invoke]() {
782  };
783 
784  log(to_string() << "Started " << _process_name << " process");
785 
786  auto me = shared_from_this();
787  std::weak_ptr<process_manager> ptr(me);
788 
789  std::thread t([ptr, cleanup, invoke]() {
790  auto self = ptr.lock();
791  if (!self) return;
792 
793  try
794  {
795  self->process_flow(cleanup, invoke);
796  }
797  catch (const error& e)
798  {
799  self->fail(error_to_string(e));
800  cleanup();
801  }
802  catch (const std::exception& ex)
803  {
804  self->fail(ex.what());
805  cleanup();
806  }
807  catch (...)
808  {
809  self->fail(to_string() << "Unknown error during " << self->_process_name << " process!");
810  cleanup();
811  }
812  });
813  t.detach();
814 
815  _started = true;
816  }
817 
819  std::function<void()> cleanup,
820  invoker invoke)
821  {
822  _progress = 5;
823  _exporter->process(_data);
824  _progress = 100;
825 
826  _done = true;
827  }
828 
829  void export_notification_model::draw_content(ux_window& win, int x, int y, float t, std::string& error_message)
830  {
831  using namespace std;
832  using namespace chrono;
833 
834  ImGui::SetCursorScreenPos({ float(x + 9), float(y + 4) });
835 
836  ImVec4 shadow{ 1.f, 1.f, 1.f, 0.1f };
837  ImGui::GetWindowDrawList()->AddRectFilled({ float(x), float(y) },
838  { float(x + width), float(y + 25) }, ImColor(shadow));
839 
840  if (update_state != STATE_COMPLETE)
841  {
842  ImGui::Text("Export in progress");
843 
844  ImGui::SetCursorScreenPos({ float(x + 10), float(y + 35) });
845 
847 
848  std::string s = to_string() << "Saving 3D view to " <<
849  get_file_name(get_manager().get_filename());
850  ImGui::Text("%s", s.c_str());
851 
853  }
854  else
855  {
856  ImGui::Text("Export Completed");
857 
858  ImGui::SetCursorScreenPos({ float(x + 10), float(y + 35) });
861  ImGui::Text("%s", txt.c_str());
862  ImGui::PopFont();
863 
864  ImGui::SetCursorScreenPos({ float(x + 40), float(y + 35) });
865  std::string s = to_string() << "Finished saving 3D view to " <<
866  get_file_name(get_manager().get_filename());
867 
868  ImGui::Text("%s", s.c_str());
869  }
870 
871  ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) });
872 
873  const auto bar_width = width - 115;
874 
875  if (update_state == STATE_IN_PROGRESS)
876  {
877  if (update_manager->done())
878  {
879  update_state = STATE_COMPLETE;
880  pinned = false;
882  }
883 
884  if (!expanded)
885  {
886  if (update_manager->failed())
887  {
888  update_manager->check_error(error_message);
889  update_state = STATE_FAILED;
890  pinned = false;
891  dismiss(false);
892  }
893 
894  draw_progress_bar(win, bar_width);
895 
896  ImGui::SetCursorScreenPos({ float(x + width - 105), float(y + height - 25) });
897  }
898  }
899  }
900 
902  {
903  return 85;
904  }
905 
907  {
909 
911 
912  ImVec4 c;
913 
914  if (update_state == STATE_COMPLETE)
915  {
916  c = alpha(saturate(light_blue, 0.7f), 1 - t);
918  }
919  else
920  {
921  c = alpha(sensor_bg, 1 - t);
923  }
924  }
925 
926  export_notification_model::export_notification_model(std::shared_ptr<export_manager> manager)
927  : process_notification_model(manager)
928  {
929  enable_expand = false;
930  expanded = false;
931  if (expanded) visible = false;
932 
933  message = "";
937 
938  pinned = true;
939  }
940 
943  {
944  enable_expand = false;
945  enable_dismiss = true;
946  pinned = true;
947  message = "Frame Metadata is a device feature allowing\n"
948  "software synchronization between different\n"
949  "camera streams.\n"
950  "It must be explicitly enabled on Windows OS\n";
951  }
952 
954  {
957  auto c = alpha(sensor_bg, 1 - t);
959  }
960 
961  void metadata_warning_model::draw_content(ux_window& win, int x, int y, float t, std::string& error_message)
962  {
963  ImGui::SetCursorScreenPos({ float(x + 9), float(y + 4) });
964 
965  ImVec4 shadow{ 1.f, 1.f, 1.f, 0.1f };
966  ImGui::GetWindowDrawList()->AddRectFilled({ float(x), float(y) },
967  { float(x + width), float(y + 25) }, ImColor(shadow));
968 
969  ImGui::Text("Frame Metadata Disabled");
970 
971  ImGui::SetCursorScreenPos({ float(x + 5), float(y + 27) });
972 
974  draw_text(get_title().c_str(), x, y, height - 50);
976 
977  ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) });
978 
979  auto sat = 1.f + sin(duration_cast<milliseconds>(system_clock::now() - created_time).count() / 700.f) * 0.1f;
982  std::string button_name = to_string() << "Enable" << "##enable_metadata" << index;
983 
984  const auto bar_width = width - 115;
985  if (ImGui::Button(button_name.c_str(), { float(bar_width), 20.f }))
986  {
988  dismiss(false);
989  }
991 
992  if (ImGui::IsItemHovered())
993  {
994  ImGui::SetTooltip("%s", "Enables metadata on connected devices (you may be prompted for administrator privileges)");
995  }
996  }
997 
999  {
1000  // Make sure we don't spam calibration remainders too often:
1001  time_t rawtime;
1002  time(&rawtime);
1003  std::string str = to_string() << "notifications." << delay_id << ".next";
1004  long long next_time = config_file::instance().get_or_default(str.c_str(), (long long)0);
1005 
1006  return rawtime < next_time;
1007  }
1008 
1010  {
1011  // Make sure we don't spam calibration remainders too often:
1012  time_t rawtime;
1013  time(&rawtime);
1014  std::string str = to_string() << "notifications." << delay_id << ".next";
1015  config_file::instance().set(str.c_str(), (long long)(rawtime + days * 60 * 60 * 24));
1016  }
1017 
1018  sw_recommended_update_alert_model::sw_recommended_update_alert_model(const std::string& current_version, const std::string& recommended_version, const std::string& recommended_version_link)
1019  : notification_model(), _current_version(current_version), _recommended_version(recommended_version), _recommended_version_link(recommended_version_link)
1020  {
1021  enable_expand = false;
1022  enable_dismiss = true;
1023  pinned = true;
1024  forced = true;
1026  message = "Current SW version: " + _current_version +"\n" +
1027  "Recommended SW version: " + _recommended_version;
1028  }
1029 
1031  {
1034  auto c = alpha(sensor_bg, 1 - t);
1036  }
1037 
1039  ux_window& win, int x, int y, float t, std::string& error_message)
1040  {
1041  ImGui::SetCursorScreenPos({ float(x + 9), float(y + 4) });
1042 
1043  ImVec4 shadow{ 1.f, 1.f, 1.f, 0.1f };
1044  ImGui::GetWindowDrawList()->AddRectFilled({ float(x), float(y) },
1045  { float(x + width), float(y + 25) },
1046  ImColor(shadow));
1047 
1048  ImGui::Text("Software Update Recommended!");
1049 
1050  ImGui::SetCursorScreenPos({ float(x + 5), float(y + 27) });
1051 
1052  draw_text(get_title().c_str(), x, y , height - 50);
1053 
1054  ImGui::SetCursorScreenPos({ float(x + 9), float(y + height - 77) });
1055 
1057  ImGui::Text("We strongly recommend you upgrade \nyour software\n");
1059 
1060  ImGui::SetCursorScreenPos({ float(x + 5), float(y + height - 25) });
1061 
1062  auto sat = 1.f
1063  + sin(duration_cast<milliseconds>(system_clock::now() - created_time).count()
1064  / 700.f)
1065  * 0.1f;
1068 
1069  const auto bar_width = width - 115;
1070 
1072  std::string button_name = to_string() << "Learn More..." << "##" << index;
1073  if (ImGui::Button(button_name.c_str(), { float(bar_width), 20.f }))
1074  {
1075  bool should_dismiss = true;
1076  try
1077  {
1079  }
1080  catch (const exception& e)
1081  {
1082  error_message = e.what();
1083  should_dismiss = false;
1084  }
1085  if (should_dismiss) dismiss(false);
1086  }
1088  if (ImGui::IsItemHovered())
1089  {
1090  win.link_hovered();
1091  ImGui::SetTooltip("Internet connection required");
1092  }
1094  }
1095 }
void enqueue(T &&item)
Definition: concurrency.h:35
float smoothstep(float x, float min, float max)
Definition: rendering.h:108
static const textual_icon lock
Definition: model-views.h:218
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val)
Definition: imgui.cpp:4650
static const ImVec4 transparent
Definition: model-views.h:44
GLenum GLuint GLenum GLsizei const GLchar * message
std::string _description
Definition: notifications.h:29
static const ImVec4 white
Definition: model-views.h:45
IMGUI_API float GetCursorPosX()
Definition: imgui.cpp:5082
IMGUI_API void AddRectFilled(const ImVec2 &a, const ImVec2 &b, ImU32 col, float rounding=0.0f, int rounding_corners=0x0F)
Definition: imgui_draw.cpp:814
virtual void set_color_scheme(float t) const
GLuint GLuint end
GLint y
std::shared_ptr< notification_model > add_notification(const notification_data &n)
GLenum GLuint GLenum severity
IMGUI_API void SetTooltip(const char *fmt,...) IM_PRINTFARGS(1)
Definition: imgui.cpp:3288
static const ImVec4 almost_white_bg
Definition: model-views.h:42
ImVec4 saturate(const ImVec4 &a, float f)
std::chrono::system_clock::time_point created_time
Definition: notifications.h:73
IMGUI_API void AddRectFilledMultiColor(const ImVec2 &a, const ImVec2 &b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left)
Definition: imgui_draw.cpp:830
GLdouble s
IMGUI_API bool InputTextMultiline(const char *label, char *buf, size_t buf_size, const ImVec2 &size=ImVec2(0, 0), ImGuiInputTextFlags flags=0, ImGuiTextEditCallback callback=NULL, void *user_data=NULL)
Definition: imgui.cpp:8223
const GLfloat * m
Definition: glext.h:6814
static const ImVec4 light_grey
Definition: model-views.h:40
Definition: imgui.h:88
IMGUI_API void PopTextWrapPos()
Definition: imgui.cpp:4592
static config_file & instance()
Definition: rs-config.cpp:80
static const ImVec4 light_blue
Definition: model-views.h:38
IMGUI_API bool IsItemActive()
Definition: imgui.cpp:3212
string _progress
Definition: log.py:34
IMGUI_API void SetNextWindowPos(const ImVec2 &pos, ImGuiSetCond cond=0)
Definition: imgui.cpp:4923
void log(rs2_log_severity severity, const char *message)
Definition: rs.hpp:149
static const textual_icon throphy
Definition: model-views.h:258
def progress(args)
Definition: log.py:43
Definition: cah-model.h:10
static metadata_helper & instance()
GLdouble GLdouble GLdouble w
GLsizei const GLchar *const * string
export_notification_model(std::shared_ptr< export_manager > manager)
IMGUI_API void PushTextWrapPos(float wrap_pos_x=0.0f)
Definition: imgui.cpp:4585
bool dequeue(T *item, unsigned int timeout_ms)
Definition: concurrency.h:69
void start(invoker invoke)
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
std::vector< std::string > split_string(std::string &input, char delim)
Definition: os.cpp:79
GLdouble n
Definition: glext.h:1966
e
Definition: rmse.py:177
static const ImVec4 grey
Definition: model-views.h:48
double get_timestamp() const
void set_color_scheme(float t) const override
virtual void draw_pre_effect(int x, int y)
Definition: notifications.h:56
std::chrono::system_clock::time_point last_moved
GLuint index
GLdouble t
virtual void enable_metadata()
void draw_pre_effect(int x, int y) override
GLboolean GLboolean GLboolean GLboolean a
rs2_notification_category get_category() const
ImFont * get_font() const
Definition: ux-window.h:64
T get_or_default(const char *key, T def) const
Definition: rs-config.h:65
std::function< void(std::function< void()>)> invoker
IMGUI_API bool BeginPopup(const char *str_id)
Definition: imgui.cpp:3455
not_this_one begin(...)
IMGUI_API void SameLine(float pos_x=0.0f, float spacing_w=-1.0f)
Definition: imgui.cpp:9246
std::string error_to_string(const error &e)
Definition: rendering.h:1583
GLdouble f
IMGUI_API ImDrawList * GetWindowDrawList()
Definition: imgui.cpp:5045
IMGUI_API void PopStyleVar(int count=1)
Definition: imgui.cpp:4675
GLsizeiptr size
void draw_progress_bar(ux_window &win, int w)
static const ImVec4 regular_blue
Definition: model-views.h:39
float w
Definition: imgui.h:100
const GLubyte * c
Definition: glext.h:12690
void invoke(std::function< void()> action)
std::function< void()> custom_action
Definition: notifications.h:65
virtual void draw_expanded(ux_window &win, std::string &error_message)
Definition: notifications.h:59
static const textual_icon link
Definition: model-views.h:257
GLdouble x
void open_url(const char *url)
Definition: os.cpp:58
rs2_log_severity _severity
Definition: notifications.h:31
std::string get_description() const
void draw_content(ux_window &win, int x, int y, float t, std::string &error_message) override
void draw(ux_window &win, int w, int progress)
virtual void dismiss(bool snooze)
Definition: notifications.h:61
GLint GLsizei GLsizei height
IMGUI_API void SetNextWindowSize(const ImVec2 &size, ImGuiSetCond cond=0)
Definition: imgui.cpp:4937
void set_color_scheme(float t) const override
static const ImVec4 sensor_bg
Definition: model-views.h:51
std::chrono::system_clock::time_point last_progress_time
IMGUI_API void SetCursorPosX(float x)
Definition: imgui.cpp:5101
static const ImVec4 sensor_header_light_blue
Definition: model-views.h:50
IMGUI_API void Text(const char *fmt,...) IM_PRINTFARGS(1)
Definition: imgui.cpp:5223
virtual int get_max_lifetime_ms() const
IMGUI_API bool Button(const char *label, const ImVec2 &size=ImVec2(0, 0))
Definition: imgui.cpp:5573
Definition: imgui.h:98
void log(std::string line)
rs2_notification_category category
Definition: notifications.h:74
void unset_color_scheme() const
IMGUI_API void EndPopup()
Definition: imgui.cpp:3489
action
Definition: enums.py:62
static const ImVec4 dark_red
Definition: model-views.h:54
ImVec4 alpha(const ImVec4 &v, float a)
static const textual_icon dotdotdot
Definition: model-views.h:256
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4 &col)
Definition: imgui.cpp:4599
static const ImVec4 black
Definition: model-views.h:43
bool try_dequeue(T *item)
Definition: concurrency.h:90
bool draw(ux_window &win, int w, int h, std::string &error_message)
virtual void draw_content(ux_window &win, int x, int y, float t, std::string &error_message)
rs2_log_severity get_severity() const
GLFWAPI void glfwSetClipboardString(GLFWwindow *window, const char *string)
Sets the clipboard to the specified string.
Definition: input.c:1261
IMGUI_API void PushFont(ImFont *font)
Definition: imgui.cpp:4539
std::chrono::system_clock::time_point last_interacted
void draw_text(const char *msg, int x, int y, int h)
void process_flow(std::function< void()> cleanup, invoker invoke) override
ImVec4 Colors[ImGuiCol_COUNT]
Definition: imgui.h:773
void draw_content(ux_window &win, int x, int y, float t, std::string &error_message) override
IMGUI_API ImVec2 GetCursorScreenPos()
Definition: imgui.cpp:5121
std::string get_file_name(const std::string &path)
Definition: os.cpp:224
GLdouble GLdouble GLdouble q
void set(const char *key, const char *value)
Definition: rs-config.cpp:15
rs2_notification_category
Category of the librealsense notification.
Definition: rs_types.h:17
static auto it
int min(int a, int b)
Definition: lz4s.c:73
IMGUI_API float GetTextLineHeight()
Definition: imgui.cpp:5027
#define _log
Definition: test-scenes.cpp:24
GLint GLsizei count
single_consumer_queue< std::function< void()> > dispatch_queue
#define RS2_API_VERSION_STR
Definition: rs.h:43
IMGUI_API bool BeginPopupModal(const char *name, bool *p_open=NULL, ImGuiWindowFlags extra_flags=0)
Definition: imgui.cpp:3465
IMGUI_API bool Selectable(const char *label, bool selected=false, ImGuiSelectableFlags flags=0, const ImVec2 &size=ImVec2(0, 0))
Definition: imgui.cpp:8550
void set_color_scheme(float t) const override
float rs2_vector::* pos
IMGUI_API void SetCursorScreenPos(const ImVec2 &pos)
Definition: imgui.cpp:5127
int i
GLuint res
Definition: glext.h:8856
IMGUI_API ImGuiStyle & GetStyle()
Definition: imgui.cpp:2019
IMGUI_API void CloseCurrentPopup()
Definition: imgui.cpp:3408
ImFont * get_large_font() const
Definition: ux-window.h:62
IMGUI_API void OpenPopup(const char *str_id)
Definition: imgui.cpp:3343
virtual void draw_dismiss(ux_window &win, int x, int y)
std::shared_ptr< process_manager > update_manager
IMGUI_API void AddRect(const ImVec2 &a, const ImVec2 &b, ImU32 col, float rounding=0.0f, int rounding_corners=0x0F, float thickness=1.0f)
Definition: imgui_draw.cpp:806
void fail(std::string error)
rs2_log_severity
Severity of the librealsense logger.
Definition: rs_types.h:153
GLuint64EXT * result
Definition: glext.h:10921
void link_hovered()
Definition: ux-window.cpp:166
std::function< void()> draw(ux_window &win, int w, int y, std::shared_ptr< notification_model > &selected, std::string &error_message)
IMGUI_API bool IsItemHovered()
Definition: imgui.cpp:3200
GLint GLsizei width
IMGUI_API void PopFont()
Definition: imgui.cpp:4549
IMGUI_API void PopStyleColor(int count=1)
Definition: imgui.cpp:4609
rs2::mouse_info & get_mouse()
Definition: ux-window.h:66
void draw_content(ux_window &win, int x, int y, float t, std::string &error_message) override
rs2_notification_category _category
Definition: notifications.h:32
std::string to_string(T value)
double get_age_in_ms(bool total=false) const


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:22