mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
* DocDockWidget.cpp
|
||||
* Copyright (c) 2013 ROBLOX Corp. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DocDockWidget.h"
|
||||
|
||||
// Qt Headers
|
||||
#include <QSettings>
|
||||
#include <QMouseEvent>
|
||||
|
||||
// Roblox Studio Headers
|
||||
#include "RobloxMainWindow.h"
|
||||
#include "DocDockManager.h"
|
||||
#include "RobloxDocManager.h"
|
||||
|
||||
#include "StudioUtilities.h"
|
||||
|
||||
static const char* DocDockWidgetSetting = "DocDockWidget/";
|
||||
|
||||
DocDockWidget::DocDockWidget(
|
||||
RobloxMainWindow& mainWindow,
|
||||
DocDockManager& docManager,
|
||||
IRobloxDoc& doc )
|
||||
: QDockWidget(&mainWindow),
|
||||
m_MainWindow(mainWindow),
|
||||
m_DocManager(docManager),
|
||||
m_Doc(doc),
|
||||
m_DocType(doc.docType()),
|
||||
m_IsMoving(false),
|
||||
m_Viewer(doc.getViewer()),
|
||||
m_IsSimulatingDrag(false)
|
||||
{
|
||||
RBXASSERT(m_Viewer);
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWidget(m_Viewer);
|
||||
setFloating(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setTitle(m_Doc.displayName(),m_Doc.fileName());
|
||||
setMinimumSize(m_Viewer->minimumSize());
|
||||
setMaximumSize(m_Viewer->maximumSize());
|
||||
setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
|
||||
|
||||
connect(this,SIGNAL(topLevelChanged(bool)),this,SLOT(onTopLevelChanged(bool)));
|
||||
connect(this,SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),this,SLOT(onDockLocationChanged(Qt::DockWidgetArea)));
|
||||
|
||||
// restore geometry for this type of doc
|
||||
const QSettings settings;
|
||||
const QString settingName = DocDockWidgetSetting + QString::number(m_DocType) + "/geometry";
|
||||
restoreGeometry(settings.value(settingName).toByteArray());
|
||||
|
||||
connect(qApp,SIGNAL(focusChanged(QWidget*,QWidget*)),this,SLOT(onFocusChanged(QWidget*,QWidget*)));
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves geometry for the next time this type of doc is opened.
|
||||
* Must call cleanup() before destruction.
|
||||
*/
|
||||
DocDockWidget::~DocDockWidget()
|
||||
{
|
||||
RBXASSERT(!widget());
|
||||
|
||||
QSettings settings;
|
||||
const QString settingName = DocDockWidgetSetting + QString::number(m_DocType) + "/geometry";
|
||||
settings.setValue(settingName,saveGeometry());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up the widget and makes sure it won't be deleted.
|
||||
* Must be called before the destructor. We need to do an immediate clean up, we can't
|
||||
* wait for the destructor to be called since we use deleteLater.
|
||||
*/
|
||||
void DocDockWidget::cleanup()
|
||||
{
|
||||
if ( !widget() )
|
||||
return;
|
||||
|
||||
stopDragging();
|
||||
|
||||
setFloating(false);
|
||||
|
||||
// make sure we're not the ones deleting the viewer
|
||||
setWidget(NULL);
|
||||
QCoreApplication::removePostedEvents(m_Viewer);
|
||||
m_Viewer->setParent(NULL);
|
||||
m_Viewer->hide();
|
||||
m_MainWindow.removeDockWidget(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates a window dragging operation.
|
||||
*/
|
||||
void DocDockWidget::startDragging()
|
||||
{
|
||||
if ( !m_IsSimulatingDrag )
|
||||
{
|
||||
m_IsSimulatingDrag = true;
|
||||
m_StartPos = QCursor::pos();
|
||||
grabMouse();
|
||||
simulateDrag();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a simulated window drag.
|
||||
* This forces the window to be moved as the cursor is moved until the left button is released.
|
||||
*/
|
||||
void DocDockWidget::simulateDrag()
|
||||
{
|
||||
if ( m_IsSimulatingDrag )
|
||||
{
|
||||
const QPoint& worldPos = QCursor::pos();
|
||||
const QPoint offset(
|
||||
width() / 2,
|
||||
style()->pixelMetric(QStyle::PM_TitleBarHeight) / 2 );
|
||||
move(worldPos - offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the dock widget title when the doc names change.
|
||||
* Updates the object name to the new title.
|
||||
*/
|
||||
void DocDockWidget::setTitle(const QString& displayName,const QString& fileName)
|
||||
{
|
||||
QString title = displayName;
|
||||
if ( !fileName.isEmpty() )
|
||||
title += " - " + fileName;
|
||||
setWindowTitle(title);
|
||||
setObjectName(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for user clicking on the attach button.
|
||||
* Attaches doc to the tab widget.
|
||||
*/
|
||||
void DocDockWidget::onAttachDoc()
|
||||
{
|
||||
RobloxDocManager::Instance().attachDoc(m_Doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests doc close so that it will be saved properly.
|
||||
*/
|
||||
void DocDockWidget::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
RBXASSERT(widget());
|
||||
|
||||
if ( m_MainWindow.requestDocClose(m_Doc) )
|
||||
QDockWidget::closeEvent(event);
|
||||
else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback when the window is being moved.
|
||||
* This causes dragging to begin and the tab hover over location to be detected.
|
||||
*/
|
||||
void DocDockWidget::moveEvent(QMoveEvent* event)
|
||||
{
|
||||
QDockWidget::moveEvent(event);
|
||||
|
||||
// ignore move event if we're not floating
|
||||
if ( !isFloating() )
|
||||
return;
|
||||
|
||||
if ( !m_IsMoving )
|
||||
{
|
||||
m_IsMoving = true;
|
||||
m_StartPos = QCursor::pos() + event->oldPos() - event->pos();
|
||||
setMouseTracking(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only hover over if we attempted to move the window a minimum distance
|
||||
const QPoint moveDelta = QCursor::pos() - m_StartPos;
|
||||
if ( moveDelta.manhattanLength() > QApplication::startDragDistance() )
|
||||
RobloxDocManager::Instance().setDockHoverOverPos(QCursor::pos());
|
||||
}
|
||||
|
||||
m_MainWindow.updateEmbeddedFindPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback when the window is being resized.
|
||||
* This causes dragging to abort.
|
||||
*/
|
||||
void DocDockWidget::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QDockWidget::resizeEvent(event);
|
||||
m_StartPos = QCursor::pos(); // ignore any dragging that might have happened
|
||||
stopDragging();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for the mouse moving during a drag.
|
||||
* If we're simulating a drag, move the window.
|
||||
*/
|
||||
void DocDockWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
QDockWidget::mouseMoveEvent(event);
|
||||
|
||||
if ( m_IsSimulatingDrag )
|
||||
simulateDrag();
|
||||
else if ( event->button() != Qt::LeftButton )
|
||||
stopDragging();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the window drag operation.
|
||||
* Attempts to attach the dock to the tab widget if over the tab widget.
|
||||
*
|
||||
* @return true if the doc was attached
|
||||
*/
|
||||
bool DocDockWidget::stopDragging()
|
||||
{
|
||||
bool attached = false;
|
||||
|
||||
if ( m_IsMoving || m_IsSimulatingDrag )
|
||||
{
|
||||
if ( m_IsSimulatingDrag )
|
||||
{
|
||||
releaseMouse();
|
||||
m_IsSimulatingDrag = false;
|
||||
}
|
||||
|
||||
setMouseTracking(false);
|
||||
m_IsMoving = false;
|
||||
|
||||
// only attach if we attempted to move the window and didn't just click on it
|
||||
const QPoint moveDelta = QCursor::pos() - m_StartPos;
|
||||
QPoint clickPos;
|
||||
if ( moveDelta.manhattanLength() > QApplication::startDragDistance() )
|
||||
clickPos = QCursor::pos();
|
||||
else
|
||||
clickPos = QPoint(INT_MAX,INT_MAX); // don't want to attach it
|
||||
|
||||
attached = RobloxDocManager::Instance().attemptAttach(m_Doc,clickPos);
|
||||
if ( !attached )
|
||||
RobloxDocManager::Instance().setCurrentDoc(&m_Doc);
|
||||
}
|
||||
|
||||
return attached;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles non-client mouse press events to begin window dragging and setting the
|
||||
* current doc if the window is activated.
|
||||
*/
|
||||
bool DocDockWidget::event(QEvent* event)
|
||||
{
|
||||
bool result = QDockWidget::event(event);
|
||||
|
||||
if ( event->type() == QEvent::NonClientAreaMouseButtonRelease ||
|
||||
event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
// Must catch mouse events here because dock widget doesn't give em to us in mouesReleaseEvent.
|
||||
// On Mac, this is the only way to detect an end window drag event.
|
||||
RBX::BaldPtr<QMouseEvent> mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if ( mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
stopDragging();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else if ( event->type() == QEvent::NonClientAreaMouseButtonPress ||
|
||||
event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
// Reset start pos in case this is just a click.
|
||||
RBX::BaldPtr<QMouseEvent> mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if ( mouseEvent->button() == Qt::LeftButton )
|
||||
m_StartPos = QCursor::pos();
|
||||
}
|
||||
else if ( event->type() == QEvent::WindowActivate && widget() )
|
||||
{
|
||||
RobloxDocManager::Instance().setCurrentDoc(&m_Doc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect changes in widget focus.
|
||||
* Only if our new focus is an ancestor of the dockwidget do we need to set the current doc.
|
||||
*/
|
||||
void DocDockWidget::onFocusChanged(QWidget* oldWidget,QWidget* newWidget)
|
||||
{
|
||||
if ( isAncestorOf(newWidget) && widget() )
|
||||
RobloxDocManager::Instance().setCurrentDoc(&m_Doc);
|
||||
}
|
||||
|
||||
#ifdef Q_WS_WIN32
|
||||
/**
|
||||
* Windows event callback to handle the end of the window drag operation.
|
||||
* This is the only way to detect when the mouse button has been released during a
|
||||
* drag on Windows.
|
||||
*/
|
||||
bool DocDockWidget::winEvent(MSG* msg,long* result)
|
||||
{
|
||||
if ( msg->message == WM_EXITSIZEMOVE )
|
||||
stopDragging();
|
||||
|
||||
return QDockWidget::winEvent(msg,result);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Callback when the dock is either docked or undocked (plugged or unplugged).
|
||||
* Begin dragging when undocked.
|
||||
* Stop dragging if it's been docked. This is just overkill.
|
||||
*/
|
||||
void DocDockWidget::onTopLevelChanged(bool TopLevel)
|
||||
{
|
||||
if ( TopLevel )
|
||||
startDragging();
|
||||
else
|
||||
stopDragging();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback when the dock widget docks somewhere else.
|
||||
* Stop dragging when it's been docked. This is just overkill.
|
||||
*/
|
||||
void DocDockWidget::onDockLocationChanged(Qt::DockWidgetArea area)
|
||||
{
|
||||
stopDragging();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user