Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <LibGUI/BoxLayout.h>
9#include <LibGUI/StackWidget.h>
10#include <LibGUI/Window.h>
11
12REGISTER_WIDGET(GUI, StackWidget);
13
14namespace GUI {
15
16void StackWidget::set_active_widget(Widget* widget)
17{
18 if (widget == m_active_widget)
19 return;
20
21 bool active_widget_had_focus = m_active_widget && m_active_widget->has_focus_within();
22
23 if (m_active_widget)
24 m_active_widget->set_visible(false);
25 m_active_widget = widget;
26 if (m_active_widget) {
27 m_active_widget->set_relative_rect(rect());
28 if (active_widget_had_focus)
29 m_active_widget->set_focus(true);
30 m_active_widget->set_visible(true);
31 }
32
33 set_focus_proxy(m_active_widget);
34
35 if (on_active_widget_change)
36 on_active_widget_change(m_active_widget);
37}
38
39void StackWidget::resize_event(ResizeEvent& event)
40{
41 if (!m_active_widget)
42 return;
43 m_active_widget->set_relative_rect({ {}, event.size() });
44}
45
46void StackWidget::child_event(Core::ChildEvent& event)
47{
48 if (!event.child() || !is<Widget>(*event.child()))
49 return Widget::child_event(event);
50 auto& child = verify_cast<Widget>(*event.child());
51 if (event.type() == Event::ChildAdded) {
52 if (!m_active_widget)
53 set_active_widget(&child);
54 else if (m_active_widget != &child)
55 child.set_visible(false);
56 } else if (event.type() == Event::ChildRemoved) {
57 if (m_active_widget == &child) {
58 Widget* new_active_widget = nullptr;
59 for_each_child_widget([&](auto& new_child) {
60 new_active_widget = &new_child;
61 return IterationDecision::Break;
62 });
63 set_active_widget(new_active_widget);
64 }
65 }
66 Widget::child_event(event);
67}
68
69Optional<UISize> StackWidget::calculated_min_size() const
70{
71 return m_active_widget->calculated_min_size();
72}
73
74}