mirror of
https://github.com/RGBCube/serenity
synced 2025-05-30 23:48:11 +00:00
Add basic z-order for Windows.
This commit is contained in:
parent
baec8925a8
commit
723ff8c2ab
3 changed files with 31 additions and 11 deletions
|
@ -4,11 +4,12 @@
|
||||||
#include "Rect.h"
|
#include "Rect.h"
|
||||||
#include "GraphicsBitmap.h"
|
#include "GraphicsBitmap.h"
|
||||||
#include <AK/AKString.h>
|
#include <AK/AKString.h>
|
||||||
|
#include <AK/InlineLinkedList.h>
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
|
|
||||||
class Widget;
|
class Widget;
|
||||||
|
|
||||||
class Window final : public Object {
|
class Window final : public Object, public InlineLinkedListNode<Window> {
|
||||||
public:
|
public:
|
||||||
explicit Window(Object* parent = nullptr);
|
explicit Window(Object* parent = nullptr);
|
||||||
virtual ~Window() override;
|
virtual ~Window() override;
|
||||||
|
@ -55,6 +56,11 @@ public:
|
||||||
|
|
||||||
void did_paint();
|
void did_paint();
|
||||||
|
|
||||||
|
// For InlineLinkedList.
|
||||||
|
// FIXME: Maybe make a ListHashSet and then WindowManager can just use that.
|
||||||
|
Window* m_next { nullptr };
|
||||||
|
Window* m_prev { nullptr };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String m_title;
|
String m_title;
|
||||||
Rect m_rect;
|
Rect m_rect;
|
||||||
|
|
|
@ -60,7 +60,7 @@ WindowManager::~WindowManager()
|
||||||
|
|
||||||
void WindowManager::paintWindowFrames()
|
void WindowManager::paintWindowFrames()
|
||||||
{
|
{
|
||||||
for (auto* window : m_windows)
|
for (auto* window = m_windows_in_order.head(); window; window = window->next())
|
||||||
paintWindowFrame(*window);
|
paintWindowFrame(*window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,20 +123,27 @@ void WindowManager::paintWindowFrame(Window& window)
|
||||||
void WindowManager::addWindow(Window& window)
|
void WindowManager::addWindow(Window& window)
|
||||||
{
|
{
|
||||||
m_windows.set(&window);
|
m_windows.set(&window);
|
||||||
|
m_windows_in_order.append(&window);
|
||||||
if (!activeWindow())
|
if (!activeWindow())
|
||||||
setActiveWindow(&window);
|
setActiveWindow(&window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::move_to_front(Window& window)
|
||||||
|
{
|
||||||
|
m_windows_in_order.remove(&window);
|
||||||
|
m_windows_in_order.append(&window);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowManager::repaint()
|
void WindowManager::repaint()
|
||||||
{
|
{
|
||||||
handlePaintEvent(*make<PaintEvent>());
|
handlePaintEvent(*make<PaintEvent>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::did_paint(Window& window)
|
void WindowManager::did_paint(Window&)
|
||||||
{
|
{
|
||||||
auto& framebuffer = FrameBufferSDL::the();
|
auto& framebuffer = FrameBufferSDL::the();
|
||||||
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing());
|
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing());
|
||||||
for (auto* window : m_windows) {
|
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||||
ASSERT(window->backing());
|
ASSERT(window->backing());
|
||||||
framebuffer.blit(window->position(), *window->backing());
|
framebuffer.blit(window->position(), *window->backing());
|
||||||
}
|
}
|
||||||
|
@ -149,6 +156,7 @@ void WindowManager::removeWindow(Window& window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_windows.remove(&window);
|
m_windows.remove(&window);
|
||||||
|
m_windows_in_order.remove(&window);
|
||||||
if (!activeWindow() && !m_windows.is_empty())
|
if (!activeWindow() && !m_windows.is_empty())
|
||||||
setActiveWindow(*m_windows.begin());
|
setActiveWindow(*m_windows.begin());
|
||||||
|
|
||||||
|
@ -200,7 +208,7 @@ void WindowManager::repaintAfterMove(const Rect& oldRect, const Rect& newRect)
|
||||||
|
|
||||||
m_rootWidget->repaint(oldRect);
|
m_rootWidget->repaint(oldRect);
|
||||||
m_rootWidget->repaint(newRect);
|
m_rootWidget->repaint(newRect);
|
||||||
for (auto* window : m_windows) {
|
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||||
if (outerRectForWindow(*window).intersects(oldRect) || outerRectForWindow(*window).intersects(newRect)) {
|
if (outerRectForWindow(*window).intersects(oldRect) || outerRectForWindow(*window).intersects(newRect)) {
|
||||||
paintWindowFrame(*window);
|
paintWindowFrame(*window);
|
||||||
window->repaint();
|
window->repaint();
|
||||||
|
@ -233,18 +241,21 @@ void WindowManager::processMouseEvent(MouseEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Respect z-order of windows...
|
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||||
for (auto* window : m_windows) {
|
|
||||||
if (titleBarRectForWindow(*window).contains(event.position())) {
|
if (titleBarRectForWindow(*window).contains(event.position())) {
|
||||||
if (event.type() == Event::MouseDown)
|
if (event.type() == Event::MouseDown) {
|
||||||
|
move_to_front(*window);
|
||||||
setActiveWindow(window);
|
setActiveWindow(window);
|
||||||
|
}
|
||||||
handleTitleBarMouseEvent(*window, event);
|
handleTitleBarMouseEvent(*window, event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->rect().contains(event.position())) {
|
if (window->rect().contains(event.position())) {
|
||||||
if (event.type() == Event::MouseDown)
|
if (event.type() == Event::MouseDown) {
|
||||||
|
move_to_front(*window);
|
||||||
setActiveWindow(window);
|
setActiveWindow(window);
|
||||||
|
}
|
||||||
// FIXME: Re-use the existing event instead of crafting a new one?
|
// FIXME: Re-use the existing event instead of crafting a new one?
|
||||||
auto localEvent = make<MouseEvent>(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button());
|
auto localEvent = make<MouseEvent>(event.type(), event.x() - window->rect().x(), event.y() - window->rect().y(), event.button());
|
||||||
window->event(*localEvent);
|
window->event(*localEvent);
|
||||||
|
@ -264,12 +275,12 @@ void WindowManager::handlePaintEvent(PaintEvent& event)
|
||||||
m_rootWidget->event(event);
|
m_rootWidget->event(event);
|
||||||
paintWindowFrames();
|
paintWindowFrames();
|
||||||
|
|
||||||
for (auto* window : m_windows)
|
for (auto* window = m_windows_in_order.head(); window; window = window->next())
|
||||||
window->event(event);
|
window->event(event);
|
||||||
|
|
||||||
auto& framebuffer = FrameBufferSDL::the();
|
auto& framebuffer = FrameBufferSDL::the();
|
||||||
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing());
|
framebuffer.blit({ 0, 0 }, *m_rootWidget->backing());
|
||||||
for (auto* window : m_windows) {
|
for (auto* window = m_windows_in_order.head(); window; window = window->next()) {
|
||||||
ASSERT(window->backing());
|
ASSERT(window->backing());
|
||||||
framebuffer.blit(window->position(), *window->backing());
|
framebuffer.blit(window->position(), *window->backing());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Rect.h"
|
#include "Rect.h"
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include <AK/HashTable.h>
|
#include <AK/HashTable.h>
|
||||||
|
#include <AK/InlineLinkedList.h>
|
||||||
#include <AK/WeakPtr.h>
|
#include <AK/WeakPtr.h>
|
||||||
|
|
||||||
class MouseEvent;
|
class MouseEvent;
|
||||||
|
@ -32,6 +33,7 @@ public:
|
||||||
void did_paint(Window&);
|
void did_paint(Window&);
|
||||||
|
|
||||||
void repaint();
|
void repaint();
|
||||||
|
void move_to_front(Window&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowManager();
|
WindowManager();
|
||||||
|
@ -52,6 +54,7 @@ private:
|
||||||
|
|
||||||
void paintWindowFrame(Window&);
|
void paintWindowFrame(Window&);
|
||||||
HashTable<Window*> m_windows;
|
HashTable<Window*> m_windows;
|
||||||
|
InlineLinkedList<Window> m_windows_in_order;
|
||||||
Widget* m_rootWidget { nullptr };
|
Widget* m_rootWidget { nullptr };
|
||||||
|
|
||||||
WeakPtr<Window> m_activeWindow;
|
WeakPtr<Window> m_activeWindow;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue