WizardDialog.cpp 4.1 KB

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