mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 19:27:35 +00:00
LibCore+LibGUI: Switch to using AK::is and AK::downcast
This commit is contained in:
parent
71556e39a4
commit
e0b8b4ac67
14 changed files with 341 additions and 98 deletions
|
@ -42,7 +42,7 @@ void InspectorWidget::set_inspected_node(Web::Node* node)
|
||||||
{
|
{
|
||||||
m_document->set_inspected_node(node);
|
m_document->set_inspected_node(node);
|
||||||
if (node && node->is_element()) {
|
if (node && node->is_element()) {
|
||||||
auto& element = Web::to<Web::Element>(*node);
|
auto& element = downcast<Web::Element>(*node);
|
||||||
if (element.resolved_style()) {
|
if (element.resolved_style()) {
|
||||||
m_style_table_view->set_model(Web::StylePropertiesModel::create(*element.resolved_style()));
|
m_style_table_view->set_model(Web::StylePropertiesModel::create(*element.resolved_style()));
|
||||||
m_computed_style_table_view->set_model(Web::StylePropertiesModel::create(*element.computed_style()));
|
m_computed_style_table_view->set_model(Web::StylePropertiesModel::create(*element.computed_style()));
|
||||||
|
|
|
@ -55,8 +55,6 @@ private:
|
||||||
RefPtr<Editor> m_editor;
|
RefPtr<Editor> m_editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
AK_BEGIN_TYPE_TRAITS(EditorWrapper)
|
||||||
inline bool Core::is<EditorWrapper>(const Core::Object& object)
|
static bool is_type(const Core::Object& object) { return !strcmp(object.class_name(), "EditorWrapper"); }
|
||||||
{
|
AK_END_TYPE_TRAITS()
|
||||||
return !strcmp(object.class_name(), "EditorWrapper");
|
|
||||||
}
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <AK/Noncopyable.h>
|
#include <AK/Noncopyable.h>
|
||||||
#include <AK/NonnullRefPtrVector.h>
|
#include <AK/NonnullRefPtrVector.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
#include <AK/TypeCasts.h>
|
||||||
#include <AK/Weakable.h>
|
#include <AK/Weakable.h>
|
||||||
#include <LibCore/Forward.h>
|
#include <LibCore/Forward.h>
|
||||||
|
|
||||||
|
@ -147,8 +148,8 @@ protected:
|
||||||
// NOTE: You may get child events for children that are not yet fully constructed!
|
// NOTE: You may get child events for children that are not yet fully constructed!
|
||||||
virtual void child_event(ChildEvent&);
|
virtual void child_event(ChildEvent&);
|
||||||
|
|
||||||
virtual void did_begin_inspection() {}
|
virtual void did_begin_inspection() { }
|
||||||
virtual void did_end_inspection() {}
|
virtual void did_end_inspection() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Object* m_parent { nullptr };
|
Object* m_parent { nullptr };
|
||||||
|
@ -159,29 +160,15 @@ private:
|
||||||
NonnullRefPtrVector<Object> m_children;
|
NonnullRefPtrVector<Object> m_children;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline bool is(const Object&) { return false; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline T& to(Object& object)
|
|
||||||
{
|
|
||||||
ASSERT(is<typename RemoveConst<T>::Type>(object));
|
|
||||||
return static_cast<T&>(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline const T& to(const Object& object)
|
|
||||||
{
|
|
||||||
ASSERT(is<typename RemoveConst<T>::Type>(object));
|
|
||||||
return static_cast<const T&>(object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
template<typename T, typename Callback>
|
template<typename T, typename Callback>
|
||||||
inline void Object::for_each_child_of_type(Callback callback)
|
inline void Object::for_each_child_of_type(Callback callback)
|
||||||
{
|
{
|
||||||
for_each_child([&](auto& child) {
|
for_each_child([&](auto& child) {
|
||||||
if (is<T>(child))
|
if (is<T>(child))
|
||||||
return callback(to<T>(child));
|
return callback(downcast<T>(child));
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,10 +91,6 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
AK_BEGIN_TYPE_TRAITS(GUI::AbstractButton)
|
||||||
inline bool Core::is<GUI::AbstractButton>(const Core::Object& object)
|
static bool is_type(const Core::Object& object) { return is<GUI::Widget>(object) && downcast<GUI::Widget>(object).is_abstract_button(); }
|
||||||
{
|
AK_END_TYPE_TRAITS()
|
||||||
if (!is<GUI::Widget>(object))
|
|
||||||
return false;
|
|
||||||
return to<GUI::Widget>(object).is_abstract_button();
|
|
||||||
}
|
|
||||||
|
|
|
@ -152,9 +152,9 @@ Action::Action(const StringView& text, const Shortcut& shortcut, RefPtr<Gfx::Bit
|
||||||
, m_shortcut(shortcut)
|
, m_shortcut(shortcut)
|
||||||
, m_checkable(checkable)
|
, m_checkable(checkable)
|
||||||
{
|
{
|
||||||
if (parent && Core::is<Widget>(*parent)) {
|
if (parent && is<Widget>(*parent)) {
|
||||||
m_scope = ShortcutScope::WidgetLocal;
|
m_scope = ShortcutScope::WidgetLocal;
|
||||||
} else if (parent && Core::is<Window>(*parent)) {
|
} else if (parent && is<Window>(*parent)) {
|
||||||
m_scope = ShortcutScope::WindowLocal;
|
m_scope = ShortcutScope::WindowLocal;
|
||||||
} else {
|
} else {
|
||||||
m_scope = ShortcutScope::ApplicationGlobal;
|
m_scope = ShortcutScope::ApplicationGlobal;
|
||||||
|
|
|
@ -42,23 +42,23 @@
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
namespace CommonActions {
|
namespace CommonActions {
|
||||||
NonnullRefPtr<Action> make_open_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_open_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_save_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_save_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_undo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_undo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_redo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_redo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_cut_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_cut_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_copy_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_copy_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_paste_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_paste_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_delete_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_delete_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_move_to_front_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_move_to_front_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_move_to_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_move_to_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_fullscreen_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_fullscreen_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_quit_action(Function<void(Action&)>);
|
NonnullRefPtr<Action> make_quit_action(Function<void(Action&)>);
|
||||||
NonnullRefPtr<Action> make_go_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_go_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_go_forward_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_go_forward_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_go_home_action(Function<void(Action&)> callback, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_go_home_action(Function<void(Action&)> callback, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_reload_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_reload_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
NonnullRefPtr<Action> make_select_all_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
NonnullRefPtr<Action> make_select_all_action(Function<void(Action&)>, Core::Object* parent = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Action final : public Core::Object {
|
class Action final : public Core::Object {
|
||||||
|
@ -168,8 +168,6 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
AK_BEGIN_TYPE_TRAITS(GUI::Action)
|
||||||
inline bool Core::is<GUI::Action>(const Core::Object& object)
|
static bool is_type(const Core::Object& object) { return object.is_action(); }
|
||||||
{
|
AK_END_TYPE_TRAITS()
|
||||||
return object.is_action();
|
|
||||||
}
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ void RadioButton::for_each_in_group(Callback callback)
|
||||||
if (!parent())
|
if (!parent())
|
||||||
return;
|
return;
|
||||||
parent()->for_each_child_of_type<RadioButton>([&](auto& child) {
|
parent()->for_each_child_of_type<RadioButton>([&](auto& child) {
|
||||||
return callback(static_cast<RadioButton&>(child));
|
return callback(downcast<RadioButton>(child));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,10 +55,6 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
AK_BEGIN_TYPE_TRAITS(GUI::RadioButton)
|
||||||
inline bool Core::is<GUI::RadioButton>(const Core::Object& object)
|
static bool is_type(const Core::Object& object) { return is<GUI::Widget>(object) && downcast<GUI::Widget>(object).is_radio_button(); }
|
||||||
{
|
AK_END_TYPE_TRAITS()
|
||||||
if (!is<GUI::Widget>(object))
|
|
||||||
return false;
|
|
||||||
return to<GUI::Widget>(object).is_radio_button();
|
|
||||||
}
|
|
||||||
|
|
|
@ -63,9 +63,9 @@ void StackWidget::resize_event(ResizeEvent& event)
|
||||||
|
|
||||||
void StackWidget::child_event(Core::ChildEvent& event)
|
void StackWidget::child_event(Core::ChildEvent& event)
|
||||||
{
|
{
|
||||||
if (!event.child() || !Core::is<Widget>(*event.child()))
|
if (!event.child() || !is<Widget>(*event.child()))
|
||||||
return Widget::child_event(event);
|
return Widget::child_event(event);
|
||||||
auto& child = Core::to<Widget>(*event.child());
|
auto& child = downcast<Widget>(*event.child());
|
||||||
if (event.type() == Event::ChildAdded) {
|
if (event.type() == Event::ChildAdded) {
|
||||||
if (!m_active_widget)
|
if (!m_active_widget)
|
||||||
set_active_widget(&child);
|
set_active_widget(&child);
|
||||||
|
|
|
@ -102,9 +102,9 @@ Gfx::IntRect TabWidget::child_rect_for_size(const Gfx::IntSize& size) const
|
||||||
|
|
||||||
void TabWidget::child_event(Core::ChildEvent& event)
|
void TabWidget::child_event(Core::ChildEvent& event)
|
||||||
{
|
{
|
||||||
if (!event.child() || !Core::is<Widget>(*event.child()))
|
if (!event.child() || !is<Widget>(*event.child()))
|
||||||
return Widget::child_event(event);
|
return Widget::child_event(event);
|
||||||
auto& child = Core::to<Widget>(*event.child());
|
auto& child = downcast<Widget>(*event.child());
|
||||||
if (event.type() == Event::ChildAdded) {
|
if (event.type() == Event::ChildAdded) {
|
||||||
if (!m_active_widget)
|
if (!m_active_widget)
|
||||||
set_active_widget(&child);
|
set_active_widget(&child);
|
||||||
|
|
|
@ -109,24 +109,24 @@ Widget::~Widget()
|
||||||
void Widget::child_event(Core::ChildEvent& event)
|
void Widget::child_event(Core::ChildEvent& event)
|
||||||
{
|
{
|
||||||
if (event.type() == Event::ChildAdded) {
|
if (event.type() == Event::ChildAdded) {
|
||||||
if (event.child() && Core::is<Widget>(*event.child()) && layout()) {
|
if (event.child() && is<Widget>(*event.child()) && layout()) {
|
||||||
if (event.insertion_before_child() && event.insertion_before_child()->is_widget())
|
if (event.insertion_before_child() && event.insertion_before_child()->is_widget())
|
||||||
layout()->insert_widget_before(Core::to<Widget>(*event.child()), Core::to<Widget>(*event.insertion_before_child()));
|
layout()->insert_widget_before(downcast<Widget>(*event.child()), downcast<Widget>(*event.insertion_before_child()));
|
||||||
else
|
else
|
||||||
layout()->add_widget(Core::to<Widget>(*event.child()));
|
layout()->add_widget(downcast<Widget>(*event.child()));
|
||||||
}
|
}
|
||||||
if (window() && event.child() && Core::is<Widget>(*event.child()))
|
if (window() && event.child() && is<Widget>(*event.child()))
|
||||||
window()->did_add_widget({}, Core::to<Widget>(*event.child()));
|
window()->did_add_widget({}, downcast<Widget>(*event.child()));
|
||||||
}
|
}
|
||||||
if (event.type() == Event::ChildRemoved) {
|
if (event.type() == Event::ChildRemoved) {
|
||||||
if (layout()) {
|
if (layout()) {
|
||||||
if (event.child() && Core::is<Widget>(*event.child()))
|
if (event.child() && is<Widget>(*event.child()))
|
||||||
layout()->remove_widget(Core::to<Widget>(*event.child()));
|
layout()->remove_widget(downcast<Widget>(*event.child()));
|
||||||
else
|
else
|
||||||
invalidate_layout();
|
invalidate_layout();
|
||||||
}
|
}
|
||||||
if (window() && event.child() && Core::is<Widget>(*event.child()))
|
if (window() && event.child() && is<Widget>(*event.child()))
|
||||||
window()->did_remove_widget({}, Core::to<Widget>(*event.child()));
|
window()->did_remove_widget({}, downcast<Widget>(*event.child()));
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
return Core::Object::child_event(event);
|
return Core::Object::child_event(event);
|
||||||
|
@ -470,9 +470,9 @@ Gfx::IntRect Widget::screen_relative_rect() const
|
||||||
Widget* Widget::child_at(const Gfx::IntPoint& point) const
|
Widget* Widget::child_at(const Gfx::IntPoint& point) const
|
||||||
{
|
{
|
||||||
for (int i = children().size() - 1; i >= 0; --i) {
|
for (int i = children().size() - 1; i >= 0; --i) {
|
||||||
if (!Core::is<Widget>(children()[i]))
|
if (!is<Widget>(children()[i]))
|
||||||
continue;
|
continue;
|
||||||
auto& child = Core::to<Widget>(children()[i]);
|
auto& child = downcast<Widget>(children()[i]);
|
||||||
if (!child.is_visible())
|
if (!child.is_visible())
|
||||||
continue;
|
continue;
|
||||||
if (child.content_rect().contains(point))
|
if (child.content_rect().contains(point))
|
||||||
|
|
|
@ -40,12 +40,6 @@
|
||||||
extern WidgetClassRegistration registration_##class_name; \
|
extern WidgetClassRegistration registration_##class_name; \
|
||||||
WidgetClassRegistration registration_##class_name(#class_name, []() { return class_name::construct(); });
|
WidgetClassRegistration registration_##class_name(#class_name, []() { return class_name::construct(); });
|
||||||
|
|
||||||
template<>
|
|
||||||
inline bool Core::is<GUI::Widget>(const Core::Object& object)
|
|
||||||
{
|
|
||||||
return object.is_widget();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
enum class SizePolicy {
|
enum class SizePolicy {
|
||||||
|
@ -249,8 +243,8 @@ public:
|
||||||
void for_each_child_widget(Callback callback)
|
void for_each_child_widget(Callback callback)
|
||||||
{
|
{
|
||||||
for_each_child([&](auto& child) {
|
for_each_child([&](auto& child) {
|
||||||
if (Core::is<Widget>(child))
|
if (is<Widget>(child))
|
||||||
return callback(Core::to<Widget>(child));
|
return callback(downcast<Widget>(child));
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -278,9 +272,9 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Widget();
|
Widget();
|
||||||
|
|
||||||
virtual void custom_layout() {}
|
virtual void custom_layout() { }
|
||||||
virtual void did_change_font() {}
|
virtual void did_change_font() { }
|
||||||
virtual void did_layout() {}
|
virtual void did_layout() { }
|
||||||
virtual void paint_event(PaintEvent&);
|
virtual void paint_event(PaintEvent&);
|
||||||
virtual void resize_event(ResizeEvent&);
|
virtual void resize_event(ResizeEvent&);
|
||||||
virtual void show_event(ShowEvent&);
|
virtual void show_event(ShowEvent&);
|
||||||
|
@ -347,14 +341,18 @@ private:
|
||||||
|
|
||||||
inline Widget* Widget::parent_widget()
|
inline Widget* Widget::parent_widget()
|
||||||
{
|
{
|
||||||
if (parent() && Core::is<Widget>(*parent()))
|
if (parent() && is<Widget>(*parent()))
|
||||||
return &Core::to<Widget>(*parent());
|
return &downcast<Widget>(*parent());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
inline const Widget* Widget::parent_widget() const
|
inline const Widget* Widget::parent_widget() const
|
||||||
{
|
{
|
||||||
if (parent() && Core::is<Widget>(*parent()))
|
if (parent() && is<Widget>(*parent()))
|
||||||
return &Core::to<const Widget>(*parent());
|
return &downcast<const Widget>(*parent());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AK_BEGIN_TYPE_TRAITS(GUI::Widget)
|
||||||
|
static bool is_type(const Core::Object& object) { return object.is_widget(); }
|
||||||
|
AK_END_TYPE_TRAITS()
|
||||||
|
|
|
@ -266,8 +266,6 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
AK_BEGIN_TYPE_TRAITS(GUI::Window)
|
||||||
inline bool Core::is<GUI::Window>(const Core::Object& object)
|
static bool is_type(const Core::Object& object) { return object.is_window(); }
|
||||||
{
|
AK_END_TYPE_TRAITS()
|
||||||
return object.is_window();
|
|
||||||
}
|
|
||||||
|
|
272
Libraries/LibGUI/Window.h.orig
Normal file
272
Libraries/LibGUI/Window.h.orig
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Function.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/WeakPtr.h>
|
||||||
|
#include <LibCore/Object.h>
|
||||||
|
#include <LibGUI/Forward.h>
|
||||||
|
#include <LibGUI/WindowType.h>
|
||||||
|
#include <LibGfx/Color.h>
|
||||||
|
#include <LibGfx/Forward.h>
|
||||||
|
#include <LibGfx/Rect.h>
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
|
||||||
|
enum class StandardCursor {
|
||||||
|
None = 0,
|
||||||
|
Arrow,
|
||||||
|
IBeam,
|
||||||
|
ResizeHorizontal,
|
||||||
|
ResizeVertical,
|
||||||
|
ResizeDiagonalTLBR,
|
||||||
|
ResizeDiagonalBLTR,
|
||||||
|
ResizeColumn,
|
||||||
|
ResizeRow,
|
||||||
|
Hand,
|
||||||
|
Help,
|
||||||
|
Drag,
|
||||||
|
Move,
|
||||||
|
Wait,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Window : public Core::Object {
|
||||||
|
C_OBJECT(Window)
|
||||||
|
public:
|
||||||
|
virtual ~Window() override;
|
||||||
|
|
||||||
|
static Window* from_window_id(int);
|
||||||
|
|
||||||
|
bool is_modal() const { return m_modal; }
|
||||||
|
void set_modal(bool);
|
||||||
|
|
||||||
|
bool is_fullscreen() const { return m_fullscreen; }
|
||||||
|
void set_fullscreen(bool);
|
||||||
|
|
||||||
|
bool is_maximized() const;
|
||||||
|
|
||||||
|
bool is_frameless() const { return m_frameless; }
|
||||||
|
void set_frameless(bool frameless) { m_frameless = frameless; }
|
||||||
|
|
||||||
|
bool is_resizable() const { return m_resizable; }
|
||||||
|
void set_resizable(bool resizable) { m_resizable = resizable; }
|
||||||
|
|
||||||
|
bool is_minimizable() const { return m_minimizable; }
|
||||||
|
void set_minimizable(bool minimizable) { m_minimizable = minimizable; }
|
||||||
|
|
||||||
|
void set_double_buffering_enabled(bool);
|
||||||
|
void set_has_alpha_channel(bool);
|
||||||
|
void set_opacity(float);
|
||||||
|
void set_window_type(WindowType);
|
||||||
|
|
||||||
|
int window_id() const { return m_window_id; }
|
||||||
|
|
||||||
|
String title() const;
|
||||||
|
void set_title(const StringView&);
|
||||||
|
|
||||||
|
Color background_color() const { return m_background_color; }
|
||||||
|
void set_background_color(Color color) { m_background_color = color; }
|
||||||
|
|
||||||
|
enum class CloseRequestDecision {
|
||||||
|
StayOpen,
|
||||||
|
Close,
|
||||||
|
};
|
||||||
|
|
||||||
|
Function<CloseRequestDecision()> on_close_request;
|
||||||
|
Function<void(bool is_active_input)> on_active_input_change;
|
||||||
|
Function<void(const bool is_active)> on_activity_change;
|
||||||
|
|
||||||
|
int x() const { return rect().x(); }
|
||||||
|
int y() const { return rect().y(); }
|
||||||
|
int width() const { return rect().width(); }
|
||||||
|
int height() const { return rect().height(); }
|
||||||
|
|
||||||
|
Gfx::IntRect rect() const;
|
||||||
|
Gfx::IntSize size() const { return rect().size(); }
|
||||||
|
void set_rect(const Gfx::IntRect&);
|
||||||
|
void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); }
|
||||||
|
|
||||||
|
Gfx::IntPoint position() const { return rect().location(); }
|
||||||
|
|
||||||
|
void move_to(int x, int y) { move_to({ x, y }); }
|
||||||
|
void move_to(const Gfx::IntPoint& point) { set_rect({ point, size() }); }
|
||||||
|
|
||||||
|
void resize(int width, int height) { resize({ width, height }); }
|
||||||
|
void resize(const Gfx::IntSize& size) { set_rect({ position(), size }); }
|
||||||
|
|
||||||
|
virtual void event(Core::Event&) override;
|
||||||
|
|
||||||
|
bool is_visible() const;
|
||||||
|
bool is_active() const { return m_is_active; }
|
||||||
|
bool is_active_input() const { return m_is_active_input; }
|
||||||
|
|
||||||
|
bool is_accessory() const { return m_accessory; }
|
||||||
|
void set_accessory(bool accessory) { m_accessory = accessory; }
|
||||||
|
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
|
virtual void close();
|
||||||
|
void move_to_front();
|
||||||
|
|
||||||
|
void start_wm_resize();
|
||||||
|
|
||||||
|
Widget* main_widget() { return m_main_widget; }
|
||||||
|
const Widget* main_widget() const { return m_main_widget; }
|
||||||
|
void set_main_widget(Widget*);
|
||||||
|
|
||||||
|
template<class T, class... Args>
|
||||||
|
inline T& set_main_widget(Args&&... args)
|
||||||
|
{
|
||||||
|
auto widget = T::construct(forward<Args>(args)...);
|
||||||
|
set_main_widget(widget.ptr());
|
||||||
|
return *widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget* focused_widget() { return m_focused_widget; }
|
||||||
|
const Widget* focused_widget() const { return m_focused_widget; }
|
||||||
|
void set_focused_widget(Widget*);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
void update(const Gfx::IntRect&);
|
||||||
|
|
||||||
|
void set_global_cursor_tracking_widget(Widget*);
|
||||||
|
Widget* global_cursor_tracking_widget() { return m_global_cursor_tracking_widget.ptr(); }
|
||||||
|
const Widget* global_cursor_tracking_widget() const { return m_global_cursor_tracking_widget.ptr(); }
|
||||||
|
|
||||||
|
void set_automatic_cursor_tracking_widget(Widget*);
|
||||||
|
Widget* automatic_cursor_tracking_widget() { return m_automatic_cursor_tracking_widget.ptr(); }
|
||||||
|
const Widget* automatic_cursor_tracking_widget() const { return m_automatic_cursor_tracking_widget.ptr(); }
|
||||||
|
|
||||||
|
Widget* hovered_widget() { return m_hovered_widget.ptr(); }
|
||||||
|
const Widget* hovered_widget() const { return m_hovered_widget.ptr(); }
|
||||||
|
void set_hovered_widget(Widget*);
|
||||||
|
|
||||||
|
Gfx::Bitmap* front_bitmap() { return m_front_bitmap.ptr(); }
|
||||||
|
Gfx::Bitmap* back_bitmap() { return m_back_bitmap.ptr(); }
|
||||||
|
|
||||||
|
Gfx::IntSize size_increment() const { return m_size_increment; }
|
||||||
|
void set_size_increment(const Gfx::IntSize&);
|
||||||
|
Gfx::IntSize base_size() const { return m_base_size; }
|
||||||
|
void set_base_size(const Gfx::IntSize&);
|
||||||
|
|
||||||
|
void set_override_cursor(StandardCursor);
|
||||||
|
void set_override_cursor(const Gfx::Bitmap&);
|
||||||
|
|
||||||
|
void set_icon(const Gfx::Bitmap*);
|
||||||
|
void apply_icon();
|
||||||
|
const Gfx::Bitmap* icon() const { return m_icon.ptr(); }
|
||||||
|
|
||||||
|
Vector<Widget*> focusable_widgets() const;
|
||||||
|
|
||||||
|
virtual void save_to(AK::JsonObject&) override;
|
||||||
|
|
||||||
|
void schedule_relayout();
|
||||||
|
|
||||||
|
static void for_each_window(Badge<WindowServerConnection>, Function<void(Window&)>);
|
||||||
|
static void update_all_windows(Badge<WindowServerConnection>);
|
||||||
|
void notify_state_changed(Badge<WindowServerConnection>, bool minimized, bool occluded);
|
||||||
|
|
||||||
|
virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; }
|
||||||
|
|
||||||
|
Action* action_for_key_event(const KeyEvent&);
|
||||||
|
|
||||||
|
void did_add_widget(Badge<Widget>, Widget&);
|
||||||
|
void did_remove_widget(Badge<Widget>, Widget&);
|
||||||
|
|
||||||
|
Window* find_parent_window();
|
||||||
|
|
||||||
|
void set_progress(int);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Window(Core::Object* parent = nullptr);
|
||||||
|
virtual void wm_event(WMEvent&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool is_window() const override final { return true; }
|
||||||
|
|
||||||
|
void handle_drop_event(DropEvent&);
|
||||||
|
void handle_mouse_event(MouseEvent&);
|
||||||
|
void handle_multi_paint_event(MultiPaintEvent&);
|
||||||
|
void handle_key_event(KeyEvent&);
|
||||||
|
void handle_resize_event(ResizeEvent&);
|
||||||
|
void handle_input_entered_or_left_event(Core::Event&);
|
||||||
|
void handle_became_active_or_inactive_event(Core::Event&);
|
||||||
|
void handle_close_request();
|
||||||
|
void handle_theme_change_event(ThemeChangeEvent&);
|
||||||
|
void handle_drag_move_event(DragEvent&);
|
||||||
|
void handle_left_event();
|
||||||
|
|
||||||
|
void server_did_destroy();
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap> create_backing_bitmap(const Gfx::IntSize&);
|
||||||
|
RefPtr<Gfx::Bitmap> create_shared_bitmap(Gfx::BitmapFormat, const Gfx::IntSize&);
|
||||||
|
void set_current_backing_bitmap(Gfx::Bitmap&, bool flush_immediately = false);
|
||||||
|
void flip(const Vector<Gfx::IntRect, 32>& dirty_rects);
|
||||||
|
void force_update();
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap> m_front_bitmap;
|
||||||
|
RefPtr<Gfx::Bitmap> m_back_bitmap;
|
||||||
|
RefPtr<Gfx::Bitmap> m_icon;
|
||||||
|
RefPtr<Gfx::Bitmap> m_custom_cursor;
|
||||||
|
int m_window_id { 0 };
|
||||||
|
float m_opacity_when_windowless { 1.0f };
|
||||||
|
RefPtr<Widget> m_main_widget;
|
||||||
|
WeakPtr<Widget> m_focused_widget;
|
||||||
|
WeakPtr<Widget> m_global_cursor_tracking_widget;
|
||||||
|
WeakPtr<Widget> m_automatic_cursor_tracking_widget;
|
||||||
|
WeakPtr<Widget> m_hovered_widget;
|
||||||
|
Gfx::IntRect m_rect_when_windowless;
|
||||||
|
String m_title_when_windowless;
|
||||||
|
Vector<Gfx::IntRect, 32> m_pending_paint_event_rects;
|
||||||
|
Gfx::IntSize m_size_increment;
|
||||||
|
Gfx::IntSize m_base_size;
|
||||||
|
Color m_background_color { Color::WarmGray };
|
||||||
|
WindowType m_window_type { WindowType::Normal };
|
||||||
|
StandardCursor m_override_cursor { StandardCursor::None };
|
||||||
|
bool m_is_active { false };
|
||||||
|
bool m_is_active_input { false };
|
||||||
|
bool m_has_alpha_channel { false };
|
||||||
|
bool m_double_buffering_enabled { true };
|
||||||
|
bool m_modal { false };
|
||||||
|
bool m_resizable { true };
|
||||||
|
bool m_minimizable { true };
|
||||||
|
bool m_fullscreen { false };
|
||||||
|
bool m_frameless { false };
|
||||||
|
bool m_layout_pending { false };
|
||||||
|
bool m_visible_for_timer_purposes { true };
|
||||||
|
bool m_visible { false };
|
||||||
|
bool m_accessory { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline bool Core::is<GUI::Window>(const Core::Object& object)
|
||||||
|
{
|
||||||
|
return object.is_window();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue