Serenity Operating System
at portability 222 lines 7.8 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Function.h> 30#include <AK/String.h> 31#include <AK/WeakPtr.h> 32#include <LibCore/Object.h> 33#include <LibGUI/Forward.h> 34#include <LibGUI/WindowType.h> 35#include <LibGfx/Color.h> 36#include <LibGfx/Forward.h> 37#include <LibGfx/Rect.h> 38 39namespace GUI { 40 41enum class StandardCursor { 42 None = 0, 43 Arrow, 44 IBeam, 45 ResizeHorizontal, 46 ResizeVertical, 47 ResizeDiagonalTLBR, 48 ResizeDiagonalBLTR, 49 Hand, 50}; 51 52class Window : public Core::Object { 53 C_OBJECT(Window) 54public: 55 virtual ~Window() override; 56 57 static Window* from_window_id(int); 58 59 bool is_modal() const { return m_modal; } 60 void set_modal(bool); 61 62 bool is_fullscreen() const { return m_fullscreen; } 63 void set_fullscreen(bool); 64 65 bool is_resizable() const { return m_resizable; } 66 void set_resizable(bool resizable) { m_resizable = resizable; } 67 68 bool is_minimizable() const { return m_minimizable; } 69 void set_minimizable(bool minimizable) { m_minimizable = minimizable; } 70 71 void set_double_buffering_enabled(bool); 72 void set_has_alpha_channel(bool); 73 void set_opacity(float); 74 void set_window_type(WindowType); 75 76 int window_id() const { return m_window_id; } 77 78 String title() const; 79 void set_title(const StringView&); 80 81 bool show_titlebar() const { return m_show_titlebar; }; 82 void set_show_titlebar(bool show) { m_show_titlebar = show; }; 83 84 Color background_color() const { return m_background_color; } 85 void set_background_color(Color color) { m_background_color = color; } 86 87 enum class CloseRequestDecision { 88 StayOpen, 89 Close, 90 }; 91 92 Function<CloseRequestDecision()> on_close_request; 93 94 int x() const { return rect().x(); } 95 int y() const { return rect().y(); } 96 int width() const { return rect().width(); } 97 int height() const { return rect().height(); } 98 99 Gfx::Rect rect() const; 100 Gfx::Size size() const { return rect().size(); } 101 void set_rect(const Gfx::Rect&); 102 void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); } 103 104 Gfx::Point position() const { return rect().location(); } 105 106 void move_to(int x, int y) { move_to({ x, y }); } 107 void move_to(const Gfx::Point& point) { set_rect({ point, size() }); } 108 109 void resize(int width, int height) { resize({ width, height }); } 110 void resize(const Gfx::Size& size) { set_rect({ position(), size }); } 111 112 virtual void event(Core::Event&) override; 113 114 bool is_visible() const; 115 bool is_active() const { return m_is_active; } 116 117 void show(); 118 void hide(); 119 virtual void close(); 120 void move_to_front(); 121 122 void start_wm_resize(); 123 124 Widget* main_widget() { return m_main_widget; } 125 const Widget* main_widget() const { return m_main_widget; } 126 void set_main_widget(Widget*); 127 128 Widget* focused_widget() { return m_focused_widget; } 129 const Widget* focused_widget() const { return m_focused_widget; } 130 void set_focused_widget(Widget*); 131 132 void update(); 133 void update(const Gfx::Rect&); 134 135 void set_global_cursor_tracking_widget(Widget*); 136 Widget* global_cursor_tracking_widget() { return m_global_cursor_tracking_widget.ptr(); } 137 const Widget* global_cursor_tracking_widget() const { return m_global_cursor_tracking_widget.ptr(); } 138 139 void set_automatic_cursor_tracking_widget(Widget*); 140 Widget* automatic_cursor_tracking_widget() { return m_automatic_cursor_tracking_widget.ptr(); } 141 const Widget* automatic_cursor_tracking_widget() const { return m_automatic_cursor_tracking_widget.ptr(); } 142 143 Widget* hovered_widget() { return m_hovered_widget.ptr(); } 144 const Widget* hovered_widget() const { return m_hovered_widget.ptr(); } 145 void set_hovered_widget(Widget*); 146 147 Gfx::Bitmap* front_bitmap() { return m_front_bitmap.ptr(); } 148 Gfx::Bitmap* back_bitmap() { return m_back_bitmap.ptr(); } 149 150 Gfx::Size size_increment() const { return m_size_increment; } 151 void set_size_increment(const Gfx::Size&); 152 Gfx::Size base_size() const { return m_base_size; } 153 void set_base_size(const Gfx::Size&); 154 155 void set_override_cursor(StandardCursor); 156 157 void set_icon(const Gfx::Bitmap*); 158 void apply_icon(); 159 const Gfx::Bitmap* icon() const { return m_icon.ptr(); } 160 161 Vector<Widget*> focusable_widgets() const; 162 163 virtual void save_to(AK::JsonObject&) override; 164 165 void schedule_relayout(); 166 167 static void update_all_windows(Badge<WindowServerConnection>); 168 void notify_state_changed(Badge<WindowServerConnection>, bool minimized, bool occluded); 169 170 virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; } 171 172 Action* action_for_key_event(const KeyEvent&); 173 174protected: 175 Window(Core::Object* parent = nullptr); 176 virtual void wm_event(WMEvent&); 177 178private: 179 virtual bool is_window() const override final { return true; } 180 181 NonnullRefPtr<Gfx::Bitmap> create_backing_bitmap(const Gfx::Size&); 182 NonnullRefPtr<Gfx::Bitmap> create_shared_bitmap(Gfx::BitmapFormat, const Gfx::Size&); 183 void set_current_backing_bitmap(Gfx::Bitmap&, bool flush_immediately = false); 184 void flip(const Vector<Gfx::Rect, 32>& dirty_rects); 185 void force_update(); 186 187 RefPtr<Gfx::Bitmap> m_front_bitmap; 188 RefPtr<Gfx::Bitmap> m_back_bitmap; 189 RefPtr<Gfx::Bitmap> m_icon; 190 int m_window_id { 0 }; 191 float m_opacity_when_windowless { 1.0f }; 192 RefPtr<Widget> m_main_widget; 193 WeakPtr<Widget> m_focused_widget; 194 WeakPtr<Widget> m_global_cursor_tracking_widget; 195 WeakPtr<Widget> m_automatic_cursor_tracking_widget; 196 WeakPtr<Widget> m_hovered_widget; 197 Gfx::Rect m_rect_when_windowless; 198 String m_title_when_windowless; 199 Vector<Gfx::Rect, 32> m_pending_paint_event_rects; 200 Gfx::Size m_size_increment; 201 Gfx::Size m_base_size; 202 Color m_background_color { Color::WarmGray }; 203 WindowType m_window_type { WindowType::Normal }; 204 bool m_is_active { false }; 205 bool m_has_alpha_channel { false }; 206 bool m_double_buffering_enabled { true }; 207 bool m_modal { false }; 208 bool m_resizable { true }; 209 bool m_minimizable { true }; 210 bool m_fullscreen { false }; 211 bool m_show_titlebar { true }; 212 bool m_layout_pending { false }; 213 bool m_visible_for_timer_purposes { true }; 214}; 215 216} 217 218template<> 219inline bool Core::is<GUI::Window>(const Core::Object& object) 220{ 221 return object.is_window(); 222}