diff --git a/src/main.cpp b/src/main.cpp index fd8417fb..33b6291b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -59,15 +59,10 @@ int main(int argc, char* argv[]) { MainFrame mainWindow; splash.showMessage(("正在创建主窗口..."), Qt::AlignHCenter | Qt::AlignBottom, Qt:: white); - // 先显示窗口,再在事件循环启动后最大化,避免首次显示时原生窗口放置未就绪导致尺寸异常 - mainWindow.showMaximized(); - // QTimer::singleShot(0, &mainWindow, &MainFrame::showMaximized); + mainWindow.show(); + QTimer::singleShot(20, &mainWindow, &MainFrame::showMaximized); splash.finish(&mainWindow); - int ret = app.exec(); - // app.Uninit(); - Sleep(200); return ret; - } diff --git a/src/ui/FramelessDelegateWin.cpp b/src/ui/FramelessDelegateWin.cpp index e52b93d1..e994ca7d 100644 --- a/src/ui/FramelessDelegateWin.cpp +++ b/src/ui/FramelessDelegateWin.cpp @@ -172,6 +172,16 @@ bool FramelessDelegateWin::nativeEvent(const QByteArray & eventType, void* messa mmi->ptMaxTrackSize.x = (rcMon.right - rcMon.left) + frameX * 2; mmi->ptMaxTrackSize.y = (rcMon.bottom - rcMon.top) + frameY * 2; + + const QSize minSize = mainWidget_->minimumSize(); + const double dpr = mainWidget_->devicePixelRatioF(); + const int minWpx = static_cast(std::round(minSize.width() * dpr)); + const int minHpx = static_cast(std::round(minSize.height() * dpr)); + // Guard against zero/negative values + const int clampedMinW = std::max(1, minWpx) + frameX * 2; + const int clampedMinH = std::max(1, minHpx) + frameY * 2; + mmi->ptMinTrackSize.x = clampedMinW; + mmi->ptMinTrackSize.y = clampedMinH; } if (::IsZoomed(msg->hwnd)) { diff --git a/src/ui/FramelessWindow.cpp b/src/ui/FramelessWindow.cpp index a941e097..af5dbdb4 100644 --- a/src/ui/FramelessWindow.cpp +++ b/src/ui/FramelessWindow.cpp @@ -11,10 +11,10 @@ FramelessWindow::FramelessWindow(QWidget* parent) | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMaximizeButtonHint - | Qt::WindowMinimizeButtonHint); + | Qt::WindowMinimizeButtonHint + ); delegate_ = FramelessDelegate::Create(this); - } FramelessWindow::~FramelessWindow() { @@ -23,7 +23,6 @@ FramelessWindow::~FramelessWindow() { void FramelessWindow::SetTitleBar(FrameTitleBar* titleBar) { titleBar->SetMainWidget(this); if (delegate_) { - // 通知委托当前标题栏,以便把它作为可拖动区域处理。 delegate_->SetTitleBar(titleBar); } } @@ -33,7 +32,6 @@ bool FramelessWindow::nativeEvent(const QByteArray& eventType, void* message, qi #else bool FramelessWindow::nativeEvent(const QByteArray & eventType, void* message, long* result) { #endif - // 先让无边框委托处理原生事件(如 WM_NCHITTEST 以支持边缘拖动缩放)。 if (delegate_ && delegate_->nativeEvent(eventType, message, result)) { return true; } diff --git a/src/ui/MainFrame.cpp b/src/ui/MainFrame.cpp index e2dc092a..bc0ae579 100644 --- a/src/ui/MainFrame.cpp +++ b/src/ui/MainFrame.cpp @@ -36,6 +36,8 @@ MainFrame::MainFrame(QWidget *parent) : ui(new Ui::MainFrame) { ui->setupUi(this); + + setMinimumSize(800, 600); assert(nullptr == s_instance); s_instance = this; @@ -102,13 +104,6 @@ void MainFrame::InitUI() { FileManagerMenu* fileMenu = new FileManagerMenu(this); AddMenuWidget("file_manager", tr("file manager"), fileMenu); - //AddMenuWidget("view_manager", tr("view manager"), new ViewManagerMenu(this)); - //AddMenuWidget("plan_manager", tr("plan manager"), new PlanManagerMenu(this)); - //AddMenuWidget("dynamic_display", tr("dynamic display"), new DynamicDisplayMenu(this)); - // ChartPlotMenu* chartMenu = new ChartPlotMenu(this); - // AddMenuWidget("simu_manager", tr("simu manager"), chartMenu); - - // Command buttons menu based on parsed commands SimuRunMenu* simuRunMenu = new SimuRunMenu(this); AddMenuWidget("simu_manager", tr("simu manager"), simuRunMenu); @@ -123,11 +118,6 @@ void MainFrame::InitUI() { simuRunMenu->SetMainWindow(mainWindow); - /*OsgWidget* viewWidget = mainWindow->GetViewWidget(); - connect(fileMenu, &FileManagerMenu::LoadDyt, viewWidget, &OsgWidget::OnLoadDyt);*/ - - //connect(system_, &SystemManagerMenu::signalShowUISetting, mainWindow, &MainWindow::slotShowUISetting); - if (ui->menuWidget->count() > 0) { ui->menuWidget->setCurrentIndex(0); menuWidget_.isEmpty() ? assert(false) : menuWidget_.key(0)->setChecked(true); diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index d4ec800a..9c570e4f 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -38,11 +38,12 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); + setMinimumSize(800, 600); LOG_INFO("MainWindow::MainWindow - Constructor called, about to call InitUI"); InitUI(); LOG_INFO("MainWindow::MainWindow - Constructor completed"); -} +} MainWindow::~MainWindow() { UninitUI(); @@ -70,7 +71,6 @@ void MainWindow::InitUI() { mapDockWidget_.insert("ModelBrowser", model); addDockWidget(Qt::LeftDockWidgetArea, model); - // 创建预制模型面板 DockWidget* presetModel = new DockWidget(tr("preset models"), 0); presetModel->SetDockWidgetTitleBar(new DockTitleBar(presetModel)); presetModel->setObjectName("Dock.PresetModelPanel"); @@ -82,11 +82,8 @@ void MainWindow::InitUI() { DockWidget* attribte = new DockWidget(tr("attribte"), 0); attribte->SetDockWidgetTitleBar(new DockTitleBar(attribte)); attribte->setObjectName("Dock.PropertyBrowser"); - //addDockWidget(pSettingUI->GetArea("PropertyBrowser"), attribte); propertyBrowser_ = new PropertyBrowser(0); propertyBrowser_->AttachDock(attribte); - // Ensure property panel has a reasonable minimum width; no maximum limit - attribte->setMinimumWidth(240); mapDockWidget_.insert("PropertyBrowser", attribte); addDockWidget(Qt::RightDockWidgetArea, attribte); @@ -106,23 +103,18 @@ void MainWindow::InitUI() { connect(modelBrowser_, &ModelBrowser::FileEntryChange, propertyBrowser_, &PropertyBrowser::OnFileEntryChange); connect(modelBrowser_, &ModelBrowser::GroupChange, propertyBrowser_, &PropertyBrowser::OnGroupChange); - qtOsgViewWidget_ = new OsgWidget; + qtOsgViewWidget_ = new OsgWidget(0); qtOsgViewWidget_->Initialize(); - DockWidget* viewDock = new DockWidget(tr("Main View"), 0); - viewDock->SetDockWidgetTitleBar(new DockTitleBar(viewDock)); - viewDock->setObjectName("Dock.MainView"); - viewDock->setWidget(qtOsgViewWidget_); - // Ensure main view has a reasonable minimum size to avoid being squeezed - // Use smaller minimum size to support smaller displays - qtOsgViewWidget_->setMinimumSize(640, 480); - viewDock->setMinimumSize(640, 480); - addDockWidget(Qt::LeftDockWidgetArea, viewDock); - mapDockWidget_.insert("MainView", viewDock); + DockWidget* mainView = new DockWidget(tr("Main View"), 0); + mainView->SetDockWidgetTitleBar(new DockTitleBar(mainView)); + mainView->setObjectName("Dock.MainView"); + qtOsgViewWidget_->AttachDock(mainView); + mapDockWidget_.insert("MainView", mainView); + addDockWidget(Qt::RightDockWidgetArea, mainView); - splitDockWidget(model, viewDock, Qt::Horizontal); + splitDockWidget(model, mainView, Qt::Horizontal); - // 将预制模型面板与模型浏览器标签化 tabifyDockWidget(model, presetModel); dataPanelManager_ = new DataPanelManager(this, this); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index c8cbd9db..583db78a 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -48,6 +48,7 @@ private: class PropertyBrowser* propertyBrowser_{ nullptr }; class QWebEngineView* webEngineView_{ nullptr }; class OsgWidget* qtOsgViewWidget_{ nullptr }; + //QWidget* qtOsgViewWidget_{ nullptr }; class SignalIndicatorLampUI* signalIndicatorLampUI_{ nullptr }; class CodeEdtUI* matlabFileDlg_{ nullptr }; diff --git a/src/ui/ModelBrowser.cpp b/src/ui/ModelBrowser.cpp index 3ed28ba8..56bd748c 100644 --- a/src/ui/ModelBrowser.cpp +++ b/src/ui/ModelBrowser.cpp @@ -3,8 +3,8 @@ #include #include -#include "DockTitleBar.h" -#include "DockWidget.h" +#include "ui/DockTitleBar.h" +#include "ui/DockWidget.h" #include "ModelBrowser/ModelTreeWidget.h" #include "workspace/WorkSpaceManager.h" diff --git a/src/viewer/OsgWidget.cpp b/src/viewer/OsgWidget.cpp index 76c4f7ca..45983ea3 100644 --- a/src/viewer/OsgWidget.cpp +++ b/src/viewer/OsgWidget.cpp @@ -21,7 +21,6 @@ #include "OsgViewer.h" #include "common/SpdLogger.h" #include "scene/OEScene.h" -#include "ui/MainFrame.h" #include "workspace/WorkSpaceManager.h" #include "workspace/WorkSpace.h" #include "scutcheon/osgScutcheon.h" @@ -33,6 +32,10 @@ #include "entities/Entity.h" #include "entities/Component.h" +#include "ui/DockTitleBar.h" +#include "ui/DockWidget.h" +#include "ui/MainFrame.h" + static void ConfigureView( osgViewer::View* view ) { view->addEventHandler(new osgViewer::StatsHandler()); view->addEventHandler(new osgViewer::WindowSizeHandler()); @@ -55,14 +58,13 @@ OsgWidget::OsgWidget(QWidget* parent, Qt::WindowFlags f) setThreadingModel(osgViewer::ViewerBase::SingleThreaded); setMouseTracking(true); setKeyEventSetsDone(0); - - // 启用拖拽接收 + setAcceptDrops(true); connect( &timer_, SIGNAL(timeout()), this, SLOT(update()) ); timer_.start( 10 ); - setMinimumSize(100, 100); + //setMinimumSize(800, 100); LOG_INFO("OsgWidget::OsgWidget"); } @@ -131,6 +133,19 @@ void OsgWidget::LoadDefaultScene() { } } +void OsgWidget::AttachDock(DockWidget* dockWidget) { + if (nullptr == dockWidget) { + qDebug() << __FUNCTION__ << "dockwidget is nullptr"; + return; + } + + dockWidget->SetDockWidgetTitleBar(nullptr); + dockWidget->setWidget(this); + + DockTitleBar* dockTitleBar = new DockTitleBar; + dockWidget->SetDockWidgetTitleBar(dockTitleBar); +} + osgQt::GraphicsWindowQt* OsgWidget::createGraphicsWindow(int x, int y, int w, int h, const std::string& name, bool windowDecoration) { osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); @@ -199,7 +214,6 @@ void OsgWidget::dragEnterEvent(QDragEnterEvent* event) { } void OsgWidget::dragMoveEvent(QDragMoveEvent* event) { - // 检查是否是预制模型拖拽 if (event->mimeData()->hasFormat("application/x-preset-model")) { event->acceptProposedAction(); } else { @@ -249,11 +263,9 @@ void OsgWidget::OnPresetModelDropped(const QString& modelType, const QString& mo } osg::Viewport* vp = view_->getCamera()->getViewport(); - // 将屏幕坐标转换为世界坐标 double longitude, latitude, height; if (!ScreenToWorldCoordinate(static_cast(position.x()), static_cast(vp->height() - position.y()), longitude, latitude, height)) { LOG_WARN("OsgWidget::OnPresetModelDropped - Failed to convert screen coordinates to world coordinates"); - // 使用默认位置 longitude = 0.0; latitude = 0.0; height = 0.0; diff --git a/src/viewer/OsgWidget.h b/src/viewer/OsgWidget.h index a11cf9a8..d906da2e 100644 --- a/src/viewer/OsgWidget.h +++ b/src/viewer/OsgWidget.h @@ -11,12 +11,14 @@ class OsgWidget : public QWidget, public osgViewer::CompositeViewer { public: OsgWidget(QWidget *parent = nullptr, Qt::WindowFlags f = nullptr); ~OsgWidget() override; - QPaintEngine* paintEngine() const override { return nullptr; } + QPaintEngine* paintEngine() const override { return nullptr; } void Initialize(void); void Uninitialize(void); void LoadDefaultScene(void); + void AttachDock(class DockWidget* dockWidget); + signals: void signalScaleInfo(const QString&); @@ -28,18 +30,11 @@ protected: void resizeEvent(QResizeEvent* event) override; void paintEvent( QPaintEvent* /*event*/ ) override; - // 拖拽事件处理 void dragEnterEvent(QDragEnterEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override; void dropEvent(QDropEvent* event) override; public slots: - /** - * @brief 处理预制模型拖拽 - * @param modelType 模型类型 - * @param modelName 模型名称 - * @param position 屏幕位置(可选) - */ void OnPresetModelDropped(const QString& modelType, const QString& modelName, const QPointF& position = QPointF()); bool ScreenToWorldCoordinate(int x, int y, double& longitude, double& latitude, double& altitude);