WizardDialog.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (c) 2021, Nick Vella <nick@nxk.io>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibGUI/BoxLayout.h>
  7. #include <LibGUI/Button.h>
  8. #include <LibGUI/SeparatorWidget.h>
  9. #include <LibGUI/Widget.h>
  10. #include <LibGUI/Wizards/AbstractWizardPage.h>
  11. #include <LibGUI/Wizards/WizardDialog.h>
  12. #include <LibGfx/Orientation.h>
  13. #include <LibGfx/SystemTheme.h>
  14. namespace GUI {
  15. WizardDialog::WizardDialog(Window* parent_window)
  16. : Dialog(parent_window)
  17. , m_page_stack()
  18. {
  19. resize(500, 360);
  20. set_title(String::formatted("Sample wizard"));
  21. set_resizable(false);
  22. if (parent_window)
  23. set_icon(parent_window->icon());
  24. auto& main_widget = set_main_widget<Widget>();
  25. main_widget.set_fill_with_background_color(true);
  26. main_widget.set_layout<VerticalBoxLayout>();
  27. main_widget.layout()->set_spacing(0);
  28. m_page_container_widget = main_widget.add<Widget>();
  29. m_page_container_widget->set_fixed_size(500, 315);
  30. m_page_container_widget->set_layout<VerticalBoxLayout>();
  31. auto& separator = main_widget.add<SeparatorWidget>(Gfx::Orientation::Horizontal);
  32. separator.set_fixed_height(2);
  33. auto& nav_container_widget = main_widget.add<Widget>();
  34. nav_container_widget.set_layout<HorizontalBoxLayout>();
  35. nav_container_widget.set_fixed_height(42);
  36. nav_container_widget.layout()->set_margins({ 0, 10 });
  37. nav_container_widget.layout()->set_spacing(0);
  38. nav_container_widget.layout()->add_spacer();
  39. m_back_button = nav_container_widget.add<Button>("< Back");
  40. m_back_button->set_fixed_width(75);
  41. m_back_button->on_click = [&](auto) {
  42. pop_page();
  43. };
  44. m_next_button = nav_container_widget.add<Button>("Next >");
  45. m_next_button->set_fixed_width(75);
  46. m_next_button->on_click = [&](auto) {
  47. VERIFY(has_pages());
  48. if (!current_page().can_go_next())
  49. return done(ExecOK);
  50. auto next_page = current_page().next_page();
  51. if (!next_page)
  52. return done(ExecOK);
  53. push_page(*next_page);
  54. };
  55. auto& button_spacer = nav_container_widget.add<Widget>();
  56. button_spacer.set_fixed_width(10);
  57. m_cancel_button = nav_container_widget.add<Button>("Cancel");
  58. m_cancel_button->set_fixed_width(75);
  59. m_cancel_button->on_click = [&](auto) {
  60. handle_cancel();
  61. };
  62. update_navigation();
  63. }
  64. WizardDialog::~WizardDialog()
  65. {
  66. }
  67. void WizardDialog::push_page(AbstractWizardPage& page)
  68. {
  69. if (!m_page_stack.is_empty())
  70. m_page_stack.last().page_leave();
  71. m_page_stack.append(page);
  72. m_page_container_widget->remove_all_children();
  73. m_page_container_widget->add_child(page);
  74. update_navigation();
  75. page.page_enter();
  76. }
  77. void WizardDialog::replace_page(AbstractWizardPage& page)
  78. {
  79. if (!m_page_stack.is_empty())
  80. m_page_stack.take_last()->page_leave();
  81. m_page_stack.append(page);
  82. m_page_container_widget->remove_all_children();
  83. m_page_container_widget->add_child(page);
  84. update_navigation();
  85. page.page_enter();
  86. }
  87. void WizardDialog::pop_page()
  88. {
  89. if (m_page_stack.size() <= 1)
  90. return;
  91. auto page = m_page_stack.take_last();
  92. page->page_leave();
  93. m_page_container_widget->remove_all_children();
  94. m_page_container_widget->add_child(m_page_stack.last());
  95. update_navigation();
  96. m_page_stack.last().page_enter();
  97. }
  98. void WizardDialog::update_navigation()
  99. {
  100. m_back_button->set_enabled(m_page_stack.size() > 1);
  101. if (has_pages()) {
  102. m_next_button->set_enabled(current_page().is_final_page() || current_page().can_go_next());
  103. m_next_button->set_text(current_page().is_final_page() ? "Finish" : "Next >");
  104. } else {
  105. m_next_button->set_text("Next >");
  106. m_next_button->set_enabled(false);
  107. }
  108. }
  109. AbstractWizardPage& WizardDialog::current_page()
  110. {
  111. VERIFY(has_pages());
  112. return m_page_stack.last();
  113. }
  114. void WizardDialog::handle_cancel()
  115. {
  116. if (on_cancel)
  117. return on_cancel();
  118. done(ExecCancel);
  119. }
  120. }