Skip to content
Prev Previous commit
Next Next commit
Add QuickWindow class
  • Loading branch information
adazem009 committed Feb 29, 2024
commit b336127c081c8b898abbb47ff56cbfa38af1fa9c
2 changes: 2 additions & 0 deletions src/uicomponents/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ set(MODULE_SRC
menuitemmodel.h
filedialog.cpp
filedialog.h
internal/quickwindow.cpp
internal/quickwindow.h
)

include(${PROJECT_SOURCE_DIR}/build/module.cmake)
Expand Down
75 changes: 75 additions & 0 deletions src/uicomponents/internal/quickwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <QAccessibleWidget>

#include "quickwindow.h"

using namespace scratchcpp::uicomponents;

QuickWindow::QuickWindow(QWindow *parent) :
QQuickWindow(parent)
{
m_accessibleWidget = new QAccessibleWidget(&m_widget, QAccessible::Dialog);
m_accessibleWidget->setText(QAccessible::Name, title());
m_widget.setAccessibleName(title());
QAccessibleEvent accessibleEvent(m_accessibleWidget, QAccessible::NameChanged);
QAccessible::updateAccessibility(&accessibleEvent);

connect(this, &QQuickWindow::windowTitleChanged, [this](const QString &title) {
m_accessibleWidget->setText(QAccessible::Name, title);
m_widget.setAccessibleName(title);
QAccessibleEvent accessibleEvent(m_accessibleWidget, QAccessible::NameChanged);
QAccessible::updateAccessibility(&accessibleEvent);
});
}

void QuickWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape && m_autoClose && m_closable)
close();

QQuickWindow::keyPressEvent(event);
}

void QuickWindow::showEvent(QShowEvent *event)
{
QQuickWindow::showEvent(event);
QAccessibleEvent accessibleEvent(m_accessibleWidget, QAccessible::Focus);
QAccessible::updateAccessibility(&accessibleEvent);
}

void QuickWindow::closeEvent(QCloseEvent *event)
{
if (m_closable)
QQuickWindow::closeEvent(event);
else
event->ignore();
}

void QuickWindow::setAutoClose(bool newAutoClose)
{
if (m_autoClose == newAutoClose)
return;

m_autoClose = newAutoClose;
emit autoCloseChanged();
}

bool QuickWindow::closable() const
{
return m_closable;
}

void QuickWindow::setClosable(bool newClosable)
{
if (m_closable == newClosable)
return;

m_closable = newClosable;
emit closableChanged();
}

bool QuickWindow::autoClose() const
{
return m_autoClose;
}
42 changes: 42 additions & 0 deletions src/uicomponents/internal/quickwindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <QQuickWindow>
#include <QWidget>

namespace scratchcpp::uicomponents
{

class QuickWindow : public QQuickWindow
{
Q_OBJECT
Q_PROPERTY(bool autoClose READ autoClose WRITE setAutoClose NOTIFY autoCloseChanged)
Q_PROPERTY(bool closable READ closable WRITE setClosable NOTIFY closableChanged)

public:
explicit QuickWindow(QWindow *parent = nullptr);

bool autoClose() const;
void setAutoClose(bool newAutoClose);

bool closable() const;
void setClosable(bool newClosable);

signals:
void autoCloseChanged();
void closableChanged();

protected:
void keyPressEvent(QKeyEvent *event) override;
void showEvent(QShowEvent *event) override;
void closeEvent(QCloseEvent *event) override;

private:
bool m_autoClose = true;
bool m_closable = true;
QWidget m_widget;
QAccessibleWidget *m_accessibleWidget = nullptr;
};

} // namespace scratchcpp::uicomponents
1 change: 1 addition & 0 deletions src/uicomponents/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set(MODULE_TEST_SRC
menumodel.cpp
menubarmodel.cpp
filedialog.cpp
quickwindow.cpp
)

include(${PROJECT_SOURCE_DIR}/build/module_test.cmake)
101 changes: 101 additions & 0 deletions src/uicomponents/test/quickwindow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include <gtest/gtest.h>
#include <QSignalSpy>

#include "internal/quickwindow.h"

using namespace scratchcpp::uicomponents;

TEST(QuickWindowTest, Constructor)
{
QuickWindow window1;
QWindow window2(&window1);
ASSERT_EQ(window1.parent(), nullptr);
ASSERT_EQ(window2.parent(), &window1);
}

TEST(QuickWindowTest, AutoClose)
{
QuickWindow window;
QSignalSpy spy(&window, &QuickWindow::autoCloseChanged);
ASSERT_TRUE(window.autoClose());

window.setAutoClose(false);
ASSERT_FALSE(window.autoClose());
ASSERT_EQ(spy.count(), 1);

window.setAutoClose(false);
ASSERT_FALSE(window.autoClose());
ASSERT_EQ(spy.count(), 1);

window.setAutoClose(true);
ASSERT_TRUE(window.autoClose());
ASSERT_EQ(spy.count(), 2);
}

TEST(QuickWindowTest, Closable)
{
QuickWindow window;
QSignalSpy spy(&window, &QuickWindow::closableChanged);
ASSERT_TRUE(window.closable());

window.setClosable(false);
ASSERT_FALSE(window.closable());
ASSERT_EQ(spy.count(), 1);

window.setClosable(false);
ASSERT_FALSE(window.closable());
ASSERT_EQ(spy.count(), 1);

window.setClosable(true);
ASSERT_TRUE(window.closable());
ASSERT_EQ(spy.count(), 2);
}

TEST(QuickWindowTest, KeyPressEvent)
{
QuickWindow window;
window.setAutoClose(true);
window.setClosable(true);
ASSERT_FALSE(window.isVisible());
window.show();
ASSERT_TRUE(window.isVisible());

QKeyEvent event1(QEvent::KeyPress, Qt::Key_Space, Qt::NoModifier, " ");
QCoreApplication::sendEvent(&window, &event1);
ASSERT_TRUE(window.isVisible());

QKeyEvent event2(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier, "");
QCoreApplication::sendEvent(&window, &event2);
ASSERT_FALSE(window.isVisible());

window.show();
window.setAutoClose(false);
QCoreApplication::sendEvent(&window, &event2);
ASSERT_TRUE(window.isVisible());

window.setClosable(false);
QCoreApplication::sendEvent(&window, &event2);
ASSERT_TRUE(window.isVisible());

window.setAutoClose(true);
QCoreApplication::sendEvent(&window, &event2);
ASSERT_TRUE(window.isVisible());
}

TEST(QuickWindowTest, CloseEvent)
{
QuickWindow window;
window.setClosable(true);
ASSERT_FALSE(window.isVisible());
window.show();
ASSERT_TRUE(window.isVisible());

QCloseEvent event;
QCoreApplication::sendEvent(&window, &event);
ASSERT_FALSE(window.isVisible());

window.setClosable(false);
window.show();
QCoreApplication::sendEvent(&window, &event);
ASSERT_TRUE(window.isVisible());
}