main.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright notice,
  13. * this list of conditions and the following disclaimer in the documentation
  14. * and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  24. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <AK/NonnullRefPtr.h>
  28. #include <AK/Vector.h>
  29. #include <LibCore/Timer.h>
  30. #include <LibGUI/AboutDialog.h>
  31. #include <LibGUI/Action.h>
  32. #include <LibGUI/Application.h>
  33. #include <LibGUI/BoxLayout.h>
  34. #include <LibGUI/Button.h>
  35. #include <LibGUI/CheckBox.h>
  36. #include <LibGUI/ColorInput.h>
  37. #include <LibGUI/ComboBox.h>
  38. #include <LibGUI/FontDatabase.h>
  39. #include <LibGUI/GroupBox.h>
  40. #include <LibGUI/Icon.h>
  41. #include <LibGUI/Image.h>
  42. #include <LibGUI/InputBox.h>
  43. #include <LibGUI/Label.h>
  44. #include <LibGUI/ListView.h>
  45. #include <LibGUI/Menu.h>
  46. #include <LibGUI/MenuBar.h>
  47. #include <LibGUI/MessageBox.h>
  48. #include <LibGUI/Model.h>
  49. #include <LibGUI/ProgressBar.h>
  50. #include <LibGUI/RadioButton.h>
  51. #include <LibGUI/ScrollBar.h>
  52. #include <LibGUI/Slider.h>
  53. #include <LibGUI/SpinBox.h>
  54. #include <LibGUI/TabWidget.h>
  55. #include <LibGUI/TextBox.h>
  56. #include <LibGUI/Variant.h>
  57. #include <LibGUI/Widget.h>
  58. #include <LibGUI/Window.h>
  59. template<typename T>
  60. class ListViewModel final : public GUI::Model {
  61. public:
  62. static NonnullRefPtr<ListViewModel> create(Vector<T>& model_items) { return adopt(*new ListViewModel(model_items)); }
  63. virtual ~ListViewModel() override { }
  64. virtual int row_count(const GUI::ModelIndex&) const override { return m_model_items.size(); }
  65. virtual int column_count(const GUI::ModelIndex&) const override { return 1; }
  66. virtual GUI::Variant data(const GUI::ModelIndex& index, Role role = Role::Display) const override
  67. {
  68. ASSERT(index.is_valid());
  69. ASSERT(index.column() == 0);
  70. if (role == Role::Display)
  71. return m_model_items.at(index.row());
  72. return {};
  73. }
  74. virtual void update() override { did_update(); }
  75. private:
  76. explicit ListViewModel(Vector<String>& model_items)
  77. : m_model_items(model_items)
  78. {
  79. }
  80. Vector<T>& m_model_items;
  81. };
  82. int main(int argc, char** argv)
  83. {
  84. auto app = GUI::Application::construct(argc, argv);
  85. auto app_icon = GUI::Icon::default_icon("app-widget-gallery");
  86. auto window = GUI::Window::construct();
  87. window->set_rect(100, 100, 430, 480);
  88. window->set_title("Widget Gallery");
  89. window->set_icon(app_icon.bitmap_for_size(16));
  90. auto menubar = GUI::MenuBar::construct();
  91. auto& app_menu = menubar->add_menu("Widget Gallery");
  92. app_menu.add_action(GUI::CommonActions::make_quit_action([&](auto&) { app->quit(); }));
  93. auto& help_menu = menubar->add_menu("Help");
  94. help_menu.add_action(GUI::Action::create("About", [&](auto&) {
  95. GUI::AboutDialog::show("Widget Gallery", app_icon.bitmap_for_size(32), window);
  96. }));
  97. auto& root_widget = window->set_main_widget<GUI::Widget>();
  98. root_widget.set_fill_with_background_color(true);
  99. root_widget.set_layout<GUI::VerticalBoxLayout>();
  100. root_widget.layout()->set_margins({ 4, 4, 4, 4 });
  101. auto& tab_widget = root_widget.add<GUI::TabWidget>();
  102. auto& tab_basic = tab_widget.add_tab<GUI::Widget>("Basic");
  103. tab_basic.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  104. tab_basic.set_layout<GUI::VerticalBoxLayout>();
  105. tab_basic.layout()->set_margins({ 8, 8, 8, 8 });
  106. tab_basic.layout()->set_spacing(8);
  107. auto& radio_group_box = tab_basic.add<GUI::GroupBox>();
  108. radio_group_box.set_layout<GUI::HorizontalBoxLayout>();
  109. radio_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  110. radio_group_box.layout()->set_margins({ 4, 4, 4, 4 });
  111. auto& radio_button_vert_container = radio_group_box.add<GUI::Widget>();
  112. radio_button_vert_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  113. radio_button_vert_container.set_layout<GUI::VerticalBoxLayout>();
  114. radio_button_vert_container.layout()->set_margins({ 4, 9, 4, 4 });
  115. auto& radio_button_container = radio_button_vert_container.add<GUI::Widget>();
  116. radio_button_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  117. radio_button_container.set_layout<GUI::HorizontalBoxLayout>();
  118. auto& radio1 = radio_button_container.add<GUI::RadioButton>("RadioButton 1");
  119. radio1.set_checked(true);
  120. auto& radio2 = radio_button_container.add<GUI::RadioButton>("RadioButton 2");
  121. (void)radio2;
  122. auto& radio3 = radio_button_container.add<GUI::RadioButton>("RadioButton 3");
  123. radio3.set_enabled(false);
  124. auto& checklabelspin_container = tab_basic.add<GUI::Widget>();
  125. checklabelspin_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  126. checklabelspin_container.set_layout<GUI::HorizontalBoxLayout>();
  127. auto& check_group_box = checklabelspin_container.add<GUI::GroupBox>();
  128. check_group_box.set_layout<GUI::HorizontalBoxLayout>();
  129. check_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  130. check_group_box.layout()->set_margins({ 4, 12, 4, 4 });
  131. auto& checkbox_container = check_group_box.add<GUI::Widget>();
  132. checkbox_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  133. checkbox_container.set_layout<GUI::VerticalBoxLayout>();
  134. checkbox_container.layout()->set_margins({ 4, 4, 4, 4 });
  135. auto& label_container = check_group_box.add<GUI::Widget>();
  136. label_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  137. label_container.set_layout<GUI::VerticalBoxLayout>();
  138. label_container.layout()->set_margins({ 4, 4, 4, 4 });
  139. auto& spin_group_box = checklabelspin_container.add<GUI::GroupBox>();
  140. spin_group_box.set_layout<GUI::HorizontalBoxLayout>();
  141. spin_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  142. spin_group_box.layout()->set_margins({ 4, 4, 4, 4 });
  143. spin_group_box.set_title("Spin boxes");
  144. auto& spin_container = spin_group_box.add<GUI::Widget>();
  145. spin_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  146. spin_container.set_layout<GUI::VerticalBoxLayout>();
  147. spin_container.layout()->set_margins({ 4, 12, 4, 4 });
  148. auto& checkbox1 = checkbox_container.add<GUI::CheckBox>("CheckBox 1");
  149. checkbox1.set_checked(true);
  150. auto& checkbox2 = checkbox_container.add<GUI::CheckBox>("CheckBox 2");
  151. checkbox2.set_enabled(false);
  152. auto& label1 = label_container.add<GUI::Label>("Label 1");
  153. (void)label1;
  154. auto& label2 = label_container.add<GUI::Label>("Label 2");
  155. label2.set_enabled(false);
  156. auto& spinbox1 = spin_container.add<GUI::SpinBox>();
  157. (void)spinbox1;
  158. auto& spinbox2 = spin_container.add<GUI::SpinBox>();
  159. spinbox2.set_enabled(false);
  160. auto& button_container = tab_basic.add<GUI::Widget>();
  161. button_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  162. button_container.set_layout<GUI::HorizontalBoxLayout>();
  163. auto& button_vert1_container = button_container.add<GUI::Widget>();
  164. button_vert1_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  165. button_vert1_container.set_layout<GUI::VerticalBoxLayout>();
  166. auto& button_vert2_container = button_container.add<GUI::Widget>();
  167. button_vert2_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  168. button_vert2_container.set_layout<GUI::VerticalBoxLayout>();
  169. auto& button1 = button_vert1_container.add<GUI::Button>("Button 1");
  170. button1.set_icon(Gfx::Bitmap::load_from_file("/res/icons/kill16.png"));
  171. auto& button2 = button_vert1_container.add<GUI::Button>("Button 2");
  172. button2.set_icon(Gfx::Bitmap::load_from_file("/res/icons/kill16.png"));
  173. button2.set_enabled(false);
  174. auto& button3 = button_vert2_container.add<GUI::Button>("\xF0\x9F\x98\x88 Button 3");
  175. (void)button3;
  176. auto& button4 = button_vert2_container.add<GUI::Button>("\xF0\x9F\x8D\x86 Button 4");
  177. button4.set_enabled(false);
  178. auto& text_group_box = tab_basic.add<GUI::GroupBox>();
  179. text_group_box.set_layout<GUI::HorizontalBoxLayout>();
  180. text_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  181. text_group_box.set_title("Text boxes");
  182. text_group_box.layout()->set_margins({ 8, 4, 8, 4 });
  183. auto& textbox_vert1_container = text_group_box.add<GUI::Widget>();
  184. textbox_vert1_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  185. textbox_vert1_container.set_layout<GUI::VerticalBoxLayout>();
  186. textbox_vert1_container.layout()->set_margins({ 1, 12, 1, 4 });
  187. auto& textbox_vert2_container = text_group_box.add<GUI::Widget>();
  188. textbox_vert2_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  189. textbox_vert2_container.set_layout<GUI::VerticalBoxLayout>();
  190. textbox_vert2_container.layout()->set_margins({ 1, 12, 1, 4 });
  191. auto& textbox1 = textbox_vert1_container.add<GUI::TextBox>();
  192. textbox1.set_text("Editable");
  193. auto& textbox2 = textbox_vert1_container.add<GUI::TextBox>();
  194. textbox2.set_text("Disabled");
  195. textbox2.set_enabled(false);
  196. auto& textbox3 = textbox_vert2_container.add<GUI::TextBox>();
  197. textbox3.set_text("Read only");
  198. textbox3.set_mode(GUI::TextEditor::ReadOnly);
  199. auto& textbox4 = textbox_vert2_container.add<GUI::TextBox>();
  200. textbox4.set_text("Display only");
  201. textbox4.set_mode(GUI::TextEditor::DisplayOnly);
  202. auto& combocolor_container = tab_basic.add<GUI::Widget>();
  203. combocolor_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  204. combocolor_container.set_layout<GUI::HorizontalBoxLayout>();
  205. auto& combo_group_box = combocolor_container.add<GUI::GroupBox>();
  206. combo_group_box.set_layout<GUI::HorizontalBoxLayout>();
  207. combo_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  208. combo_group_box.layout()->set_margins({ 4, 4, 4, 4 });
  209. combo_group_box.set_title("Combo boxes");
  210. auto& color_group_box = combocolor_container.add<GUI::GroupBox>();
  211. color_group_box.set_layout<GUI::HorizontalBoxLayout>();
  212. color_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  213. color_group_box.layout()->set_margins({ 4, 4, 4, 4 });
  214. color_group_box.set_title("Color pickers");
  215. auto& combo_container = combo_group_box.add<GUI::Widget>();
  216. combo_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  217. combo_container.set_layout<GUI::VerticalBoxLayout>();
  218. combo_container.layout()->set_margins({ 4, 12, 4, 4 });
  219. auto& color_container = color_group_box.add<GUI::Widget>();
  220. color_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  221. color_container.set_layout<GUI::VerticalBoxLayout>();
  222. color_container.layout()->set_margins({ 4, 12, 4, 4 });
  223. Vector<String> model_items;
  224. model_items.append("Yes");
  225. model_items.append("No");
  226. model_items.append("Maybe");
  227. model_items.append("I don't know");
  228. model_items.append("Can you repeat the question?");
  229. auto& combobox1 = combo_container.add<GUI::ComboBox>();
  230. combobox1.set_only_allow_values_from_model(true);
  231. combobox1.set_model(*ListViewModel<AK::String>::create(model_items));
  232. auto& combobox2 = combo_container.add<GUI::ComboBox>();
  233. combobox2.set_enabled(false);
  234. auto& color_input_enabled = color_container.add<GUI::ColorInput>();
  235. color_input_enabled.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  236. color_input_enabled.set_color(Color::from_string("#961605ff").value());
  237. color_input_enabled.set_color_picker_title("Select color for desktop");
  238. auto& color_input_disabled = color_container.add<GUI::ColorInput>();
  239. color_input_disabled.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  240. color_input_disabled.set_color(Color::from_string("#961605ff").value());
  241. color_input_disabled.set_enabled(false);
  242. auto& tab_others = tab_widget.add_tab<GUI::Widget>("Sliders");
  243. tab_others.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  244. tab_others.set_layout<GUI::VerticalBoxLayout>();
  245. tab_others.layout()->set_margins({ 8, 8, 8, 8 });
  246. tab_others.layout()->set_spacing(8);
  247. auto& vert_slider_group_box = tab_others.add<GUI::GroupBox>();
  248. vert_slider_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  249. vert_slider_group_box.set_layout<GUI::HorizontalBoxLayout>();
  250. vert_slider_group_box.layout()->set_margins({ 4, 28, 4, 4 });
  251. vert_slider_group_box.set_title("Vertical sliders");
  252. auto& vslider1 = vert_slider_group_box.add<GUI::VerticalSlider>();
  253. vslider1.set_tooltip("Fixed");
  254. auto& vslider2 = vert_slider_group_box.add<GUI::VerticalSlider>();
  255. vslider2.set_enabled(false);
  256. vslider2.set_tooltip("Disabled");
  257. auto& vslider3 = vert_slider_group_box.add<GUI::VerticalSlider>();
  258. vslider3.set_max(5);
  259. vslider3.set_knob_size_mode(GUI::Slider::KnobSizeMode::Proportional);
  260. vslider3.set_tooltip("Proportional");
  261. auto& horizontal_slider_group_box = tab_others.add<GUI::GroupBox>();
  262. horizontal_slider_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  263. horizontal_slider_group_box.set_layout<GUI::VerticalBoxLayout>();
  264. horizontal_slider_group_box.layout()->set_margins({ 4, 12, 4, 4 });
  265. horizontal_slider_group_box.set_title("Horizontal sliders");
  266. auto& horizontal_slider_container = horizontal_slider_group_box.add<GUI::Widget>();
  267. horizontal_slider_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  268. horizontal_slider_container.set_layout<GUI::HorizontalBoxLayout>();
  269. horizontal_slider_container.layout()->set_margins({ 4, 4, 4, 4 });
  270. auto& horizontal_slider_container2 = horizontal_slider_group_box.add<GUI::Widget>();
  271. horizontal_slider_container2.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  272. horizontal_slider_container2.set_layout<GUI::HorizontalBoxLayout>();
  273. horizontal_slider_container2.layout()->set_margins({ 4, 4, 4, 4 });
  274. auto& slider1 = horizontal_slider_container.add<GUI::HorizontalSlider>();
  275. (void)slider1;
  276. auto& slider2 = horizontal_slider_container.add<GUI::HorizontalSlider>();
  277. slider2.set_enabled(false);
  278. slider2.set_value(50);
  279. auto& slider3 = horizontal_slider_container.add<GUI::HorizontalSlider>();
  280. slider3.set_max(5);
  281. slider3.set_knob_size_mode(GUI::Slider::KnobSizeMode::Proportional);
  282. auto& progress1 = horizontal_slider_container2.add<GUI::ProgressBar>();
  283. progress1.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  284. progress1.set_preferred_size(0, 28);
  285. slider1.on_value_changed = [&](int value) {
  286. progress1.set_value(value);
  287. if (!(value % (100 / slider3.max())))
  288. slider3.set_value(value / (100 / slider3.max()));
  289. };
  290. slider3.on_value_changed = [&](int value) {
  291. progress1.set_value((value * 100) / slider3.max());
  292. slider1.set_value((value * 100) / slider3.max());
  293. };
  294. auto& scroll_group_box = tab_others.add<GUI::GroupBox>();
  295. scroll_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  296. scroll_group_box.set_layout<GUI::VerticalBoxLayout>();
  297. scroll_group_box.layout()->set_margins({ 12, 12, 12, 12 });
  298. scroll_group_box.set_title("Scrollbars");
  299. scroll_group_box.layout()->add_spacer();
  300. auto& scrollbar1 = scroll_group_box.add<GUI::ScrollBar>(Orientation::Horizontal);
  301. scrollbar1.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  302. scrollbar1.set_preferred_size(0, 16);
  303. scrollbar1.set_min(0);
  304. scrollbar1.set_max(100);
  305. scrollbar1.set_value(50);
  306. scroll_group_box.layout()->add_spacer();
  307. auto& scrollbar2 = scroll_group_box.add<GUI::ScrollBar>(Orientation::Horizontal);
  308. scrollbar2.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  309. scrollbar2.set_preferred_size(0, 16);
  310. scrollbar2.set_enabled(false);
  311. scroll_group_box.layout()->add_spacer();
  312. auto& tab_modals = tab_widget.add_tab<GUI::Widget>("Modals");
  313. tab_modals.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  314. tab_modals.set_layout<GUI::VerticalBoxLayout>();
  315. tab_modals.layout()->set_margins({ 8, 8, 8, 8 });
  316. tab_modals.layout()->set_spacing(8);
  317. GUI::MessageBox::Type msg_box_type = GUI::MessageBox::Type::Error;
  318. auto& msgbox_group_container = tab_modals.add<GUI::GroupBox>("Message boxes");
  319. msgbox_group_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  320. msgbox_group_container.set_layout<GUI::VerticalBoxLayout>();
  321. msgbox_group_container.layout()->set_margins({ 4, 12, 4, 2 });
  322. auto& msgbox_radio_container = msgbox_group_container.add<GUI::Widget>();
  323. msgbox_radio_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  324. msgbox_radio_container.set_layout<GUI::HorizontalBoxLayout>();
  325. msgbox_radio_container.layout()->set_margins({ 4, 12, 4, 4 });
  326. auto& icon_group_box = msgbox_radio_container.add<GUI::GroupBox>("Icon");
  327. icon_group_box.set_layout<GUI::VerticalBoxLayout>();
  328. icon_group_box.layout()->set_margins({ 4, 16, 4, 4 });
  329. icon_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  330. auto& radio_none = icon_group_box.add<GUI::RadioButton>("None");
  331. radio_none.on_checked = [&](bool) {
  332. msg_box_type = GUI::MessageBox::Type::None;
  333. };
  334. auto& radio_information = icon_group_box.add<GUI::RadioButton>("\xE2\x84\xB9 Information");
  335. radio_information.on_checked = [&](bool) {
  336. msg_box_type = GUI::MessageBox::Type::Information;
  337. };
  338. auto& question_information = icon_group_box.add<GUI::RadioButton>("\xF0\x9F\xA4\x94 Question");
  339. question_information.on_checked = [&](bool) {
  340. msg_box_type = GUI::MessageBox::Type::Question;
  341. };
  342. auto& radio_warning = icon_group_box.add<GUI::RadioButton>("\xE2\x9A\xA0 Warning");
  343. radio_warning.on_checked = [&](bool) {
  344. msg_box_type = GUI::MessageBox::Type::Warning;
  345. };
  346. auto& radio_error = icon_group_box.add<GUI::RadioButton>("\xE2\x9D\x8C Error");
  347. radio_error.set_checked(true);
  348. radio_error.on_checked = [&](bool) {
  349. msg_box_type = GUI::MessageBox::Type::Error;
  350. };
  351. auto& button_group_box = msgbox_radio_container.add<GUI::GroupBox>("Buttons");
  352. button_group_box.set_layout<GUI::VerticalBoxLayout>();
  353. button_group_box.layout()->set_margins({ 4, 16, 4, 4 });
  354. button_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  355. GUI::MessageBox::InputType msg_box_input_type = GUI::MessageBox::InputType::OKCancel;
  356. auto& radio_ok = button_group_box.add<GUI::RadioButton>("OK");
  357. radio_ok.on_checked = [&](bool) {
  358. msg_box_input_type = GUI::MessageBox::InputType::OK;
  359. };
  360. auto& radio_ok_cancel = button_group_box.add<GUI::RadioButton>("OK & Cancel");
  361. radio_ok_cancel.set_checked(true);
  362. radio_ok_cancel.on_checked = [&](bool) {
  363. msg_box_input_type = GUI::MessageBox::InputType::OKCancel;
  364. };
  365. auto& radio_yes_no = button_group_box.add<GUI::RadioButton>("Yes & No");
  366. radio_yes_no.on_checked = [&](bool) {
  367. msg_box_input_type = GUI::MessageBox::InputType::YesNo;
  368. };
  369. auto& radio_yes_no_cancel = button_group_box.add<GUI::RadioButton>("Yes & No & Cancel");
  370. radio_yes_no_cancel.on_checked = [&](bool) {
  371. msg_box_input_type = GUI::MessageBox::InputType::YesNoCancel;
  372. };
  373. auto& msgbox_text_container = msgbox_group_container.add<GUI::Widget>();
  374. msgbox_text_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  375. msgbox_text_container.set_layout<GUI::VerticalBoxLayout>();
  376. msgbox_text_container.set_preferred_size(0, 100);
  377. msgbox_text_container.layout()->set_margins({ 4, 8, 4, 8 });
  378. auto& title_textbox = msgbox_text_container.add<GUI::TextBox>();
  379. title_textbox.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  380. title_textbox.set_preferred_size(0, 24);
  381. title_textbox.set_text("Demo Title");
  382. auto& content_textbox = msgbox_text_container.add<GUI::TextBox>();
  383. content_textbox.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  384. content_textbox.set_preferred_size(0, 24);
  385. content_textbox.set_text("Demo text for message box.");
  386. auto& msgbox_button = msgbox_text_container.add<GUI::Button>("Create");
  387. msgbox_button.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  388. msgbox_button.set_preferred_size(0, 30);
  389. msgbox_button.on_click = [&](auto) {
  390. GUI::MessageBox::show(window, content_textbox.text(), title_textbox.text(), msg_box_type, msg_box_input_type);
  391. };
  392. auto& input_group_box = tab_modals.add<GUI::GroupBox>("Input boxes");
  393. input_group_box.set_layout<GUI::VerticalBoxLayout>();
  394. input_group_box.layout()->set_margins({ 4, 12, 4, 4 });
  395. input_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  396. input_group_box.set_preferred_size(0, 160);
  397. input_group_box.layout()->add_spacer();
  398. auto& input_label = input_group_box.add<GUI::Label>("Valued user input goes here.");
  399. input_label.set_font(Gfx::Font::default_bold_font());
  400. input_group_box.layout()->add_spacer();
  401. auto& input_button_container = input_group_box.add<GUI::Widget>();
  402. input_button_container.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  403. input_button_container.set_layout<GUI::VerticalBoxLayout>();
  404. input_button_container.layout()->set_margins({ 4, 0, 4, 0 });
  405. auto& input_button = input_button_container.add<GUI::Button>("Input...");
  406. input_button.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed);
  407. input_button.set_preferred_size(0, 30);
  408. String value;
  409. input_button.on_click = [&](auto) {
  410. if (GUI::InputBox::show(value, window, "Enter input:", "Input Box") == GUI::InputBox::ExecOK && !value.is_empty())
  411. input_label.set_text(value);
  412. };
  413. auto& tab_image = tab_widget.add_tab<GUI::Widget>("Images");
  414. tab_image.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  415. tab_image.set_layout<GUI::VerticalBoxLayout>();
  416. tab_image.layout()->set_margins({ 8, 8, 8, 8 });
  417. tab_image.layout()->set_spacing(8);
  418. auto& banner_image = tab_image.add<GUI::Image>();
  419. banner_image.set_frame_thickness(2);
  420. banner_image.load_from_file("/res/brand-banner.png");
  421. auto& gif_animation_image = tab_image.add<GUI::Image>();
  422. gif_animation_image.load_from_file("/res/download-animation.gif");
  423. auto& tab_cursors = tab_widget.add_tab<GUI::Widget>("Cursors");
  424. tab_cursors.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  425. tab_cursors.set_layout<GUI::VerticalBoxLayout>();
  426. tab_cursors.layout()->set_margins({ 8, 8, 8, 8 });
  427. tab_cursors.layout()->set_spacing(8);
  428. auto& cursor_group_box = tab_cursors.add<GUI::GroupBox>("Cursor");
  429. cursor_group_box.set_layout<GUI::VerticalBoxLayout>();
  430. cursor_group_box.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fill);
  431. cursor_group_box.layout()->set_margins({ 4, 12, 4, 4 });
  432. auto& radio_cursor_none = cursor_group_box.add<GUI::RadioButton>("None");
  433. radio_cursor_none.set_checked(true);
  434. radio_cursor_none.on_checked = [&](bool) {
  435. window->set_override_cursor(GUI::StandardCursor::None);
  436. };
  437. auto& radio_cursor_arrow = cursor_group_box.add<GUI::RadioButton>("Arrow");
  438. radio_cursor_arrow.on_checked = [&](bool) {
  439. window->set_override_cursor(GUI::StandardCursor::Arrow);
  440. };
  441. auto& radio_cursor_i_beam = cursor_group_box.add<GUI::RadioButton>("IBeam");
  442. radio_cursor_i_beam.on_checked = [&](bool) {
  443. window->set_override_cursor(GUI::StandardCursor::IBeam);
  444. };
  445. auto& radio_cursor_resize_horizontal = cursor_group_box.add<GUI::RadioButton>("ResizeHorizontal");
  446. radio_cursor_resize_horizontal.on_checked = [&](bool) {
  447. window->set_override_cursor(GUI::StandardCursor::ResizeHorizontal);
  448. };
  449. auto& radio_cursor_resize_vertical = cursor_group_box.add<GUI::RadioButton>("ResizeVertical");
  450. radio_cursor_resize_vertical.on_checked = [&](bool) {
  451. window->set_override_cursor(GUI::StandardCursor::ResizeVertical);
  452. };
  453. auto& radio_cursor_resize_diagonal_tlbr = cursor_group_box.add<GUI::RadioButton>("ResizeDiagonalTLBR");
  454. radio_cursor_resize_diagonal_tlbr.on_checked = [&](bool) {
  455. window->set_override_cursor(GUI::StandardCursor::ResizeDiagonalTLBR);
  456. };
  457. auto& radio_cursor_resize_diagonal_bltr = cursor_group_box.add<GUI::RadioButton>("ResizeDiagonalBLTR");
  458. radio_cursor_resize_diagonal_bltr.on_checked = [&](bool) {
  459. window->set_override_cursor(GUI::StandardCursor::ResizeDiagonalBLTR);
  460. };
  461. auto& radio_cursor_resize_column = cursor_group_box.add<GUI::RadioButton>("ResizeColumn");
  462. radio_cursor_resize_column.on_checked = [&](bool) {
  463. window->set_override_cursor(GUI::StandardCursor::ResizeColumn);
  464. };
  465. auto& radio_cursor_resize_row = cursor_group_box.add<GUI::RadioButton>("ResizeRow");
  466. radio_cursor_resize_row.on_checked = [&](bool) {
  467. window->set_override_cursor(GUI::StandardCursor::ResizeRow);
  468. };
  469. auto& radio_cursor_hand = cursor_group_box.add<GUI::RadioButton>("Hand");
  470. radio_cursor_hand.on_checked = [&](bool) {
  471. window->set_override_cursor(GUI::StandardCursor::Hand);
  472. };
  473. auto& radio_cursor_help = cursor_group_box.add<GUI::RadioButton>("Help");
  474. radio_cursor_help.on_checked = [&](bool) {
  475. window->set_override_cursor(GUI::StandardCursor::Help);
  476. };
  477. auto& radio_cursor_drag = cursor_group_box.add<GUI::RadioButton>("Drag");
  478. radio_cursor_drag.on_checked = [&](bool) {
  479. window->set_override_cursor(GUI::StandardCursor::Drag);
  480. };
  481. auto& radio_cursor_move = cursor_group_box.add<GUI::RadioButton>("Move");
  482. radio_cursor_move.on_checked = [&](bool) {
  483. window->set_override_cursor(GUI::StandardCursor::Move);
  484. };
  485. auto& radio_cursor_wait = cursor_group_box.add<GUI::RadioButton>("Wait");
  486. radio_cursor_wait.on_checked = [&](bool) {
  487. window->set_override_cursor(GUI::StandardCursor::Wait);
  488. };
  489. app->set_menubar(move(menubar));
  490. window->show();
  491. return app->exec();
  492. }