summaryrefslogtreecommitdiff
path: root/Widgets
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-14 01:23:01 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-14 01:23:01 +0200
commit959a1b0750328b59b25953bec7a9e8da95b3e058 (patch)
treeb86c27ac2592d2083109493ac0cf056c526180a9 /Widgets
parent3ebea059961ec027ee0298e38201aa43f7e9451c (diff)
downloadserenity-959a1b0750328b59b25953bec7a9e8da95b3e058.zip
Close the MsgBox when clicking the OK button.
This feels vaguely crashy. I haven't tested window/widget destruction before so there's sure to be bugs.
Diffstat (limited to 'Widgets')
-rw-r--r--Widgets/Event.h10
-rw-r--r--Widgets/Object.cpp8
-rw-r--r--Widgets/Object.h8
-rw-r--r--Widgets/Widget.cpp2
-rw-r--r--Widgets/Window.cpp11
-rw-r--r--Widgets/Window.h4
-rw-r--r--Widgets/WindowManager.cpp26
-rw-r--r--Widgets/WindowManager.h4
-rw-r--r--Widgets/test.cpp1
9 files changed, 65 insertions, 9 deletions
diff --git a/Widgets/Event.h b/Widgets/Event.h
index ab63b0d0a9..07d675bab3 100644
--- a/Widgets/Event.h
+++ b/Widgets/Event.h
@@ -17,6 +17,7 @@ static const char* eventNames[] = {
"KeyDown",
"KeyUp",
"Timer",
+ "DeferredDestroy",
};
class Event {
@@ -33,6 +34,7 @@ public:
KeyDown,
KeyUp,
Timer,
+ DeferredDestroy,
};
Event() { }
@@ -53,6 +55,14 @@ private:
Type m_type { Invalid };
};
+class DeferredDestroyEvent final : public Event {
+public:
+ DeferredDestroyEvent()
+ : Event(Event::DeferredDestroy)
+ {
+ }
+};
+
class QuitEvent final : public Event {
public:
QuitEvent()
diff --git a/Widgets/Object.cpp b/Widgets/Object.cpp
index 0eaaed08f6..f5bb856be8 100644
--- a/Widgets/Object.cpp
+++ b/Widgets/Object.cpp
@@ -28,6 +28,9 @@ void Object::event(Event& event)
switch (event.type()) {
case Event::Timer:
return timerEvent(static_cast<TimerEvent&>(event));
+ case Event::DeferredDestroy:
+ delete this;
+ break;
case Event::Invalid:
ASSERT_NOT_REACHED();
break;
@@ -82,3 +85,8 @@ void Object::stopTimer()
m_timerID = 0;
}
+void Object::deleteLater()
+{
+ EventLoop::main().postEvent(this, make<DeferredDestroyEvent>());
+}
+
diff --git a/Widgets/Object.h b/Widgets/Object.h
index 8bf27c8d19..f945350b88 100644
--- a/Widgets/Object.h
+++ b/Widgets/Object.h
@@ -24,12 +24,14 @@ public:
void stopTimer();
bool hasTimer() const { return m_timerID; }
-private:
- virtual void timerEvent(TimerEvent&);
-
void addChild(Object&);
void removeChild(Object&);
+ void deleteLater();
+
+private:
+ virtual void timerEvent(TimerEvent&);
+
Object* m_parent { nullptr };
int m_timerID { 0 };
diff --git a/Widgets/Widget.cpp b/Widgets/Widget.cpp
index 07b09b6583..e002834b3f 100644
--- a/Widgets/Widget.cpp
+++ b/Widgets/Widget.cpp
@@ -36,6 +36,8 @@ void Widget::event(Event& event)
if (auto* win = window()) {
if (win->isBeingDragged())
return;
+ if (!win->isVisible())
+ return;
}
m_hasPendingPaintEvent = false;
return paintEvent(static_cast<PaintEvent&>(event));
diff --git a/Widgets/Window.cpp b/Widgets/Window.cpp
index c0ba0a2351..c281da1fd5 100644
--- a/Widgets/Window.cpp
+++ b/Widgets/Window.cpp
@@ -11,6 +11,10 @@ Window::Window(Object* parent)
Window::~Window()
{
+ delete m_mainWidget;
+ m_mainWidget = nullptr;
+ if (parent())
+ parent()->removeChild(*this);
WindowManager::the().removeWindow(*this);
}
@@ -96,6 +100,11 @@ bool Window::isActive() const
return WindowManager::the().activeWindow() == this;
}
+bool Window::isVisible() const
+{
+ return WindowManager::the().isVisible(const_cast<Window&>(*this));
+}
+
void Window::setFocusedWidget(Widget* widget)
{
if (m_focusedWidget.ptr() == widget)
@@ -113,5 +122,7 @@ void Window::setFocusedWidget(Widget* widget)
void Window::close()
{
+ WindowManager::the().removeWindow(*this);
+ deleteLater();
}
diff --git a/Widgets/Window.h b/Widgets/Window.h
index cf9d1006b8..2717e5a4e1 100644
--- a/Widgets/Window.h
+++ b/Widgets/Window.h
@@ -22,9 +22,11 @@ public:
const Rect& rect() const { return m_rect; }
void setRect(const Rect&);
+ void setRectWithoutRepaint(const Rect& rect) { m_rect = rect; }
Point position() const { return m_rect.location(); }
void setPosition(const Point& position) { setRect({ position.x(), position.y(), width(), height() }); }
+ void setPositionWithoutRepaint(const Point& position) { setRectWithoutRepaint({ position.x(), position.y(), width(), height() }); }
Widget* mainWidget() { return m_mainWidget; }
const Widget* mainWidget() const { return m_mainWidget; }
@@ -44,6 +46,8 @@ public:
const Widget* focusedWidget() const { return m_focusedWidget.ptr(); }
void setFocusedWidget(Widget*);
+ bool isVisible() const;
+
void close();
private:
diff --git a/Widgets/WindowManager.cpp b/Widgets/WindowManager.cpp
index 6e21c5c646..c2d32ef7f0 100644
--- a/Widgets/WindowManager.cpp
+++ b/Widgets/WindowManager.cpp
@@ -126,22 +126,32 @@ void WindowManager::addWindow(Window& window)
setActiveWindow(&window);
}
+void WindowManager::repaint()
+{
+ handlePaintEvent(*make<PaintEvent>());
+}
+
void WindowManager::removeWindow(Window& window)
{
- ASSERT(m_windows.contains(&window));
+ if (!m_windows.contains(&window))
+ return;
+
m_windows.remove(&window);
if (!activeWindow() && !m_windows.isEmpty())
setActiveWindow(*m_windows.begin());
+
+ repaint();
}
void WindowManager::notifyTitleChanged(Window& window)
{
- //printf("[WM] Window{%p} title set to '%s'\n", &window, window.title().characters());
+ printf("[WM] Window{%p} title set to '%s'\n", &window, window.title().characters());
}
void WindowManager::notifyRectChanged(Window& window, const Rect& oldRect, const Rect& newRect)
{
- //printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height());
+ printf("[WM] Window %p rect changed (%d,%d %dx%d) -> (%d,%d %dx%d)\n", &window, oldRect.x(), oldRect.y(), oldRect.width(), oldRect.height(), newRect.x(), newRect.y(), newRect.width(), newRect.height());
+ repaintAfterMove(oldRect, newRect);
}
void WindowManager::handleTitleBarMouseEvent(Window& window, MouseEvent& event)
@@ -205,7 +215,7 @@ void WindowManager::processMouseEvent(MouseEvent& event)
Point pos = m_dragWindowOrigin;
printf("[WM] Dragging [origin: %d,%d] now: %d,%d\n", m_dragOrigin.x(), m_dragOrigin.y(), event.x(), event.y());
pos.moveBy(event.x() - m_dragOrigin.x(), event.y() - m_dragOrigin.y());
- m_dragWindow->setPosition(pos);
+ m_dragWindow->setPositionWithoutRepaint(pos);
paintWindowFrame(*m_dragWindow);
return;
}
@@ -243,9 +253,8 @@ void WindowManager::handlePaintEvent(PaintEvent& event)
m_rootWidget->event(event);
paintWindowFrames();
- for (auto* window : m_windows) {
+ for (auto* window : m_windows)
window->event(event);
- }
}
void WindowManager::event(Event& event)
@@ -296,3 +305,8 @@ void WindowManager::setActiveWindow(Window* window)
}
}
+bool WindowManager::isVisible(Window& window) const
+{
+ return m_windows.contains(&window);
+}
+
diff --git a/Widgets/WindowManager.h b/Widgets/WindowManager.h
index f53c29740e..02073ba3cb 100644
--- a/Widgets/WindowManager.h
+++ b/Widgets/WindowManager.h
@@ -27,6 +27,10 @@ public:
Window* activeWindow() { return m_activeWindow.ptr(); }
void setActiveWindow(Window*);
+ bool isVisible(Window&) const;
+
+ void repaint();
+
private:
WindowManager();
~WindowManager();
diff --git a/Widgets/test.cpp b/Widgets/test.cpp
index 054c7e343b..ca72394d45 100644
--- a/Widgets/test.cpp
+++ b/Widgets/test.cpp
@@ -86,6 +86,7 @@ int main(int argc, char** argv)
tb->onReturnPressed = [] (TextBox& textBox) {
printf("TextBox %p return pressed: '%s'\n", &textBox, textBox.text().characters());
+ MsgBox(nullptr, textBox.text());
};
WindowManager::the().setActiveWindow(widgetTestWindow);