Move mainwindow to app/

This commit is contained in:
2025-03-15 11:18:12 -04:00
parent d230662924
commit f5a38892b1
10 changed files with 18 additions and 13 deletions

View File

@@ -9,7 +9,11 @@
# Qtk Application
################################################################################
set(QTK_GUI_SOURCES qtkscene.cpp qtkscene.h main.cpp)
set(QTK_GUI_SOURCES
qtkmainwindow.cpp qtkmainwindow.h qtkmainwindow.ui
qtkscene.cpp qtkscene.h
main.cpp
)
qt_add_executable(qtk_gui ${QTK_GUI_SOURCES})
target_link_libraries(qtk_gui PRIVATE qtk_plugin_library)

View File

@@ -8,7 +8,7 @@
#include <QApplication>
#include "designer-plugins/qtkmainwindow.h"
#include "qtkmainwindow.h"
#include "qtkscene.h"
int main(int argc, char * argv[])

104
src/app/qtkmainwindow.cpp Normal file
View File

@@ -0,0 +1,104 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: MainWindow for Qtk application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include "qtkmainwindow.h"
#include "ui_qtkmainwindow.h"
/*******************************************************************************
* Constructors / Destructors
******************************************************************************/
MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
{
ui_ = new Ui::MainWindow;
setObjectName("MainWindow");
// For use in design mode using Qt Creator
// + We can use the `ui` member to access nested widgets by name
ui_->setupUi(this);
ui_->menuView->addAction(ui_->toolBar->toggleViewAction());
// Initialize static container for all active QtkWidgets
auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
for (auto & qtkWidget : qtkWidgets) {
// NOTE: Set a temporary scene for the widget to use for initialization.
// This should be replaced by loading a scene, or creating a new (unsaved)
// scene when Qtk is opened.
qtkWidget->setScene(new EmptyScene);
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
// Add GUI 'view' toolbar option to show debug console.
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
// Refresh GUI widgets when scene or objects are updated.
connect(qtkWidget->getScene(),
&Qtk::Scene::sceneUpdated,
this,
&MainWindow::refreshScene);
// Update the ToolBox details panel when an item is double-clicked.
connect(qtkWidget,
&Qtk::QtkWidget::objectFocusChanged,
ui_->qtk__ToolBox,
&Qtk::ToolBox::updateFocus);
}
// TODO: Fix / use MainWindow in Qt Designer to add these dock widgets.
// For now we will add them manually, but we should be able to do this in the
// designer. At the moment if you edit the UI in designer the dock widget
// areas below will override the designer settings.
// Dock the toolbox widget to the main window.
addDockWidget(Qt::LeftDockWidgetArea, ui_->qtk__ToolBox);
// Add an option to toggle active widgets in the GUI's toolbar 'view' menu.
ui_->menuView->addAction(ui_->qtk__ToolBox->toggleViewAction());
addDockWidget(Qt::RightDockWidgetArea, ui_->qtk__TreeView);
ui_->menuView->addAction(ui_->qtk__TreeView->toggleViewAction());
// Set the window icon used for Qtk.
setWindowIcon(Qtk::getIcon());
}
MainWindow::~MainWindow()
{
delete ui_;
}
/*******************************************************************************
* Public Methods
******************************************************************************/
MainWindow * MainWindow::getMainWindow()
{
static auto * window = new MainWindow;
return window;
}
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index)
{
if (views_.size() <= index) {
return Q_NULLPTR;
}
auto it = views_.begin();
std::advance(it, index);
return it->second;
}
Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name)
{
if (!views_.count(name)) {
return Q_NULLPTR;
}
return views_[name];
}
void MainWindow::refreshScene(const QString & sceneName)
{
// TODO: Select TreeView using sceneName
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
}

123
src/app/qtkmainwindow.h Normal file
View File

