Qt: Cleanup abstraction layers a bit.
Move some code from header to source. The header has not been removed entirely so that Qt MOC files can use it. - Rename GLWidget as SSView and QtGLMainWindow as SSMainWindow.pull/1451/head
parent
7e8a7c8ffb
commit
a4eb339e6c
|
@ -7,15 +7,18 @@
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "guiqt.h"
|
#include "guiqt.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QScreen>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
@ -638,9 +641,186 @@ MenuBarRef GetOrCreateMainMenu(bool* unique) {
|
||||||
// Windows
|
// Windows
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void SSView::startEditing(int x, int y, int fontHeight, int minWidth,
|
||||||
|
bool isMonoSpace, const std::string& val)
|
||||||
|
{
|
||||||
|
entry->setGeometry(QRect(x, y, minWidth, fontHeight));
|
||||||
|
entry->setText(QString::fromStdString(val));
|
||||||
|
|
||||||
|
if (!entry->isVisible()) {
|
||||||
|
entry->show();
|
||||||
|
entry->setFocus();
|
||||||
|
entry->setCursorPosition(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSView::stopEditing() {
|
||||||
|
if (entry->isVisible()) {
|
||||||
|
entry->hide();
|
||||||
|
setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSView::wheelEvent(QWheelEvent* event)
|
||||||
|
{
|
||||||
|
const double wheelDelta=120.0;
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::NONE;
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::SCROLL_VERT;
|
||||||
|
slvMouseEvent.scrollDelta = (double)event->angleDelta().y() / wheelDelta;
|
||||||
|
|
||||||
|
emit mouseEventOccuredSignal(slvMouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSView::updateSlvSpaceMouseEvent(QMouseEvent* event)
|
||||||
|
{
|
||||||
|
slvMouseEvent.shiftDown = false;
|
||||||
|
slvMouseEvent.controlDown = false;
|
||||||
|
|
||||||
|
switch (event->type())
|
||||||
|
{
|
||||||
|
case QEvent::MouseMove:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::MOTION;
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::PRESS;
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonDblClick:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::DBL_PRESS;
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::RELEASE;
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::NONE;
|
||||||
|
break;
|
||||||
|
case QEvent::Wheel:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::SCROLL_VERT;
|
||||||
|
//slvMouseEvent.scrollDelta = event->
|
||||||
|
break;
|
||||||
|
case QEvent::Leave:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::LEAVE;
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::NONE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
slvMouseEvent.type = MouseEvent::Type::RELEASE;
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::MouseButtons buttonState = (slvMouseEvent.type == MouseEvent::Type::MOTION) ? event->buttons() : event->button();
|
||||||
|
|
||||||
|
switch (buttonState)
|
||||||
|
{
|
||||||
|
case Qt::MouseButton::LeftButton:
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::LEFT;
|
||||||
|
break;
|
||||||
|
case Qt::MouseButton::RightButton:
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::RIGHT;
|
||||||
|
break;
|
||||||
|
case Qt::MouseButton::MidButton:
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::MIDDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
slvMouseEvent.button = MouseEvent::Button::NONE;
|
||||||
|
//slvMouseEvent.button = slvMouseEvent.button;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
slvMouseEvent.x = event->pos().x();
|
||||||
|
slvMouseEvent.y = event->pos().y();
|
||||||
|
Qt::KeyboardModifiers keyModifier = QGuiApplication::keyboardModifiers();
|
||||||
|
|
||||||
|
switch (keyModifier)
|
||||||
|
{
|
||||||
|
case Qt::ShiftModifier:
|
||||||
|
slvMouseEvent.shiftDown = true;
|
||||||
|
break;
|
||||||
|
case Qt::ControlModifier:
|
||||||
|
slvMouseEvent.controlDown = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit mouseEventOccuredSignal(slvMouseEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to override the event method to catch the tab key during a key press event
|
||||||
|
* Qt does not send a key press event when the tab key is presed. To get that
|
||||||
|
* we need to overwrite the event functon and check if the tab key was presed during a key press event
|
||||||
|
* otherwise we send the rest of the event back to the widget for further processes
|
||||||
|
*/
|
||||||
|
bool SSView::event(QEvent* e)
|
||||||
|
{
|
||||||
|
if(e->type() == QEvent::KeyPress) {
|
||||||
|
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(e);
|
||||||
|
if(keyEvent->key() == Qt::Key_Tab)
|
||||||
|
emit tabKeyPressed();
|
||||||
|
} else {
|
||||||
|
QWidget::event(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSView::updateSlvSpaceKeyEvent(QKeyEvent* event)
|
||||||
|
{
|
||||||
|
slvKeyEvent.key = KeyboardEvent::Key(-1);
|
||||||
|
slvKeyEvent.shiftDown = false;
|
||||||
|
slvKeyEvent.controlDown = false;
|
||||||
|
if (event->modifiers() == Qt::ShiftModifier)
|
||||||
|
slvKeyEvent.shiftDown = true;
|
||||||
|
if (event->modifiers() == Qt::ControlModifier)
|
||||||
|
slvKeyEvent.controlDown = true;
|
||||||
|
|
||||||
|
if (event->key() >= Qt::Key_F1 && event->key() <= Qt::Key_F35) {
|
||||||
|
slvKeyEvent.key = KeyboardEvent::Key::FUNCTION;
|
||||||
|
slvKeyEvent.num = event->key() - Qt::Key_F1 + 1;
|
||||||
|
}
|
||||||
|
if (event->key() >= Qt::Key_Space && event->key() <= Qt::Key_yen) {
|
||||||
|
slvKeyEvent.key = KeyboardEvent::Key::CHARACTER;
|
||||||
|
QString keyLower = event->text().toLower();
|
||||||
|
slvKeyEvent.chr = keyLower.toUcs4().at(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit keyEventOccuredSignal(slvKeyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSMainWindow::SSMainWindow(Platform::Window* pwin,
|
||||||
|
Platform::Window::Kind kind, QWidget* parent)
|
||||||
|
: QMainWindow(parent), receiver(pwin)
|
||||||
|
{
|
||||||
|
ssView = new SSView;
|
||||||
|
if (kind == Platform::Window::Kind::TOOL) {
|
||||||
|
QWidget* group = new QWidget;
|
||||||
|
scrollBar = new QScrollBar(Qt::Vertical, group);
|
||||||
|
connect(scrollBar, SIGNAL(valueChanged(int)), SLOT(sliderSlot(int)));
|
||||||
|
|
||||||
|
QHBoxLayout* lo = new QHBoxLayout(group);
|
||||||
|
lo->setContentsMargins(0, 0, 0, 0);
|
||||||
|
lo->setSpacing(2);
|
||||||
|
lo->addWidget(ssView);
|
||||||
|
lo->addWidget(scrollBar);
|
||||||
|
group->setLayout(lo);
|
||||||
|
|
||||||
|
setCentralWidget(group);
|
||||||
|
//setWindowFlags(Qt::Tool);
|
||||||
|
} else {
|
||||||
|
scrollBar = nullptr;
|
||||||
|
setCentralWidget(ssView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSMainWindow::sliderSlot(int value)
|
||||||
|
{
|
||||||
|
if (receiver->onScrollbarAdjusted)
|
||||||
|
receiver->onScrollbarAdjusted(double(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSMainWindow::closeEvent(QCloseEvent* ev)
|
||||||
|
{
|
||||||
|
emit windowClosedSignal();
|
||||||
|
ev->ignore();
|
||||||
|
}
|
||||||
|
|
||||||
class WindowImplQt final : public Window, public QObject {
|
class WindowImplQt final : public Window, public QObject {
|
||||||
public:
|
public:
|
||||||
QtGLMainWindow* windowGLQ;
|
SSMainWindow* ssWindow;
|
||||||
Window::Kind windowKind;
|
Window::Kind windowKind;
|
||||||
std::shared_ptr<WindowImplQt> parentWindow;
|
std::shared_ptr<WindowImplQt> parentWindow;
|
||||||
//std::shared_ptr<MenuBarImpQt> menuBarQt;
|
//std::shared_ptr<MenuBarImpQt> menuBarQt;
|
||||||
|
@ -649,15 +829,15 @@ public:
|
||||||
: windowKind(kind),
|
: windowKind(kind),
|
||||||
parentWindow(parent)
|
parentWindow(parent)
|
||||||
{
|
{
|
||||||
windowGLQ = new QtGLMainWindow(this, kind, parentWindow ? parentWindow->windowGLQ : nullptr);
|
ssWindow = new SSMainWindow(this, kind, parentWindow ? parentWindow->ssWindow : nullptr);
|
||||||
connect(windowGLQ, &QtGLMainWindow::windowClosedSignal, this, &WindowImplQt::runOnClose);
|
connect(ssWindow, &SSMainWindow::windowClosedSignal, this, &WindowImplQt::runOnClose);
|
||||||
|
|
||||||
GLWidget* view = windowGLQ->GetGlWidget();
|
SSView* view = ssWindow->ssView;
|
||||||
connect(view, &GLWidget::mouseEventOccuredSignal, this, &WindowImplQt::runOnMouseEvent);
|
connect(view, &SSView::mouseEventOccuredSignal, this, &WindowImplQt::runOnMouseEvent);
|
||||||
connect(view, &GLWidget::keyEventOccuredSignal, this, &WindowImplQt::runOnKeyboardEvent);
|
connect(view, &SSView::keyEventOccuredSignal, this, &WindowImplQt::runOnKeyboardEvent);
|
||||||
connect(view, &GLWidget::renderOccuredSignal, this, &WindowImplQt::runOnRender);
|
connect(view, &SSView::renderOccuredSignal, this, &WindowImplQt::runOnRender);
|
||||||
connect(view, &GLWidget::editingDoneSignal, this, &WindowImplQt::runOnEditingDone);
|
connect(view, &SSView::editingDoneSignal, this, &WindowImplQt::runOnEditingDone);
|
||||||
connect(view, &GLWidget::tabKeyPressed, this, &WindowImplQt::processTabKeyPressed);
|
connect(view, &SSView::tabKeyPressed, this, &WindowImplQt::processTabKeyPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
~WindowImplQt() {
|
~WindowImplQt() {
|
||||||
|
@ -685,13 +865,13 @@ public:
|
||||||
|
|
||||||
// Returns physical display DPI.
|
// Returns physical display DPI.
|
||||||
double GetPixelDensity() override {
|
double GetPixelDensity() override {
|
||||||
return windowGLQ->GetPixelDensity();
|
return QGuiApplication::primaryScreen()->logicalDotsPerInch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns raster graphics and coordinate scale (already applied on the platform side),
|
// Returns raster graphics and coordinate scale (already applied on the platform side),
|
||||||
// i.e. size of logical pixel in physical pixels, or device pixel ratio.
|
// i.e. size of logical pixel in physical pixels, or device pixel ratio.
|
||||||
double GetDevicePixelRatio() override {
|
double GetDevicePixelRatio() override {
|
||||||
return windowGLQ->GetDevicePixelRatio();
|
return ssWindow->ssView->devicePixelRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns (fractional) font scale, to be applied on top of (integral) device pixel ratio.
|
// Returns (fractional) font scale, to be applied on top of (integral) device pixel ratio.
|
||||||
|
@ -700,70 +880,69 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsVisible() override {
|
bool IsVisible() override {
|
||||||
return windowGLQ->IsVisible();
|
return ssWindow->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetVisible(bool visible) override {
|
void SetVisible(bool visible) override {
|
||||||
windowGLQ->setVisible(visible);
|
ssWindow->setVisible(visible);
|
||||||
windowGLQ->raise();
|
ssWindow->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Focus() override {
|
void Focus() override {
|
||||||
windowGLQ->setFocus();
|
ssWindow->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsFullScreen() override {
|
bool IsFullScreen() override {
|
||||||
return windowGLQ->isFullScreen();
|
return ssWindow->isFullScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetFullScreen(bool fullScreen) override {
|
void SetFullScreen(bool fullScreen) override {
|
||||||
if (true == fullScreen)
|
// Qt::WindowNoState is "normal".
|
||||||
windowGLQ->setWindowState(Qt::WindowFullScreen);
|
ssWindow->setWindowState(fullScreen ? Qt::WindowFullScreen
|
||||||
else
|
: Qt::WindowNoState);
|
||||||
windowGLQ->setWindowState(Qt::WindowNoState); //The window has no state set (in normal state).
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTitle(const std::string& title) override {
|
void SetTitle(const std::string& title) override {
|
||||||
windowGLQ->setWindowTitle(QString::fromStdString(title));
|
ssWindow->setWindowTitle(QString::fromStdString(title));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMenuBar(MenuBarRef menuBar) override {
|
void SetMenuBar(MenuBarRef menuBar) override {
|
||||||
// Cast this menu bar to a Qt
|
// Cast this menu bar to a Qt
|
||||||
//menuBarQt = std::static_pointer_cast<MenuBarImpQt>(menuBar);
|
//menuBarQt = std::static_pointer_cast<MenuBarImpQt>(menuBar);
|
||||||
//windowGLQ->setMenuBar(menuBarQt->menuBarQ);
|
//ssWindow->setMenuBar(menuBarQt->menuBarQ);
|
||||||
|
|
||||||
if(windowGLQ->menuBar() != gMenuBarQt->menuBarQ) {
|
if(ssWindow->menuBar() != gMenuBarQt->menuBarQ) {
|
||||||
windowGLQ->setMenuBar(gMenuBarQt->menuBarQ);
|
ssWindow->setMenuBar(gMenuBarQt->menuBarQ);
|
||||||
gMenuBarQt->findShowPropertyBrowserMenuItem();
|
gMenuBarQt->findShowPropertyBrowserMenuItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetContentSize(double* width, double* height) override {
|
void GetContentSize(double* width, double* height) override {
|
||||||
windowGLQ->GetContentSize(width, height);
|
double pixelRatio = GetDevicePixelRatio();
|
||||||
|
QSize rc = ssWindow->ssView->size();
|
||||||
|
*width = rc.width() / pixelRatio;
|
||||||
|
*height = rc.height() / pixelRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMinContentSize(double width, double height) override {
|
void SetMinContentSize(double width, double height) override {
|
||||||
int w = width;
|
ssWindow->resize(int(width), int(height));
|
||||||
int h = height;
|
|
||||||
windowGLQ->setGeometry(50,50,w, h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreezePosition(SettingsRef settings, const std::string& key) override {
|
void FreezePosition(SettingsRef settings, const std::string& key) override {
|
||||||
if (!(windowGLQ->isVisible())) return;
|
if (!(ssWindow->isVisible())) return;
|
||||||
|
|
||||||
int left, top, width, height;
|
int left, top, width, height;
|
||||||
#if 0
|
#if 0
|
||||||
QPoint topLeftPoint = windowGLQ->geometry().topLeft();
|
QPoint topLeftPoint = ssWindow->geometry().topLeft();
|
||||||
left = topLeftPoint.x();
|
left = topLeftPoint.x();
|
||||||
top = topLeftPoint.y();
|
top = topLeftPoint.y();
|
||||||
#endif
|
#endif
|
||||||
QPoint windowPos = windowGLQ->pos();
|
QPoint windowPos = ssWindow->pos();
|
||||||
left = windowPos.x();
|
left = windowPos.x();
|
||||||
top = windowPos.y();
|
top = windowPos.y();
|
||||||
width = windowGLQ->geometry().width();
|
width = ssWindow->geometry().width();
|
||||||
height = windowGLQ->geometry().height();
|
height = ssWindow->geometry().height();
|
||||||
bool isMaximized = windowGLQ->isMaximized();
|
bool isMaximized = ssWindow->isMaximized();
|
||||||
|
|
||||||
settings->FreezeInt(key + "_Left", left);
|
settings->FreezeInt(key + "_Left", left);
|
||||||
settings->FreezeInt(key + "_Top", top);
|
settings->FreezeInt(key + "_Top", top);
|
||||||
|
@ -781,13 +960,13 @@ public:
|
||||||
height = settings->ThawInt(key + "_Height", height);
|
height = settings->ThawInt(key + "_Height", height);
|
||||||
|
|
||||||
if(width != 0 && height != 0) {
|
if(width != 0 && height != 0) {
|
||||||
windowGLQ->move(left, top);
|
ssWindow->move(left, top);
|
||||||
windowGLQ->resize(width, height);
|
ssWindow->resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings->ThawBool(key + "_Maximized", false)) {
|
if (settings->ThawBool(key + "_Maximized", false)) {
|
||||||
// windowGLQ->SetFullScreen(true);
|
// ssWindow->SetFullScreen(true);
|
||||||
windowGLQ->setWindowState(Qt::WindowMaximized);
|
ssWindow->setWindowState(Qt::WindowMaximized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,65 +975,81 @@ public:
|
||||||
switch (cursor)
|
switch (cursor)
|
||||||
{
|
{
|
||||||
case Cursor::POINTER:
|
case Cursor::POINTER:
|
||||||
windowGLQ->setCursor(Qt::ArrowCursor);
|
ssWindow->setCursor(Qt::ArrowCursor);
|
||||||
break;
|
break;
|
||||||
case Cursor::HAND:
|
case Cursor::HAND:
|
||||||
windowGLQ->setCursor(Qt::PointingHandCursor);
|
ssWindow->setCursor(Qt::PointingHandCursor);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
windowGLQ->setCursor(Qt::ArrowCursor);
|
ssWindow->setCursor(Qt::ArrowCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetTooltip(const std::string& text, double x, double y,
|
void SetTooltip(const std::string& text, double x, double y,
|
||||||
double width, double height) override {
|
double width, double height) override {
|
||||||
windowGLQ->SetTooltip(text, x, y, width, height);
|
ssWindow->ssView->setToolTip(QString::fromStdString(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsEditorVisible() override {
|
bool IsEditorVisible() override {
|
||||||
return windowGLQ->IsEditorVisible();
|
return ssWindow->ssView->entry->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowEditor(double x, double y, double fontHeight, double minWidth,
|
void ShowEditor(double x, double y, double fontHeight, double minWidth,
|
||||||
bool isMonospace, const std::string& text) override {
|
bool isMonospace, const std::string& text) override {
|
||||||
windowGLQ->ShowEditor(x, y, fontHeight, minWidth, isMonospace, text);
|
// font size from Solvespace is very small and hard to see
|
||||||
|
// hard coded 20 for height and 100 for width
|
||||||
|
// using Arial font of size 16
|
||||||
|
// font decalred and set to the entry QLabel in the constructor
|
||||||
|
// Raed Marwan
|
||||||
|
ssWindow->ssView->startEditing(x, y, 20, 100, isMonospace, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HideEditor() override {
|
void HideEditor() override {
|
||||||
windowGLQ->HideEditor();
|
ssWindow->ssView->stopEditing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScrollbarVisible(bool visible) override {
|
void SetScrollbarVisible(bool visible) override {
|
||||||
//printf("Scroll vis %d\n", int(visible));
|
//printf("Scroll vis %d\n", int(visible));
|
||||||
windowGLQ->SetScrollbarVisible(visible);
|
QScrollBar* scrollBar = ssWindow->scrollBar;
|
||||||
|
if (scrollBar)
|
||||||
|
scrollBar->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureScrollbar(double min, double max, double pageSize) override {
|
void ConfigureScrollbar(double min, double max, double pageSize) override {
|
||||||
//printf("Scroll bar %f %f %f\n", min, max, pageSize);
|
//printf("Scroll bar %f %f %f\n", min, max, pageSize);
|
||||||
windowGLQ->ConfigureScrollbar(min, max, pageSize);
|
QScrollBar* scrollBar = ssWindow->scrollBar;
|
||||||
|
if (scrollBar) {
|
||||||
|
scrollBar->setRange(int(min), int(max - pageSize));
|
||||||
|
scrollBar->setPageStep(int(pageSize));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetScrollbarPosition() override {
|
double GetScrollbarPosition() override {
|
||||||
return windowGLQ->GetScrollbarPosition();
|
QScrollBar* scrollBar = ssWindow->scrollBar;
|
||||||
|
if (scrollBar)
|
||||||
|
return (double) scrollBar->value();
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScrollbarPosition(double pos) override {
|
void SetScrollbarPosition(double pos) override {
|
||||||
//printf("Scroll pos %f\n", pos);
|
//printf("Scroll pos %f\n", pos);
|
||||||
windowGLQ->SetScrollbarPosition(pos);
|
QScrollBar* scrollBar = ssWindow->scrollBar;
|
||||||
|
if (scrollBar)
|
||||||
|
scrollBar->setValue((int) pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Invalidate() override {
|
void Invalidate() override {
|
||||||
windowGLQ->Invalidate();
|
ssWindow->ssView->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QtGLMainWindow* getQtGLMainWindow() {
|
SSMainWindow* getQtGLMainWindow() {
|
||||||
return windowGLQ;
|
return ssWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void processTabKeyPressed() {
|
void processTabKeyPressed() {
|
||||||
|
|
||||||
if(windowGLQ->menuBar() != gMenuBarQt->menuBarQ && gMenuBarQt->showPropertyBrowserMenuItem != nullptr) {
|
if(ssWindow->menuBar() != gMenuBarQt->menuBarQ && gMenuBarQt->showPropertyBrowserMenuItem != nullptr) {
|
||||||
gMenuBarQt->showPropertyBrowserMenuItem->actionItemQ->setChecked(false);
|
gMenuBarQt->showPropertyBrowserMenuItem->actionItemQ->setChecked(false);
|
||||||
gMenuBarQt->showPropertyBrowserMenuItem->onTriggered(false);
|
gMenuBarQt->showPropertyBrowserMenuItem->onTriggered(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,25 +4,22 @@
|
||||||
|
|
||||||
#include <solvespace.h>
|
#include <solvespace.h>
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QOpenGLWidget>
|
#include <QOpenGLWidget>
|
||||||
#include <QScreen>
|
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QToolTip>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace SolveSpace::Platform;
|
namespace SolveSpace {
|
||||||
|
namespace Platform {
|
||||||
|
|
||||||
class GLWidget : public QOpenGLWidget
|
class SSView : public QOpenGLWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLWidget(QWidget* parent = 0)
|
SSView(QWidget* parent = 0)
|
||||||
: QOpenGLWidget(parent) {
|
: QOpenGLWidget(parent) {
|
||||||
|
|
||||||
entry = new QLineEdit(this);
|
entry = new QLineEdit(this);
|
||||||
|
@ -35,32 +32,14 @@ public:
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
~GLWidget()
|
~SSView()
|
||||||
{
|
{
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void startEditing(int x, int y, int fontHeight, int minWidth, bool isMonoSpace,
|
void startEditing(int x, int y, int fontHeight, int minWidth,
|
||||||
const std::string& val) {
|
bool isMonoSpace, const std::string& val);
|
||||||
|
void stopEditing();
|
||||||
entry->setGeometry(QRect(x, y, minWidth, fontHeight));
|
|
||||||
entry->setText(QString::fromStdString(val));
|
|
||||||
|
|
||||||
if (!entry->isVisible()) {
|
|
||||||
entry->show();
|
|
||||||
entry->setFocus();
|
|
||||||
entry->setCursorPosition(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopEditing() {
|
|
||||||
|
|
||||||
if (entry->isVisible()) {
|
|
||||||
entry->hide();
|
|
||||||
setFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QSize minimumSizeHint() const {
|
QSize minimumSizeHint() const {
|
||||||
return QSize(50, 50);
|
return QSize(50, 50);
|
||||||
|
@ -90,15 +69,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
//----Mouse Events--------
|
//----Mouse Events--------
|
||||||
void wheelEvent(QWheelEvent* event)
|
void wheelEvent(QWheelEvent* event);
|
||||||
{
|
|
||||||
const double wheelDelta=120.0;
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::NONE;
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::SCROLL_VERT;
|
|
||||||
slvMouseEvent.scrollDelta = (double)event->angleDelta().y() / wheelDelta;
|
|
||||||
|
|
||||||
emit mouseEventOccuredSignal(slvMouseEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override{
|
void mouseReleaseEvent(QMouseEvent* event) override{
|
||||||
updateSlvSpaceMouseEvent(event);
|
updateSlvSpaceMouseEvent(event);
|
||||||
|
@ -112,95 +83,11 @@ protected:
|
||||||
updateSlvSpaceMouseEvent(event);
|
updateSlvSpaceMouseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSlvSpaceMouseEvent(QMouseEvent* event)
|
void updateSlvSpaceMouseEvent(QMouseEvent* event);
|
||||||
{
|
|
||||||
slvMouseEvent.shiftDown = false;
|
|
||||||
slvMouseEvent.controlDown = false;
|
|
||||||
|
|
||||||
switch (event->type())
|
|
||||||
{
|
|
||||||
case QEvent::MouseMove:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::MOTION;
|
|
||||||
break;
|
|
||||||
case QEvent::MouseButtonPress:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::PRESS;
|
|
||||||
break;
|
|
||||||
case QEvent::MouseButtonDblClick:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::DBL_PRESS;
|
|
||||||
break;
|
|
||||||
case QEvent::MouseButtonRelease:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::RELEASE;
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::NONE;
|
|
||||||
break;
|
|
||||||
case QEvent::Wheel:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::SCROLL_VERT;
|
|
||||||
//slvMouseEvent.scrollDelta = event->
|
|
||||||
break;
|
|
||||||
case QEvent::Leave:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::LEAVE;
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::NONE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
slvMouseEvent.type = MouseEvent::Type::RELEASE;
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::MouseButtons buttonState = (slvMouseEvent.type == MouseEvent::Type::MOTION) ? event->buttons() : event->button();
|
|
||||||
|
|
||||||
switch (buttonState)
|
|
||||||
{
|
|
||||||
case Qt::MouseButton::LeftButton:
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::LEFT;
|
|
||||||
break;
|
|
||||||
case Qt::MouseButton::RightButton:
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::RIGHT;
|
|
||||||
break;
|
|
||||||
case Qt::MouseButton::MidButton:
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::MIDDLE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
slvMouseEvent.button = MouseEvent::Button::NONE;
|
|
||||||
//slvMouseEvent.button = slvMouseEvent.button;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
slvMouseEvent.x = event->pos().x();
|
|
||||||
slvMouseEvent.y = event->pos().y();
|
|
||||||
Qt::KeyboardModifiers keyModifier = QGuiApplication::keyboardModifiers();
|
|
||||||
|
|
||||||
switch (keyModifier)
|
|
||||||
{
|
|
||||||
case Qt::ShiftModifier:
|
|
||||||
slvMouseEvent.shiftDown = true;
|
|
||||||
break;
|
|
||||||
case Qt::ControlModifier:
|
|
||||||
slvMouseEvent.controlDown = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit mouseEventOccuredSignal(slvMouseEvent);
|
|
||||||
}
|
|
||||||
//----Keyboard Events--------
|
//----Keyboard Events--------
|
||||||
|
|
||||||
/*
|
bool event(QEvent* e);
|
||||||
* Need to override the event method to catch the tab key during a key press event
|
|
||||||
* Qt does not send a key press event when the tab key is presed. To get that
|
|
||||||
* we need to overwrite the event functon and check if the tab key was presed during a key press event
|
|
||||||
* otherwise we send the rest of the event back to the widget for further processes
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool event(QEvent* e)
|
|
||||||
{
|
|
||||||
if(e->type() == QEvent::KeyPress) {
|
|
||||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(e);
|
|
||||||
if(keyEvent->key() == Qt::Key_Tab) {
|
|
||||||
emit tabKeyPressed();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QWidget::event(e);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* keyEvent)
|
void keyPressEvent(QKeyEvent* keyEvent)
|
||||||
{
|
{
|
||||||
|
@ -216,38 +103,11 @@ protected:
|
||||||
QWidget::keyReleaseEvent(keyEvent);
|
QWidget::keyReleaseEvent(keyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSlvSpaceKeyEvent(QKeyEvent* event)
|
void updateSlvSpaceKeyEvent(QKeyEvent* event);
|
||||||
{
|
|
||||||
slvKeyEvent.key = KeyboardEvent::Key(-1);
|
|
||||||
slvKeyEvent.shiftDown = false;
|
|
||||||
slvKeyEvent.controlDown = false;
|
|
||||||
if (event->modifiers() == Qt::ShiftModifier)
|
|
||||||
slvKeyEvent.shiftDown = true;
|
|
||||||
if (event->modifiers() == Qt::ControlModifier)
|
|
||||||
slvKeyEvent.controlDown = true;
|
|
||||||
|
|
||||||
if (event->key() >= Qt::Key_F1 && event->key() <= Qt::Key_F35) {
|
|
||||||
slvKeyEvent.key = KeyboardEvent::Key::FUNCTION;
|
|
||||||
slvKeyEvent.num = event->key() - Qt::Key_F1 + 1;
|
|
||||||
}
|
|
||||||
if (event->key() >= Qt::Key_Space && event->key() <= Qt::Key_yen) {
|
|
||||||
slvKeyEvent.key = KeyboardEvent::Key::CHARACTER;
|
|
||||||
QString keyLower = event->text().toLower();
|
|
||||||
slvKeyEvent.chr = keyLower.toUcs4().at(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit keyEventOccuredSignal(slvKeyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTooltip(const std::string& text, double x, double y,
|
|
||||||
double width, double height) {
|
|
||||||
this->setToolTip(QString::fromStdString(text));
|
|
||||||
QPoint pos(x, y);
|
|
||||||
QToolTip::showText(pos, toolTip());
|
|
||||||
}
|
|
||||||
signals:
|
signals:
|
||||||
void mouseEventOccuredSignal(SolveSpace::Platform::MouseEvent mouseEvent);
|
void mouseEventOccuredSignal(MouseEvent mouseEvent);
|
||||||
void keyEventOccuredSignal(SolveSpace::Platform::KeyboardEvent keyEvent);
|
void keyEventOccuredSignal(KeyboardEvent keyEvent);
|
||||||
void renderOccuredSignal();
|
void renderOccuredSignal();
|
||||||
void editingDoneSignal(std::string);
|
void editingDoneSignal(std::string);
|
||||||
void tabKeyPressed();
|
void tabKeyPressed();
|
||||||
|
@ -255,184 +115,35 @@ signals:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
QLineEdit* entry;
|
QLineEdit* entry;
|
||||||
SolveSpace::Platform::MouseEvent slvMouseEvent;
|
MouseEvent slvMouseEvent;
|
||||||
SolveSpace::Platform::KeyboardEvent slvKeyEvent;
|
KeyboardEvent slvKeyEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class QtGLMainWindow : public QMainWindow
|
class SSMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QtGLMainWindow(Platform::Window* pwin, Platform::Window::Kind kind, QWidget* parent = 0)
|
SSMainWindow(Platform::Window* pwin, Platform::Window::Kind kind,
|
||||||
: QMainWindow(parent), receiver(pwin)
|
QWidget* parent = 0);
|
||||||
{
|
|
||||||
glWidget = new GLWidget;
|
|
||||||
if (kind == Platform::Window::Kind::TOOL) {
|
|
||||||
QWidget* group = new QWidget;
|
|
||||||
scrollBar = new QScrollBar(Qt::Vertical, group);
|
|
||||||
connect(scrollBar, SIGNAL(valueChanged(int)), SLOT(sliderSlot(int)));
|
|
||||||
|
|
||||||
QHBoxLayout* lo = new QHBoxLayout(group);
|
|
||||||
lo->setContentsMargins(0, 0, 0, 0);
|
|
||||||
lo->setSpacing(2);
|
|
||||||
lo->addWidget(glWidget);
|
|
||||||
lo->addWidget(scrollBar);
|
|
||||||
group->setLayout(lo);
|
|
||||||
|
|
||||||
setCentralWidget(group);
|
|
||||||
//setWindowFlags(Qt::Tool);
|
|
||||||
} else {
|
|
||||||
scrollBar = nullptr;
|
|
||||||
setCentralWidget(glWidget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~QtGLMainWindow() {}
|
|
||||||
|
|
||||||
void SetScrollbarVisible(bool visible) {
|
|
||||||
if (scrollBar)
|
|
||||||
scrollBar->setVisible(visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureScrollbar(double min, double max, double pageSize) {
|
|
||||||
if (scrollBar) {
|
|
||||||
scrollBar->setRange(int(min), int(max - pageSize));
|
|
||||||
scrollBar->setPageStep(int(pageSize));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double GetScrollbarPosition() {
|
|
||||||
if (scrollBar)
|
|
||||||
return (double) scrollBar->value();
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetScrollbarPosition(double pos) {
|
|
||||||
if (scrollBar)
|
|
||||||
scrollBar->setValue((int) pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Invalidate() {
|
|
||||||
glWidget->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartEditing(int x, int y, int fontHeight, int minWidth, bool isMonoSpace,
|
|
||||||
const std::string& val) {
|
|
||||||
glWidget->startEditing(x, y, fontHeight, minWidth, isMonoSpace, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopEditing(){
|
|
||||||
glWidget->stopEditing();
|
|
||||||
}
|
|
||||||
|
|
||||||
GLWidget* GetGlWidget() {
|
|
||||||
return glWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns physical display DPI.
|
|
||||||
double GetPixelDensity() {
|
|
||||||
return QGuiApplication::primaryScreen()->logicalDotsPerInch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns raster graphics and coordinate scale (already applied on the platform side),
|
|
||||||
// i.e. size of logical pixel in physical pixels, or device pixel ratio.
|
|
||||||
double GetDevicePixelRatio() {
|
|
||||||
return glWidget->devicePixelRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns (fractional) font scale, to be applied on top of (integral) device pixel ratio.
|
|
||||||
double GetDeviceFontScale() {
|
|
||||||
return GetPixelDensity() / GetDevicePixelRatio() / 96.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsVisible() {
|
|
||||||
return this->isVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetVisible(bool visible) {
|
|
||||||
this->setVisible(visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Focus() {
|
|
||||||
this->setFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsFullScreen() {
|
|
||||||
return this->isFullScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetFullScreen(bool fullScreen) {
|
|
||||||
if (true == fullScreen)
|
|
||||||
setWindowState(Qt::WindowFullScreen);
|
|
||||||
else
|
|
||||||
setWindowState(Qt::WindowNoState); //The window has no state set (in normal state).
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTitle(const std::string& title) {
|
|
||||||
setWindowTitle(QString::fromStdString(title));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetContentSize(double* width, double* height) {
|
|
||||||
double pixelRatio = GetDevicePixelRatio();
|
|
||||||
QRect rc = glWidget->geometry();
|
|
||||||
*width = rc.width() / pixelRatio;
|
|
||||||
*height = rc.height() / pixelRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMinContentSize(double width, double height) {
|
|
||||||
resize((int)width, (int)height);
|
|
||||||
glWidget->resize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTooltip(const std::string& text, double x, double y,
|
|
||||||
double width, double height) {
|
|
||||||
glWidget->setToolTip(QString::fromStdString(text));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEditorVisible() {
|
|
||||||
return glWidget->entry->isVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowEditor(double x, double y, double fontHeight, double minWidth,
|
|
||||||
bool isMonospace, const std::string& text) {
|
|
||||||
|
|
||||||
// font size from Solvespace is very small and hard to see
|
|
||||||
// hard coded 20 for height and 100 for width
|
|
||||||
// using Arial font of size 16
|
|
||||||
// font decalred and set to the entry QLabel in the constructor
|
|
||||||
// Raed Marwan
|
|
||||||
glWidget->startEditing(x, y, 20, 100, isMonospace, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HideEditor() {
|
|
||||||
glWidget->stopEditing();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
void sliderSlot(int value);
|
||||||
void sliderSlot(int value) {
|
|
||||||
if (receiver->onScrollbarAdjusted)
|
|
||||||
receiver->onScrollbarAdjusted(double(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void closeEvent(QCloseEvent* ev);
|
||||||
void closeEvent(QCloseEvent* ev)
|
|
||||||
{
|
|
||||||
emit windowClosedSignal();
|
|
||||||
ev->ignore();
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void windowClosedSignal();
|
void windowClosedSignal();
|
||||||
|
|
||||||
private:
|
public:
|
||||||
Platform::Window* receiver;
|
Platform::Window* receiver;
|
||||||
GLWidget* glWidget;
|
SSView* ssView;
|
||||||
QScrollBar* scrollBar;
|
QScrollBar* scrollBar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue