Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Use a QMainWindow as top-level to enable a proper menubar

This refactor removes CascadeWindow (the old, weird root element)
and puts all of its behvaior in MainWindow, which is a QMainWindow
exposed to QML via the 'window' name. Non-OS X platforms now have
a proper menubar, too.
  • Loading branch information...
commit ed2f0b4b85aa158280a6abb03d5dad749f241ead 1 parent 20c0017
@special authored
View
8 cascade.pro
@@ -12,11 +12,11 @@ macx:QMAKE_POST_LINK += cp $${_PRO_FILE_PWD_}/src/Info.plist $${OUT_PWD}/$${TARG
SOURCES += src/main.cpp \
src/cascade.cpp \
src/file.cpp \
- src/cascadewindow.cpp \
src/filesystemscanner.cpp \
src/filesmodel.cpp \
src/imagedecodingcache.cpp \
- src/fastimageitem.cpp
+ src/fastimageitem.cpp \
+ src/mainwindow.cpp
# Please do not modify the following two lines. Required for deployment.
include(qmlapplicationviewer/qmlapplicationviewer.pri)
@@ -25,11 +25,11 @@ qtcAddDeployment()
HEADERS += \
src/cascade.h \
src/file.h \
- src/cascadewindow.h \
src/filesystemscanner.h \
src/filesmodel.h \
src/imagedecodingcache.h \
- src/fastimageitem.h
+ src/fastimageitem.h \
+ src/mainwindow.h
RESOURCES += \
res/res.qrc
View
16 qml/cascade/main.qml
@@ -1,20 +1,18 @@
import cascade 0.0
import QtQuick 1.1
-CascadeWindow {
+Rectangle {
id: root
width: 800
height: 600
+ color: "black"
focus: true
- windowTitle: "Cascade"
- idealSize: viewer.sourceSize
- idealSizeMargin: Qt.size(filmstripArea.width, 0)
FilmstripArea {
id: filmstripArea
anchors.top: parent.top
anchors.bottom: parent.bottom
- enabled: root.filmstripEnabled
+ enabled: window.filmstripEnabled
}
FastImage {
@@ -57,8 +55,10 @@ CascadeWindow {
when: cascade.currentFile !== null
PropertyChanges {
- target: root
+ target: window
windowTitle: cascade.currentFile.name + " - " + cascade.currentFile.parent.path
+ idealSize: viewer.sourceSize
+ idealSizeMargin: Qt.size(filmstripArea.width, 0)
}
}
@@ -89,7 +89,7 @@ CascadeWindow {
cascade.currentFile = cascade.root.nextFile
break
case Qt.Key_Escape:
- root.toggleFullScreen()
+ window.toggleFullScreen()
break
default:
return
@@ -131,7 +131,7 @@ CascadeWindow {
onDoubleClicked: {
if (root.state != "opened")
- root.openBrowseDialog()
+ window.openBrowseDialog()
}
}
}
View
26 src/main.cpp
@@ -1,38 +1,22 @@
#include <QtGui/QApplication>
#include <QtDeclarative>
-#include "qmlapplicationviewer.h"
#include "cascade.h"
-#include "cascadewindow.h"
#include "file.h"
#include "filesmodel.h"
#include "fastimageitem.h"
+#include "mainwindow.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
- QScopedPointer<QApplication> app(createApplication(argc, argv));
+ QApplication a(argc, argv);
qRegisterMetaType<QList<File*> >();
qmlRegisterUncreatableType<File>("cascade", 0, 0, "File", "");
- qmlRegisterType<CascadeWindow>("cascade", 0, 0, "CascadeWindow");
qmlRegisterType<FilesModel>("cascade", 0, 0, "FilesModel");
qmlRegisterType<FastImageItem>("cascade", 0, 0, "FastImage");
- QmlApplicationViewer viewer;
- viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
- viewer.setAcceptDrops(true);
+ MainWindow *w = new MainWindow;
+ w->show();
- QScopedPointer<Cascade> cascade(new Cascade);
- {
- QStringList arguments = app->arguments();
- if (arguments.size() > 1)
- cascade->setRoot(arguments[1]);
- }
-
- viewer.rootContext()->setContextProperty("cascade", cascade.data());
-
- viewer.setResizeMode(QDeclarativeView::SizeRootObjectToView);
- viewer.setMainQmlFile(QLatin1String("qml/cascade/main.qml"));
- viewer.showExpanded();
-
- return app->exec();
+ return a.exec();
}
View
154 src/cascadewindow.cpp → src/mainwindow.cpp
@@ -1,31 +1,66 @@
-#include "cascadewindow.h"
+#include "mainwindow.h"
+#include "qmlapplicationviewer.h"
#include "cascade.h"
+#include <QDeclarativeContext>
#include <QApplication>
-#include <QPainter>
-#include <QStyleOptionGraphicsItem>
-#include <QFileDialog>
+#include <QMenuBar>
+#include <QGraphicsObject>
#include <QDesktopWidget>
-#include <QGraphicsSceneDragDropEvent>
-#include <QMimeData>
#include <QDesktopServices>
+#include <QFileDialog>
+#include <QResizeEvent>
-CascadeWindow::CascadeWindow(QDeclarativeItem *parent)
- : QDeclarativeItem(parent), widget(qApp->topLevelWidgets()[0]), m_autoResize(true), m_filmstripEnabled(false)
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent), m_menuBar(0), m_autoResize(true), m_filmstripEnabled(false)
{
- setFlag(ItemHasNoContents, false);
setAcceptDrops(true);
+ setWindowTitle(tr("Cascade"));
+ menuBar();
qApp->installEventFilter(this);
m_mouseHideTimer.setInterval(1000);
m_mouseHideTimer.setSingleShot(true);
connect(&m_mouseHideTimer, SIGNAL(timeout()), SLOT(hideMouse()));
- menuBar = new QMenuBar(0);
- QMenu *fileMenu = menuBar->addMenu(tr("&File"));
+ QmlApplicationViewer *viewer = new QmlApplicationViewer;
+ viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
+ viewer->setResizeMode(QDeclarativeView::SizeRootObjectToView);
+ viewer->setAcceptDrops(false);
+
+ Cascade *cascade = new Cascade(this);
+ QStringList args = qApp->arguments();
+ if (args.size() > 1)
+ cascade->setRoot(args[1]);
+ viewer->rootContext()->setContextProperty("cascade", cascade);
+ viewer->rootContext()->setContextProperty("window", this);
+
+ viewer->setMainQmlFile(QLatin1String("qml/cascade/main.qml"));
+ setCentralWidget(viewer);
+
+ setupMenu();
+}
+
+QMenuBar *MainWindow::menuBar()
+{
+#ifdef Q_OS_MAC
+ if (!m_menuBar)
+ m_menuBar = new QMenuBar(0);
+#else
+ if (!m_menuBar)
+ m_menuBar = QMainWindow::menuBar();
+#endif
+ return m_menuBar;
+}
+
+void MainWindow::setupMenu()
+{
+ QMenuBar *menu = menuBar();
+
+ QMenu *fileMenu = menu->addMenu(tr("&File"));
fileMenu->addAction(tr("&Open Folder"), this, SLOT(openBrowseDialog()), QKeySequence(QKeySequence::Open));
fileMenu->addAction(tr("Open File"), this, SLOT(openFileDialog()), QKeySequence(tr("Ctrl+Shift+O")));
- QMenu *viewMenu = menuBar->addMenu(tr("&View"));
+ QMenu *viewMenu = menu->addMenu(tr("&View"));
viewMenu->addAction(tr("&Auto Size Window"), this, SLOT(toggleAutoResize()), QKeySequence(tr("Ctrl+A")));
viewMenu->addAction(tr("&Full Screen"), this, SLOT(toggleFullScreen()), QKeySequence(tr("Ctrl+F")));
@@ -36,13 +71,24 @@ CascadeWindow::CascadeWindow(QDeclarativeItem *parent)
connect(this, SIGNAL(filmstripEnabledChanged(bool)), a, SLOT(setChecked(bool)));
}
-bool CascadeWindow::eventFilter(QObject *, QEvent *ev)
+void MainWindow::hideMouse()
+{
+ setCursor(Qt::BlankCursor);
+}
+
+void MainWindow::showMouse()
+{
+ setCursor(Qt::ArrowCursor);
+ m_mouseHideTimer.stop();
+}
+
+bool MainWindow::eventFilter(QObject *, QEvent *ev)
{
switch (ev->type()) {
case QEvent::MouseMove:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
- if (fullScreen()) {
+ if (isFullScreen()) {
showMouse();
m_mouseHideTimer.start();
}
@@ -54,52 +100,21 @@ bool CascadeWindow::eventFilter(QObject *, QEvent *ev)
return false;
}
-void CascadeWindow::paint(QPainter *p, const QStyleOptionGraphicsItem *opt, QWidget *)
-{
- p->fillRect(opt->rect, Qt::black);
-}
-
-QString CascadeWindow::windowTitle() const
-{
- return widget->windowTitle();
-}
-
-void CascadeWindow::setWindowTitle(const QString &title)
-{
- widget->setWindowTitle(title);
-}
-
-void CascadeWindow::hideMouse()
-{
- widget->setCursor(Qt::BlankCursor);
-}
-
-void CascadeWindow::showMouse()
-{
- widget->setCursor(Qt::ArrowCursor);
- m_mouseHideTimer.stop();
-}
-
-bool CascadeWindow::fullScreen() const
-{
- return widget->isFullScreen();
-}
-
-void CascadeWindow::setFullScreen(bool on)
+void MainWindow::setFullScreen(bool on)
{
bool preserveAuto = m_autoResize;
if (on)
{
- widget->showFullScreen();
+ showFullScreen();
hideMouse();
}
else
{
/* Resize the window while hidden to avoid some flickering */
- widget->hide();
- widget->setWindowState(widget->windowState() & ~Qt::WindowFullScreen);
+ hide();
+ setWindowState(windowState() & ~Qt::WindowFullScreen);
updateAutoSize();
- widget->show();
+ showNormal();
showMouse();
}
/* Reset to preserve after the resize */
@@ -107,29 +122,30 @@ void CascadeWindow::setFullScreen(bool on)
emit fullScreenChanged(on);
}
-void CascadeWindow::updateAutoSize()
+void MainWindow::updateAutoSize()
{
- if (!m_autoResize || fullScreen())
+ if (!m_autoResize || isFullScreen())
return;
QDesktopWidget *desktop = qApp->desktop();
- QRect available = desktop->availableGeometry(desktop->screenNumber(widget));
+ QRect available = desktop->availableGeometry(desktop->screenNumber(this));
available.adjust(m_idealSizeMargin.width()/2, m_idealSizeMargin.height()/2,
m_idealSizeMargin.width()/-2, m_idealSizeMargin.height()/-2);
QSizeF ideal = m_idealSize;
ideal.scale(available.size() * 0.9, Qt::KeepAspectRatio);
ideal += m_idealSizeMargin;
+ ideal += size() - centralWidget()->size();
QSizeF margin = (available.size() - ideal) / 2;
available.adjust(margin.width(), margin.height(), -margin.width(), -margin.height());
- widget->setGeometry(available.x(), available.y(), ideal.width(), ideal.height());
+ setGeometry(available.x(), available.y(), ideal.width(), ideal.height());
/* Reset, because geometryChanged unsets it for all other kinds of resizing */
m_autoResize = true;
}
-void CascadeWindow::setIdealSize(QSize ideal)
+void MainWindow::setIdealSize(QSize ideal)
{
if (ideal == m_idealSize || !ideal.isValid())
return;
@@ -138,7 +154,7 @@ void CascadeWindow::setIdealSize(QSize ideal)
updateAutoSize();
}
-void CascadeWindow::setIdealSizeMargin(QSizeF margin)
+void MainWindow::setIdealSizeMargin(QSizeF margin)
{
if (margin == m_idealSizeMargin)
return;
@@ -147,7 +163,7 @@ void CascadeWindow::setIdealSizeMargin(QSizeF margin)
updateAutoSize();
}
-void CascadeWindow::setAutoResize(bool on)
+void MainWindow::setAutoResize(bool on)
{
if (on == m_autoResize)
return;
@@ -157,17 +173,17 @@ void CascadeWindow::setAutoResize(bool on)
updateAutoSize();
}
-void CascadeWindow::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void MainWindow::resizeEvent(QResizeEvent *event)
{
- QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
+ QMainWindow::resizeEvent(event);
/* Turn off auto sizing; if this resize was caused by auto sizing, it will be reset
* afterwards. */
- if (widget->isVisible())
+ if (isVisible())
m_autoResize = false;
}
-void CascadeWindow::setFilmstripEnabled(bool on)
+void MainWindow::setFilmstripEnabled(bool on)
{
if (on == m_filmstripEnabled)
return;
@@ -176,27 +192,27 @@ void CascadeWindow::setFilmstripEnabled(bool on)
emit filmstripEnabledChanged(on);
}
-void CascadeWindow::openBrowseDialog()
+void MainWindow::openBrowseDialog()
{
QString current = cascade->root() ? cascade->root()->path() : QDesktopServices::storageLocation(QDesktopServices::PicturesLocation);
- QString path = QFileDialog::getExistingDirectory(widget, tr("Open Folder"), current, 0);
- widget->activateWindow();
+ QString path = QFileDialog::getExistingDirectory(this, tr("Open Folder"), current, 0);
+ activateWindow();
if (path.isEmpty())
return;
cascade->setRoot(path);
}
-void CascadeWindow::openFileDialog()
+void MainWindow::openFileDialog()
{
QString current = cascade->root() ? cascade->root()->path() : QDesktopServices::storageLocation(QDesktopServices::PicturesLocation);
- QString path = QFileDialog::getOpenFileName(widget, tr("Open File"), current, tr("Images (*.jpg *.png)"));
- widget->activateWindow();
+ QString path = QFileDialog::getOpenFileName(this, tr("Open File"), current, tr("Images (*.jpg *.png)"));
+ activateWindow();
if (path.isEmpty())
return;
cascade->setRoot(path);
}
-void CascadeWindow::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
/* We only accept one local file URL, which can be a folder or a file.
* Dragging multiple files/folders is ignored. */
@@ -205,7 +221,7 @@ void CascadeWindow::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
event->acceptProposedAction();
}
-void CascadeWindow::dropEvent(QGraphicsSceneDragDropEvent *event)
+void MainWindow::dropEvent(QDropEvent *event)
{
QUrl url = event->mimeData()->urls().value(0, QUrl());
if (!url.isValid() || url.scheme() != "file")
View
35 src/cascadewindow.h → src/mainwindow.h
@@ -1,11 +1,10 @@
-#ifndef CASCADEWINDOW_H
-#define CASCADEWINDOW_H
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
-#include <QDeclarativeItem>
-#include <QMenuBar>
+#include <QMainWindow>
#include <QTimer>
-class CascadeWindow : public QDeclarativeItem
+class MainWindow : public QMainWindow
{
Q_OBJECT
@@ -14,25 +13,23 @@ class CascadeWindow : public QDeclarativeItem
Q_PROPERTY(QSizeF idealSizeMargin READ idealSizeMargin WRITE setIdealSizeMargin)
Q_PROPERTY(bool filmstripEnabled READ isFilmstripEnabled WRITE setFilmstripEnabled NOTIFY filmstripEnabledChanged)
Q_PROPERTY(bool autoResize READ isAutoResize WRITE setAutoResize NOTIFY autoResizeChanged)
- Q_PROPERTY(bool fullScreen READ fullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
+ Q_PROPERTY(bool fullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
public:
- explicit CascadeWindow(QDeclarativeItem *parent = 0);
+ explicit MainWindow(QWidget *parent = 0);
+
+ /* Override QMainWindow for OS X-specific behavior */
+ QMenuBar *menuBar();
- QString windowTitle() const;
- bool fullScreen() const;
QSize idealSize() const { return m_idealSize; }
QSizeF idealSizeMargin() const { return m_idealSizeMargin; }
bool isFilmstripEnabled() const { return m_filmstripEnabled; }
bool isAutoResize() const { return m_autoResize; }
- virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
-
public slots:
- void setWindowTitle(const QString &title);
void setFullScreen(bool on);
- void toggleFullScreen() { setFullScreen(!fullScreen()); }
+ void toggleFullScreen() { setFullScreen(!isFullScreen()); }
void setFilmstripEnabled(bool on);
void toggleFilmstrip() { setFilmstripEnabled(!isFilmstripEnabled()); }
void setIdealSize(QSize size);
@@ -53,20 +50,20 @@ public slots:
void fullScreenChanged(bool fullScreen);
protected:
- virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
- virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
- virtual void dropEvent(QGraphicsSceneDragDropEvent *event);
+ virtual void resizeEvent(QResizeEvent *);
virtual bool eventFilter(QObject *, QEvent *);
+ virtual void dragEnterEvent(QDragEnterEvent *);
+ virtual void dropEvent(QDropEvent *);
private:
- QWidget * const widget;
- QMenuBar *menuBar;
+ QMenuBar *m_menuBar;
QSize m_idealSize;
QSizeF m_idealSizeMargin;
QTimer m_mouseHideTimer;
bool m_autoResize, m_filmstripEnabled;
+ void setupMenu();
void updateAutoSize();
};
-#endif // CASCADEWINDOW_H
+#endif // MAINWINDOW_H
Please sign in to comment.
Something went wrong with that request. Please try again.