@@ -0,0 +1,123 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: MainWindow for Qtk application ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <unordered_map>
#include <QMainWindow>
#include <QPlainTextEdit>
#include "designer-plugins/debugconsole.h"
namespace Ui
{
class MainWindow;
}
/**
* An empty scene used for initializing all QtkWidgets within the MainWindow.
* This serves as a temporary placeholder for QtkScene (for example), which is
* defined in the separate qtk_gui target. The reason for this separation is to
* support the use of QtkWidgets (the qtk_plugins target) within the Qt Designer
* application without implementations provided in the Qtk Desktop Application.
*
* For the Qtk application, this should be replaced by loading the previous
* scene or creating a new _unsaved_ scene when the application is opened.
* Currently we have essentially hard-coded QtkScene to use as examples for
* testing the application. This means that the only way to create or modify a
* scene is to write code. Any modifications made in the application, such as
* moving or resizing objects, will not persist and cannot be saved.
*
* For users of Qtk Designer Plugins, this means that installing
* the `qtk_plugins` target to Qt Designer allows use all of the designer's
* features to build an interface and position or resize a QtkWidget as needed.
* The QtkWidget also appears as widget in the IDE's toolbars and can be added
* to any new application easily, once the plugins are installed.
*
* Once the application is designed, you can define a custom scene and use the
* Qtk API or Qt OpenGL funtions directly to render to it.
*
* Any application using a QtkWidget can set a custom scene in their main
* function. See the MainWindow::MainWindow constructor as an example.
*/
class EmptyScene : public Qtk::Scene
{
void init() override { setSceneName("Empty Scene"); }
};
/**
* MainWindow class to provide an example of using a QtkWidget within a Qt
* window application.
*/
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
/***************************************************************************
* Contructors / Destructors
**************************************************************************/
/**
* This ctor also initializes the Scene for each QtkWidget in the window.
* To load a different scene this would need to be updated.
*
* @param parent The parent for this QMainWindow
*/
explicit MainWindow(QWidget * parent = nullptr);
~MainWindow() override;
/***************************************************************************
* Public Methods
**************************************************************************/
/**
* Allows widgets to retrieve an instance of this root QMainWindow.
* @return this
*/
static MainWindow * getMainWindow();
Qtk::QtkWidget * getQtkWidget(int64_t index = 0);
/**
* Accessor for retrieving a QtkWidget by it's objectName.
* This function will not construct a new QtkWidget if none is found.
*
* @param name The objectName associated with the QtkWidget.
* @return Pointer to an active QtkWidget or Q_NULLPTR is not found.
*/
Qtk::QtkWidget * getQtkWidget(const QString & name);
public slots:
/**
* Trigger a refresh for widgets related to a scene that has been updated.
* @param sceneName The name of the scene that has been modified.
*/
void refreshScene(const QString & sceneName);
private:
/***************************************************************************
* Private Members
**************************************************************************/
/** Do not allow copying */
MainWindow(const MainWindow &) {};
Ui::MainWindow * ui_ {};
/**
* Maps a scene name to the QtkWidget viewing it.
* TODO: Value should be a vector of QtkWidget * for multiple scene views.
*/
std::unordered_map<QString, Qtk::QtkWidget *> views_ {};
};
#endif // MAINWINDOW_H

348
src/app/qtkmainwindow.ui Normal file
View File

@@ -0,0 +1,348 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1034</width>
<height>601</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Qtk - MainWindow</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../resources/icons/icon.png</normaloff>../resources/icons/icon.png</iconset>
</property>
<property name="unifiedTitleAndToolBarOnMac">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Object details and configuration panel.</string>
</property>
<property name="whatsThis">
<string>When an object is double-clicked in the TreeView for a scene, this panel will display relevant details and options.</string>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="movable">
<bool>true</bool>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>View 1</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
<property name="toolTip">
<string/>
</property>
<property name="whatsThis">
<string>Qtk scene view rendered using OpenGL.</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>View 2</string>
</attribute>
</widget>
</widget>
</item>
<item>
<widget class="Qtk::TreeView" name="qtk::TreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>TreeView of objects within the current scene.</string>
</property>
<property name="whatsThis">
<string>TreeView of objects within the current scene. Double-click to select an object and snap to it's position.</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1034</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuTest">
<property name="title">
<string>File</string>
</property>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="separator"/>
<addaction name="actionSave"/>
<addaction name="actionSave_as"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
<widget class="QMenu" name="menuTab_Position">
<property name="title">
<string>Tab Position</string>
</property>
<addaction name="actionTop"/>
<addaction name="actionBottom"/>
<addaction name="actionLeft"/>
<addaction name="actionRight"/>
</widget>
<addaction name="menuTab_Position"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionAbout"/>
</widget>
<addaction name="menuTest"/>
<addaction name="menuEdit"/>
<addaction name="menuView"/>
<addaction name="menuHelp"/>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="floatable">
<bool>true</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionLoad_Model"/>
<addaction name="actionDelete_Object"/>
</widget>
<action name="actionOpen">
<property name="icon">
<iconset>
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</iconset>
</property>
<property name="text">
<string>Open...</string>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset>
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
</property>
<property name="text">
<string>Save</string>
</property>
</action>
<action name="actionSave_as">
<property name="text">
<string>Save as...</string>
</property>
</action>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="actionShow_Console">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Show Console</string>
</property>
</action>
<action name="actionLoad_Model">
<property name="icon">
<iconset>
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
</property>
<property name="text">
<string>Load Model</string>
</property>
<property name="font">
<font/>
</property>
</action>
<action name="actionDelete_Object">
<property name="icon">
<iconset>
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
</property>
<property name="text">
<string>Delete Object</string>
</property>
</action>
<action name="actionNew">
<property name="text">
<string>New</string>
</property>
</action>
<action name="actionTop">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Top</string>
</property>
</action>
<action name="actionBottom">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Bottom</string>
</property>
</action>
<action name="actionLeft">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Left</string>
</property>
</action>
<action name="actionRight">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Right</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About</string>
</property>
</action>
<action name="actionNested_Widgets">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Nested Widgets</string>
</property>
</action>
<action name="actionUndo">
<property name="text">
<string>Undo</string>
</property>
</action>
<action name="actionRedo">
<property name="text">
<string>Redo</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>Qtk::QtkWidget</class>
<extends>QOpenGLWidget</extends>
<header>designer-plugins/qtkwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Qtk::TreeView</class>
<extends>QDockWidget</extends>
<header>designer-plugins/treeview.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Qtk::ToolBox</class>
<extends>QDockWidget</extends>
<header>designer-plugins/toolbox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>actionExit</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>411</x>
<y>300</y>
</hint>
</hints>
</connection>
</connections>
</ui>