summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/Controls/Control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Studio/Controls/Control.cpp')
-rw-r--r--src/Authoring/Studio/Controls/Control.cpp1738
1 files changed, 0 insertions, 1738 deletions
diff --git a/src/Authoring/Studio/Controls/Control.cpp b/src/Authoring/Studio/Controls/Control.cpp
deleted file mode 100644
index 03f01403..00000000
--- a/src/Authoring/Studio/Controls/Control.cpp
+++ /dev/null
@@ -1,1738 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2002 NVIDIA Corporation.
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt 3D Studio.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "Qt3DSCommonPrecompile.h"
-
-#include "Control.h"
-#include "Renderer.h"
-#include "MasterP.h"
-#include "StudioUtils.h"
-#include "HotKeys.h"
-#include "ControlGraph.h"
-#include "ControlData.h"
-#include "ResourceCache.h"
-#include "MouseCursor.h"
-
-#include <QtWidgets/qapplication.h>
-
-using namespace Q3DStudio::Control;
-
-IMPLEMENT_OBJECT_COUNTER(CControl)
-
-//=============================================================================
-/**
- * Constructor, creates a control with all default values.
- */
-CControl::CControl()
- : m_cursorSet(-1)
-{
- m_ControlData = CControlData::CreateControlData(*this);
- ADDTO_OBJECT_COUNTER(CControl)
-}
-
-//=============================================================================
-/**
- * Destructor
- */
-CControl::~CControl()
-{
- REMOVEFROM_OBJECT_COUNTER(CControl)
- m_ControlData->ReleaseControl();
-}
-
-//=============================================================================
-/**
- * Draw this control and all children below it.
- * This can be overriden by controls to draw themselves but should still be
- * called if sub controls are to be drawn.
- * This will call Draw if this control is actually supposed to be drawn. It will
- * be drawn if it is invalidated or if anything above it in it's heirarchy has
- * been invalidated.
- * @param inRenderer the renderer to draw this control out to.
- */
-void CControl::OnDraw(CRenderer *inRenderer, CRct &inDirtyRect,
- bool inIgnoreValidation /* = false */)
-{
- EnsureLayout();
- bool isInvalidated = IsInvalidated();
-
- // inRenderer->PushClippingRect( GetSize( ) );
-
- CRct theBoundingBox = inRenderer->GetClippingRect();
-
- if (isInvalidated) {
- CRct theRect(GetSize());
- theRect.And(theBoundingBox);
- theRect.Offset(inRenderer->GetTranslation());
- inDirtyRect.Or(theRect);
- }
-
- if (isInvalidated || inIgnoreValidation)
- Draw(inRenderer);
-
- // Notify the children in the reverse order that they are drawn.
- ControlGraph::SReverseIterator theRPos = ControlGraph::GetRChildren(*this);
- for (; !theRPos.IsDone(); ++theRPos) {
- (*theRPos)->EnsureLayout();
- (*theRPos)->BeginDrawChildren(inRenderer);
- }
-
- // Go through all the children and draw them in the correct order. By keeping
- // this order there is a semblance of depth.
- ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this);
- for (; !thePos.IsDone(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->IsVisible()) {
- CPt thePosition = theChild->GetPosition();
- inRenderer->PushTranslation(thePosition);
-
- // Clipping of non-visible objects.
- if (theChild->IsInRect(theBoundingBox))
- theChild->OnDraw(inRenderer, inDirtyRect, inIgnoreValidation || isInvalidated);
- else
- theChild->NotifyNotInClipRect();
- inRenderer->PopTranslation();
- }
- }
-
- // inRenderer->PopClippingRect( );
-
- // Set this as not being invalidated.
- Invalidate(false);
-}
-
-//=============================================================================
-/**
- * Performs the drawing for this control.
- * Does nothing by default.
- * @param inRenderer the renderer to draw to.
- */
-void CControl::Draw(CRenderer *inRenderer)
-{
- Q_UNUSED(inRenderer);
-}
-
-//=============================================================================
-/**
- * Notification that this control is not in the clipping rect and hence will
- * not be drawn.
- * By default, tell inform its children
- */
-void CControl::NotifyNotInClipRect()
-{
- ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this);
- for (; !thePos.IsDone(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- theChild->NotifyNotInClipRect();
- }
-}
-
-//=============================================================================
-/**
- * Get the position of this control.
- * The position of this control is relative to it's parent's 0,0 coordinate.
- * @return the position relative to it's parent's position.
- */
-CPt CControl::GetPosition() const
-{
- return m_ControlData->m_Position;
-}
-
-//=============================================================================
-/**
- * Set the position of this control.
- * The position of this control is relative to it's parent's 0,0 coordinate.
- * @return the position relative to it's parent's position.
- */
-void CControl::SetPosition(CPt inPosition)
-{
- if (inPosition != m_ControlData->m_Position) {
- MarkChildrenNeedLayout();
- m_ControlData->m_Position = inPosition;
- Invalidate();
- }
-}
-
-//=============================================================================
-/**
- * Overload of SetPosition to allow it to take 2 parameters.
- * This will call SetPosition( CPt ) so there is no need to extend this
- * method.
- * @param inX the X position to set.
- * @param inY the Y position to set.
- */
-void CControl::SetPosition(long inX, long inY)
-{
- SetPosition(CPt(inX, inY));
-}
-
-//=============================================================================
-/**
- * Get the size of the control.
- * The size is the width and height of the control from it's position.
- * @return the size of this control.
- */
-CPt CControl::GetSize() const
-{
- return m_ControlData->m_Size;
-}
-
-//=============================================================================
-/**
- * Set the size of this control.
- * The size is the width and height of the control from it's position.
- * @param inSize the new size of the control.
- */
-void CControl::SetSize(CPt inSize)
-{
- if (GetSize() != inSize) {
- m_ControlData->m_Size = inSize;
- if (GetParent() != nullptr)
- GetParent()->OnChildSizeChanged(this); // this callback needs to die
- OnSizeChanged(inSize);
- }
-}
-
-void CControl::OnSizeChanged(CPt /*inSize*/)
-{
- MarkChildrenNeedLayout();
- Invalidate();
-}
-
-//=============================================================================
-/**
- * Overload of SetSize to allow it to take 2 parameters.
- * This will call SetSize( CPt ) so there is no need to extend this method.
- * @param inWidth the new width of this control.
- * @param inHeight the new height of this control.
- */
-void CControl::SetSize(long inX, long inY)
-{
- SetSize(CPt(inX, inY));
-}
-
-//=============================================================================
-/**
- * Get the minimum allowable size of this control.
- * This is used by layout managers to get the minimum size that a control is
- * allowed to be when it is resizing the control. This defaults to 0,0.
- * @return the minimum size that this control is allowed to be.
- */
-CPt CControl::GetMinimumSize()
-{
- return m_ControlData->m_MinSize;
-}
-
-//=============================================================================
-/**
- * Set the minimum allowable size of this control.
- * This is used by layout managers to get the minimum size that a control is
- * allowed to be when it is resizing the control. This defaults to 0,0.
- * param inSize the minimum size that this control is allowed to be.
- */
-void CControl::SetMinimumSize(CPt inSize)
-{
- if (inSize != m_ControlData->m_MinSize) {
- NotifyParentNeedsLayout();
- m_ControlData->m_MinSize = inSize;
- if (inSize.x > m_ControlData->m_MaxSize.x)
- m_ControlData->m_MaxSize.x = inSize.x;
- if (inSize.y > m_ControlData->m_MaxSize.y)
- m_ControlData->m_MaxSize.y = inSize.y;
- }
-}
-
-//=============================================================================
-/**
- * Get the maximum allowable size of this control.
- * This is used by layout managers to get the maximum size that a control is
- * allowed to be when it is resizing the control. This defaults to LONG_MAX,LONG_MAX.
- * @return the maximum size that this control is allowed to be.
- */
-CPt CControl::GetMaximumSize()
-{
- return m_ControlData->m_MaxSize;
-}
-
-//=============================================================================
-/**
- * Set the maximum allowable size of this control.
- * This is used by layout managers to get the maximum size that a control is
- * allowed to be when it is resizing the control. This defaults to LONG_MAX,LONG_MAX.
- * @param inSize the maximum size that this control is allowed to be.
- */
-void CControl::SetMaximumSize(CPt inSize)
-{
- if (inSize != m_ControlData->m_MaxSize) {
- NotifyParentNeedsLayout();
- m_ControlData->m_MaxSize = inSize;
- }
-}
-
-//=============================================================================
-/**
- * Get the preferred size of this control.
- * This is used by layout managers to get the preferred size of the control.
- * The preferred size is often used for relative scaling of sibling controls.
- * @return the preferred size of this control.
- */
-CPt CControl::GetPreferredSize()
-{
- return m_ControlData->m_PrefSize;
-}
-
-//=============================================================================
-/**
- * Set the preferred size of this control.
- * This is used by layout managers to get the preferred size of the control.
- * The preferred size is often used for relative scaling of sibling controls.
- * @param the preferred size of this control.
- */
-void CControl::SetPreferredSize(CPt inSize)
-{
- if (inSize != m_ControlData->m_PrefSize) {
- NotifyParentNeedsLayout();
- Invalidate();
- m_ControlData->m_PrefSize = inSize;
- }
-}
-
-void CControl::SetAbsoluteSize(CPt inSize)
-{
- SetMinimumSize(inSize);
- SetMaximumSize(inSize);
- SetPreferredSize(inSize);
- SetSize(inSize);
-}
-
-//=============================================================================
-/**
- * Event called when the mouse is moving.
- * This event will be called when the mouse is over this control or when this
- * control has the focus. This can be extended by controls but should be called
- * if the event is to be propagated down to child controls.
- * @param inPoint the location of the mouse relative to this control.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- */
-void CControl::OnMouseMove(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- bool theHitFlag = false;
- // Go through all the children notifying them of mouse moves.
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If a child has not already gotten the move (higher level child covering a lower level
- // one)
- // then check the hit test.
- if (!theHitFlag && theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- // This is the first child to be hit, do not allow the message to go onto another
- // sibling under this one.
- theHitFlag = true;
-
- // Do not fire events to non-enabled children.
- if (theChild->IsEnabled()) {
- // If this is the first time the mouse is over this then fire a mouse over
- if (!theChild->IsMouseOver())
- theChild->OnMouseOver(theChildPoint, inFlags);
- // Fire a mouse move as well, this will also propagate the mouse over to
- // grand-children etc.
- theChild->OnMouseMove(theChildPoint, inFlags);
- }
- }
- // Check all the children and if they think the mouse is over them then notify them of a
- // mouse out.
- else if (theChild->IsMouseOver()) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- theChild->OnMouseOut(theChildPoint, inFlags);
- }
- }
-
- // If there is a child with focus and the mouse is not over it then still notify it of the mouse
- // move
- // If the mouse is over it then it would have gotten the move from the above loop.
- if (m_ControlData->m_MouseFocus && !m_ControlData->m_MouseFocus->IsMouseOver()) {
- CPt theChildPoint = inPoint - m_ControlData->m_MouseFocus->GetPosition();
- m_ControlData->m_MouseFocus->OnMouseMove(theChildPoint, inFlags);
- }
-}
-
-//=============================================================================
-/**
- * Notification that the mouse is over this control.
- * This is only called once when the mouse enters the control, and does not get
- * called until the mouse leaves then re-enters the control.
- * @param inPoint where the mouse is, relative to this control.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- */
-void CControl::OnMouseOver(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- Q_UNUSED(inPoint);
- Q_UNUSED(inFlags);
- m_ControlData->m_IsMouseOver = true;
-}
-
-//=============================================================================
-/**
- * Notification that the mouse left this control.
- * This is only called once when the mouse leaves the control and does not get
- * called until the mouse enters then re-leaves the control.
- * This also notifies all children that the mouse is over that it is no longer
- * over.
- * @param inPoint where the mouse is, relative to this control.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- */
-void CControl::OnMouseOut(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- m_ControlData->m_IsMouseOver = false;
-
- // Go through all the children looking for ones that think the mouse is over.
- // If it is then notify it of a mouse out.
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->IsMouseOver()) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- theChild->OnMouseOut(inPoint, inFlags);
- }
- }
-}
-
-//=============================================================================
-/**
- * Notification that the left mouse button was clicked on this control.
- * This handles the mouse hits and sets the focus to the control that was
- * clicked on.
- * @param inPoint where the mouse was clicked, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- * @return true if the mouse event is processed.
- */
-bool CControl::OnMouseDown(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- bool theRetVal = false;
- bool theChildGotHit = false;
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- theChildGotHit = true;
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled()) {
- theRetVal = theChild->OnMouseDown(theChildPoint, inFlags);
-
- if (m_ControlData->m_Focus != theChild) {
- if (m_ControlData->m_Focus)
- m_ControlData->m_Focus->OnLoseFocus();
- if (theChild->CanGainFocus()) {
- m_ControlData->m_Focus = theChild;
- m_ControlData->m_Focus->OnGainFocus();
- } else {
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- }
- }
- m_ControlData->m_MouseFocus = theChild;
- } else {
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- }
-
- // only want OnMouseDown to be called on the first child under the point.
- break;
- }
- }
- if (!theChildGotHit && m_ControlData->m_Focus) {
- m_ControlData->m_Focus->OnLoseFocus();
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- }
- m_ControlData->SetMouseDown(!theRetVal);
-
- return theRetVal;
-}
-
-//=============================================================================
-/**
- * Notification that the right mouse button was clicked on this control.
- * This handles the mouse hits and sets the focus to the control that was
- * clicked on.
- * @param inPoint where the mouse was clicked, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- * @return true if the mouse event is processed.
- */
-bool CControl::OnMouseRDown(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- bool theRetVal = false;
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
-
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled()) {
- if (m_ControlData->m_Focus != theChild) {
- if (m_ControlData->m_Focus)
- m_ControlData->m_Focus->OnLoseFocus();
- if (theChild->CanGainFocus()) {
- m_ControlData->m_Focus = theChild;
- m_ControlData->m_Focus->OnGainFocus();
- } else {
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- }
- }
- m_ControlData->m_MouseFocus = theChild;
- theRetVal = theChild->OnMouseRDown(theChildPoint, inFlags);
- } else {
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- }
-
- // only want OnMouseDown to be called on the first child under the point.
- break;
- }
- }
-
- return theRetVal;
-}
-
-//=============================================================================
-/**
- * Notification thatthe mouse was double clicked on this control.
- * This handled the mouse hits and passes it down to all the children.
- * @param inPoint where the mouse was clicked, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- * @return true if the mouse event is processed.
- */
-bool CControl::OnMouseDoubleClick(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- bool theRetVal = false;
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled())
- theRetVal = theChild->OnMouseDoubleClick(theChildPoint, inFlags);
-
- // only want OnMouseDown to be called on the first child under the point.
- break;
- }
- }
-
- return theRetVal;
-}
-
-bool CControl::OnMouseWheel(CPt inPoint, long inAmount, Qt::KeyboardModifiers inFlags)
-{
- bool theRetVal = false;
-
- // try letting the focus getting the wheel first
- if (m_ControlData->m_Focus) {
- CPt theChildPoint = inPoint - m_ControlData->m_Focus->GetPosition();
- theRetVal = m_ControlData->m_Focus->OnMouseWheel(theChildPoint, inAmount, inFlags);
- }
-
- // if the focus does not want the wheel then let the mouse pos do it.
- if (!theRetVal) {
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->GetMouseWheelEventState() == ControlEventState::Listening
- && theChild->IsEnabled() && theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- theRetVal = theChild->OnMouseWheel(theChildPoint, inAmount, inFlags);
- break;
- }
- }
- }
-
- return theRetVal;
-}
-
-//=============================================================================
-/**
- * Notification that the mouse is hovering over this control.
- * This handles the mouse hover and passes it down to all the children.
- * @param inPoint where the mouse is located, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- * @return true if the mouse event is processed.
- */
-bool CControl::OnMouseHover(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- bool theRetVal = false;
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled())
- theRetVal = theChild->OnMouseHover(theChildPoint, inFlags);
-
- // only want OnMouseHover to be called on the first child under the point.
- break;
- }
- }
-
- return theRetVal;
-}
-
-//=============================================================================
-/**
- * Notification that the left mouse button was released.
- * This is only called on the control that has focus, not on the control under
- * the mouse.
- * @param inPoint where the mouse was released, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- */
-void CControl::OnMouseUp(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- if (m_ControlData->m_MouseFocus) {
- CPt theChildPoint = inPoint - m_ControlData->m_MouseFocus->GetPosition();
- m_ControlData->m_MouseFocus->OnMouseUp(theChildPoint, inFlags);
- }
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled() && theChild != m_ControlData->m_MouseFocus
- && theChild != m_ControlData->m_Focus) {
- theChild->OnMouseUp(theChildPoint, inFlags);
- }
-
- // only want OnMouseUp to be called on the first child under the point.
- break;
- }
- }
- m_ControlData->m_MouseFocus = std::shared_ptr<CControlData>();
-
- if (m_ControlData->m_IsMouseDown) {
- OnMouseClick(inPoint, inFlags);
- m_ControlData->SetMouseDown(false);
- }
-}
-
-//=============================================================================
-/**
- * Notification that the right mouse button was released.
- * This is only called on the control that has focus, not on the control under
- * the mouse.
- * @param inPoint where the mouse was released, in local coordinates.
- * @param inFlags Modifier keys that are down at time of event. Can be any
- * combination of the following: MODIFIER_CONTROL | MODIFIER_SHIFT |
- * MODIFIER_ALT | MOUSE_LBUTTON | MOUSE_RBUTTON | MOUSE_MBUTTON
- */
-void CControl::OnMouseRUp(CPt inPoint, Qt::KeyboardModifiers inFlags)
-{
- if (m_ControlData->m_MouseFocus) {
- CPt theChildPoint = inPoint - m_ControlData->m_MouseFocus->GetPosition();
- m_ControlData->m_MouseFocus->OnMouseRUp(theChildPoint, inFlags);
- }
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- // If the child was hit then notify it of the mouse down, and set the focus to
- // be it.
- if (theChild->HitTest(inPoint)) {
- CPt theChildPoint = inPoint - theChild->GetPosition();
- // Only send the event if the child is enabled.
- if (theChild->IsEnabled() && theChild != m_ControlData->m_MouseFocus
- && theChild != m_ControlData->m_Focus) {
- theChild->OnMouseRUp(theChildPoint, inFlags);
- }
-
- // only want OnMouseUp to be called on the first child under the point.
- break;
- }
- }
- m_ControlData->m_MouseFocus = std::shared_ptr<CControlData>();
-}
-
-//=============================================================================
-/**
- * Handles character input from the keyboard.
- *
- * @param inChar Character that was pressed
- * @return true if the character was handled, false if this control does not
- * care about the character that was pressed
- */
-bool CControl::OnChar(const QString &inChar, Qt::KeyboardModifiers inModifiers)
-{
- if (m_ControlData->m_Focus)
- return m_ControlData->m_Focus->OnChar(inChar, inModifiers);
- else
- return false;
-}
-
-//=============================================================================
-/**
- * Handles a key down message from the keyboard.
- *
- * @param inChar Character that was pressed
- * @return true if the character was handled, false if this control does not
- * care about the character that was pressed
- */
-bool CControl::OnKeyDown(unsigned int inChar, Qt::KeyboardModifiers inModifiers)
-{
- bool theRetVal = false;
-
- if (m_ControlData->m_Focus)
- theRetVal = m_ControlData->m_Focus->OnKeyDown(inChar, inModifiers);
-
- if (!theRetVal) {
- if (inChar == Qt::Key_Tab) {
- if (inModifiers & Qt::ShiftModifier)
- OnReverseTab();
- else
- OnTab();
- theRetVal = true;
- }
- }
-
- return theRetVal;
-}
-
-//=============================================================================
-/**
- * Handles a key up from the keyboard.
- *
- * @param inChar Character that was pressed
- * @return true if the character was handled, false if this control does not
- * care about the character that was pressed
- */
-bool CControl::OnKeyUp(unsigned int inChar, Qt::KeyboardModifiers)
-{
- Q_UNUSED(inChar);
- return false;
-}
-
-//=============================================================================
-/**
- * Find the first child (descendant) control that has a valid drop target.
- */
-CDropTarget *CControl::FindDropCandidate(CPt &inMousePoint, Qt::KeyboardModifiers inFlags,
- EStudioObjectType objectType,
- Q3DStudio::DocumentEditorFileType::Enum fileType)
-{
- CDropTarget *theDropTarget = NULL;
-
- // Go through all the children looking for the first one that was clicked on
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->IsMouseOver() && theChild->IsEnabled()) {
- // Put the point into this childs coords.
- CPt theChildPoint = inMousePoint - theChild->GetPosition();
-
- // Allow the child the opportunity to respond
- theDropTarget = theChild->FindDropCandidate(theChildPoint, inFlags, objectType,
- fileType);
-
- if (theDropTarget)
- break;
- }
- }
- return theDropTarget;
-}
-
-//=============================================================================
-/**
- * Add a child control to this control.
- * This will make the child behave as a child of this, get set up for drawing
- * and events. The inInsertBefore control is used to determine Z-depth, or
- * manually insert a control into a specific location.
- * The child cannot already be a child of another control.
- * @param inControl the control to be added.
- * @param inInsertBefore the control to be inserted before, or std::shared_ptr<CControlData>() to
- * be at the back.\
- */
-void CControl::AddChild(CControl *inControl,
- CControl *inInsertBefore /*=std::shared_ptr<CControlData>()*/)
-{
- NotifyParentNeedsLayout();
- ControlGraph::AddChild(*this, *inControl, inInsertBefore);
-}
-
-//=============================================================================
-/**
- * Remove a child control from this control.
- * This will remove it from drawing and getting any events.
- * @param inControl the control to be removed.
- */
-void CControl::RemoveChild(CControl *inControl)
-{
- if (inControl) {
- ControlGraph::RemoveChild(*this, *inControl);
-
- if (m_ControlData->m_Focus == inControl->m_ControlData)
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- if (m_ControlData->m_MouseFocus == inControl->m_ControlData)
- m_ControlData->m_MouseFocus = std::shared_ptr<CControlData>();
- }
-}
-
-//=============================================================================
-/**
- * Remove all child controls from this control.
- * This will remove it from drawing and getting any events.
- *
- * This is not recursive
- */
-void CControl::RemoveAllChildren()
-{
- NotifyParentNeedsLayout();
- ControlGraph::RemoveAllChildren(*this);
-
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- m_ControlData->m_MouseFocus = std::shared_ptr<CControlData>();
-}
-
-//=============================================================================
-/**
- * Retrieve the index of a child control. The index will return the zero based position.
- * @param inChildControl the control that is a direct child of this control
- * @return the zero-based index of this control we will return -1 if we don't find the control
- */
-long CControl::GetChildIndex(CControl *inChildControl)
-{
- return ControlGraph::GetChildIndex(*this, *inChildControl);
-}
-
-static inline CControl *ToControl(std::shared_ptr<CControlData> inPtr)
-{
- if (inPtr)
- return inPtr->GetControl();
- return nullptr;
-}
-
-//=============================================================================
-/**
- * Finds a child control by its name
- * @return the child if found, std::shared_ptr<CControlData>() otherwise
- */
-CControl *CControl::FindChildByName(const Q3DStudio::CString &inName)
-{
- std::shared_ptr<CControlData> theResult = std::shared_ptr<CControlData>();
-
- ControlGraph::SIterator theChildIter = GetChildren();
- for (; !theChildIter.IsDone(); ++theChildIter) {
- if (theChildIter.GetCurrent()->GetName() == inName) {
- theResult = theChildIter.GetCurrent();
- break;
- }
- }
-
- return ToControl(theResult);
-}
-
-CControl *CControl::FocusedChild()
-{
- CControl *theResult = nullptr;
-
- ControlGraph::SIterator theChildIter = GetChildren();
- for (; !theChildIter.IsDone(); ++theChildIter) {
- auto current = ToControl(theChildIter.GetCurrent());
- auto hasFocus = HasFocus(current);
- if (hasFocus) {
- if (current->GetFirstChild())
- theResult = current->FocusedChild();
- else
- theResult = current;
- break;
- }
- }
-
- return theResult;
-}
-
-//=============================================================================
-/**
- * Check to see if the mouse is over this control or not.
- * @return true if the mouse is over this control.
- */
-bool CControl::IsMouseOver() const
-{
- return m_ControlData->m_IsMouseOver;
-}
-
-//=============================================================================
-/**
- * Check to see if inPoint is over this control or not.
- * This is used for mouse hits and can be extended for non-standard control
- * shapes. Non-visible controls always return false.
- * @param inPoint the location of the mouse in local coordinates.
- */
-bool CControl::HitTest(const CPt &inPoint) const
-{
- CPt thePoint = inPoint - GetPosition();
- CPt theSize = GetSize();
- // Basic check to see if it's in the size.
- if (IsVisible() && thePoint.x >= 0 && thePoint.y >= 0 && thePoint.x < theSize.x
- && thePoint.y < theSize.y) {
- return true;
- }
- return false;
-}
-
-//=============================================================================
-/**
- * Checks to see if any part of this control is in the rect.
- * This is used for drawing and ignoring objects that do not need to be
- * redrawn or need to be drawn.
- * @param inRect the rect to check to see if this is in.
- * @return true if this is in the rect.
- */
-bool CControl::IsInRect(const CRct &inRect) const
-{
- CRct myRect(GetPosition(), GetSize());
-
- if (myRect.position <= inRect.size + inRect.position) {
- if (myRect.size + myRect.position >= inRect.position)
- return true;
- }
- return false;
-}
-
-//=============================================================================
-/**
- * Invalidate this control and cause it to be redrawn.
- * @param inInvalidate true if this is to be invalidated.
- */
-void CControl::Invalidate(bool inInvalidate /*= true*/)
-{
- m_ControlData->m_IsInvalidated = inInvalidate;
- if (inInvalidate && GetParent() != nullptr)
- GetParent()->OnChildInvalidated();
- if (!inInvalidate)
- m_ControlData->m_IsChildInvalidated = false;
-}
-
-//=============================================================================
-/**
- * Invalidate this object and all children within inRect.
- * @param inRect the rect in which to invalidate all children.
- */
-void CControl::InvalidateRect(const CRct &inRect)
-{
- Invalidate();
-
- ControlGraph::SIterator thePos = GetChildren();
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->IsInRect(inRect)) {
- CRct theChildRect = inRect;
- theChildRect.Offset(theChild->GetPosition());
-
- theChild->InvalidateRect(inRect);
- }
- }
-}
-
-//=============================================================================
-/**
- * Check to see if this control is invalidated or not.
- * @return true if this control is invalidated.
- */
-bool CControl::IsInvalidated() const
-{
- return m_ControlData->IsInvalidated();
-}
-
-//=============================================================================
-/**
- * Notifies this control that a child of it has been invalidated.
- */
-void CControl::OnChildInvalidated()
-{
- // Only do it if we haven't already, avoid multiple traversals up the tree.
- if (!m_ControlData->m_IsChildInvalidated) {
- if (GetParent() != nullptr)
- GetParent()->OnChildInvalidated();
- else if (m_ControlData->m_WindowListener != nullptr)
- m_ControlData->m_WindowListener->OnControlInvalidated();
-
- m_ControlData->m_IsChildInvalidated = true;
- }
-}
-
-//=============================================================================
-/**
- * Checks to see if a child of this control is invalidated.
- */
-bool CControl::IsChildInvalidated() const
-{
- return m_ControlData->m_IsChildInvalidated || m_ControlData->m_IsInvalidated;
-}
-
-//=============================================================================
-/**
- * Set this control as being visible or not.
- * If the control is not visible then it will not be drawn and will not
- * get mouse clicks.
- * @param inIsVisible true if this control is to be visible.
- */
-void CControl::SetVisible(bool inIsVisible)
-{
- if (inIsVisible != m_ControlData->m_IsVisible) {
- m_ControlData->m_IsVisible = inIsVisible;
- NotifyParentNeedsLayout();
-
- if (GetParent() != nullptr)
- GetParent()->OnChildSizeChanged(this);
-
- OnVisibleStateChange(inIsVisible);
- OnParentVisibleStateChanged(inIsVisible);
-
- this->Invalidate();
- }
-}
-
-//=============================================================================
-/**
- * Notification that the visible state of a control has changed
- */
-void CControl::OnVisibleStateChange(bool inIsVisible)
-{
- Q_UNUSED(inIsVisible);
-}
-
-void CControl::OnParentVisibleStateChanged(bool inIsVisible)
-{
- NotifyParentNeedsLayout();
- ControlGraph::SIterator thePos = GetChildren();
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- theChild->OnParentVisibleStateChanged(inIsVisible);
- }
-}
-
-//=============================================================================
-/**
- * Checks to see if this control is visible or not.
- * If the control is not visible then it will not be drawn and will not
- * get mouse clicks.
- * @return true if this control is visible.
- */
-bool CControl::IsVisible() const
-{
- return m_ControlData->m_IsVisible;
-}
-
-//=============================================================================
-/**
- * Sets whether or not this control is enabled.
- * If the control is not enabled then it is still drawn and still intercepts
- * mouse clicks, but it will not actually process them.
- * @param inIsEnabled true if this control is to be enabled.
- */
-void CControl::SetEnabled(bool inIsEnabled)
-{
- if (inIsEnabled != m_ControlData->m_IsEnabled) {
- NotifyParentNeedsLayout();
- m_ControlData->m_IsEnabled = inIsEnabled;
-
- ControlGraph::SIterator thePos = GetChildren();
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- theChild->SetParentEnabled(inIsEnabled);
- }
- Invalidate();
- }
-}
-
-void CControl::SetParentEnabled(bool inParentEnabled)
-{
- NotifyParentNeedsLayout();
- m_ControlData->m_IsParentEnabled = inParentEnabled;
- ControlGraph::SIterator thePos = GetChildren();
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- theChild->SetParentEnabled(inParentEnabled);
- }
- Invalidate();
-}
-
-//=============================================================================
-/**
- * Gets whether or not this control is enabled.
- * If the control is not enabled then it is still drawn and still intercepts
- * mouse clicks, but it will not actually process them.
- * @param inIsEnabled true if this control is to be enabled.
- */
-bool CControl::IsEnabled() const
-{
- return m_ControlData->IsEnabled();
-}
-
-//=============================================================================
-/**
- * Gets teh value of the enabled flag without its parent's flag
- */
-bool CControl::GetEnabledFlag()
-{
- return m_ControlData->GetEnabledFlag();
-}
-
-//=============================================================================
-/**
- * Sets the enabled flag...this is used when a control wants to override the
- * SetEnabled function and does not necessarily want to pass enabled messages
- * to its children no matter what
- */
-void CControl::SetEnabledFlag(bool inIsEnabled)
-{
- m_ControlData->SetEnabledFlag(inIsEnabled);
- Invalidate();
-}
-
-//=============================================================================
-/**
- * Notification that the size of a child has changed.
- * @param inControl the control that has changed size.
- */
-void CControl::OnChildSizeChanged(CControl *inControl)
-{
- Q_UNUSED(inControl);
-}
-
-void CControl::SetName(const QString &inName)
-{
- m_ControlData->SetName(Q3DStudio::CString::fromQString(inName));
-}
-
-QString CControl::GetName()
-{
- return m_ControlData->GetName().toQString();
-}
-
-void CControl::BeginDrawChildren(CRenderer *inRenderer)
-{
- Q_UNUSED(inRenderer);
-}
-
-long CControl::DoPopup(QMenu *inMenu, CPt inLocation)
-{
- inLocation.Offset(GetPosition());
- CControl *theParent(GetParent());
- if (theParent)
- return theParent->DoPopup(inMenu, inLocation);
- else
- return m_ControlData->m_WindowListener->DoPopup(inMenu, inLocation);
-}
-
-//=============================================================================
-/**
- * Called when a control acquires focus
- */
-void CControl::OnGainFocus()
-{
-}
-
-//=============================================================================
-/**
- * Causes focus to be lost.
- */
-void CControl::OnLoseFocus()
-{
- if (m_ControlData->m_Focus)
- m_ControlData->m_Focus->OnLoseFocus();
- FireFocusEvent(false);
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
-}
-
-//=============================================================================
-/**
- * @return the parent control of this class
- */
-CControl *CControl::GetParent()
-{
- return m_ControlData->GetParent();
-}
-
-const CControl *CControl::GetParent() const
-{
- return m_ControlData->GetParent();
-}
-
-//=============================================================================
-/**
- * Removes a control from the top level control
- */
-void CControl::RemoveUberControl(CControl *inControl)
-{
- if (GetParent() != nullptr)
- GetParent()->RemoveUberControl(inControl);
- else
- RemoveChild(inControl);
- Invalidate();
-}
-
-long CControl::GetChildCount()
-{
- return ControlGraph::GetNumChildren(*this);
-}
-
-Q3DStudio::Control::ControlGraph::SIterator CControl::GetChildren()
-{
- return ControlGraph::GetChildren(*this);
-}
-
-Q3DStudio::Control::ControlGraph::SReverseIterator CControl::GetReverseChildren()
-{
- return ControlGraph::GetRChildren(*this);
-}
-
-//=============================================================================
-/**
- * Gets the global position of the point in regards to the top level control
- */
-CPt CControl::GetGlobalPosition(CPt inChildPoint) const
-{
- CPt thePosition(GetPosition());
- CPt thePoint = CPt(inChildPoint.x + thePosition.x, inChildPoint.y + thePosition.y);
- if (GetParent())
- return GetParent()->GetGlobalPosition(thePoint);
- else
- return thePoint;
-}
-
-//=============================================================================
-/**
- * Query the platform specific render device (window)
- */
-Qt3DSRenderDevice CControl::GetPlatformDevice()
-{
- if (GetParent())
- return GetParent()->GetPlatformDevice();
- return nullptr;
-}
-
-//=============================================================================
-/**
- * Does self or child use this render device?
- * @see CWndControl::OnKillFocus
- */
-bool CControl::IsChildPlatformDevice(Qt3DSRenderDevice inDevice)
-{
- if (GetPlatformDevice() == inDevice)
- return true;
-
- ControlGraph::SIterator thePos = GetChildren();
- for (; thePos.HasNext(); ++thePos) {
- std::shared_ptr<CControlData> theChild = (*thePos);
- if (theChild->IsChildPlatformDevice(inDevice))
- return true;
- }
-
- return false;
-}
-
-//=============================================================================
-/**
- * Shows the window's moveable window with text
- *
- * @param inLocation the postion of hte center point of the window
- * @param inText the text the window will display
- */
-void CControl::ShowMoveableWindow(CPt inLocation, const Q3DStudio::CString &inText,
- CRct inBoundingRct)
-{
- CPt thePosition(GetPosition());
- CPt thePoint = CPt(inLocation.x + thePosition.x, inLocation.y + thePosition.y);
-
- if (GetParent())
- GetParent()->ShowMoveableWindow(thePoint, inText, inBoundingRct);
- else if (m_ControlData->m_WindowListener)
- m_ControlData->m_WindowListener->ShowMoveableWindow(thePoint, inText, inBoundingRct);
-}
-
-//=============================================================================
-/**
- * Hides the window's moveable window
- */
-void CControl::HideMoveableWindow()
-{
- if (GetParent() != nullptr)
- GetParent()->HideMoveableWindow();
- else if (m_ControlData->m_WindowListener)
- m_ControlData->m_WindowListener->HideMoveableWindow();
-}
-
-//=============================================================================
-/**
- * Offsets the position of this control... this is useful if you don't want to calculate
- * the global position every time
- */
-void CControl::OffsetPosition(CPt inOffset)
-{
- CPt thePosition(GetPosition());
- thePosition.Offset(inOffset);
- SetPosition(thePosition);
-}
-
-//=============================================================================
-/**
- * Gets the first child of this control
- */
-CControl *CControl::GetFirstChild()
-{
- std::shared_ptr<CControlData> theChild = std::shared_ptr<CControlData>();
- ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this);
- if (!thePos.IsDone())
- theChild = (*thePos);
- return ToControl(theChild);
-}
-
-//=============================================================================
-/**
- * @return true if this control has focus
- */
-bool CControl::HasFocus(CControl *inControl)
-{
- return (ToControl(m_ControlData->m_Focus) == inControl);
-}
-
-//=============================================================================
-/**
- * default is true for controls... override if the control cannot have focus
- */
-bool CControl::CanGainFocus()
-{
- if (IsVisible()) {
- for (ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this); !thePos.IsDone();
- ++thePos) {
- if ((*thePos)->CanGainFocus())
- return true;
- }
- }
- return false;
-}
-
-//=============================================================================
-/**
- * Returns true if this CControl is in focus.
- * @return True if this CControl is in focus.
- */
-bool CControl::IsInFocus()
-{
- if (GetParent())
- return GetParent()->HasFocus(this);
-
- return false;
-}
-
-//=============================================================================
-/**
- * Handles the tab button in controls
- */
-void CControl::OnTab()
-{
- // Go through the children... if there is a focus, then get the next control
- ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this);
- bool theFoundFlag = false;
- if (m_ControlData->m_Focus) {
- while (!thePos.IsDone() && !theFoundFlag) {
- std::shared_ptr<CControlData> theCurrentControl = (*thePos);
- if (theCurrentControl == m_ControlData->m_Focus) {
- ++thePos;
- while (!thePos.IsDone() && !theFoundFlag) {
- std::shared_ptr<CControlData> theNextFocusCanidate = (*thePos);
- if (theNextFocusCanidate->CanGainFocus()) {
- m_ControlData->m_Focus->OnLoseFocus();
- theFoundFlag = true;
- m_ControlData->m_Focus = theNextFocusCanidate;
- m_ControlData->m_Focus->SetFocusToFirstAvailable();
- } else {
- ++thePos;
- }
- }
- } else {
- ++thePos;
- }
- }
- // If we didn't find it and we have a parent, then allow the parent to decide
- if (!theFoundFlag) {
- m_ControlData->m_Focus->OnLoseFocus();
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- if (GetParent())
- GetParent()->OnTab();
- else
- SetFocusToFirstAvailable();
- }
- } else {
- // If no focus, then go to first available control
- SetFocusToFirstAvailable();
- }
-}
-
-//=============================================================================
-/**
- * Handles the shift tab button in controls
- */
-void CControl::OnReverseTab()
-{
- // Go through the children in reverse order... if there is a focus, then get the next control
- ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- bool theFoundFlag = false;
- if (m_ControlData->m_Focus) {
- while (!thePos.IsDone() && !theFoundFlag) {
- std::shared_ptr<CControlData> theCurrentControl = (*thePos);
- if (theCurrentControl == m_ControlData->m_Focus) {
- ++thePos;
- while (!thePos.IsDone() && !theFoundFlag) {
- std::shared_ptr<CControlData> theNextFocusCanidate = (*thePos);
- if (theNextFocusCanidate->CanGainFocus()) {
- m_ControlData->m_Focus->OnLoseFocus();
- theFoundFlag = true;
- m_ControlData->m_Focus = theNextFocusCanidate;
- m_ControlData->m_Focus->SetFocusToLastAvailable();
- } else {
- ++thePos;
- }
- }
- } else {
- ++thePos;
- }
- }
- // If we didn't find it and we have a parent, then allow the parent to decide
- if (!theFoundFlag) {
- m_ControlData->m_Focus->OnLoseFocus();
- m_ControlData->m_Focus = std::shared_ptr<CControlData>();
- if (GetParent())
- GetParent()->OnReverseTab();
- else
- SetFocusToLastAvailable();
- }
- } else {
- // If no focus, then go to last available control
- SetFocusToLastAvailable();
- }
-}
-
-//=============================================================================
-/**
- * Sets the focus to the first available child control
- */
-void CControl::SetFocusToFirstAvailable()
-{
- bool theFlag = false;
- OnGainFocus();
-
- // if there are any child controls, then go through them
- for (ControlGraph::SIterator thePos = ControlGraph::GetChildren(*this);
- !thePos.IsDone() && !theFlag; ++thePos) {
- std::shared_ptr<CControlData> theControl = (*thePos);
- if (theControl->CanGainFocus()) {
- m_ControlData->m_Focus = theControl;
- m_ControlData->m_Focus->SetFocusToFirstAvailable();
- theFlag = true;
- }
- }
-}
-
-//=============================================================================
-/**
- * Sets the focus to the last available child control
- */
-void CControl::SetFocusToLastAvailable()
-{
- bool theFlag = false;
- OnGainFocus();
-
- // if there are any child controls, then go through them
- for (ControlGraph::SReverseIterator thePos = ControlGraph::GetRChildren(*this);
- !thePos.IsDone() && !theFlag; ++thePos) {
- std::shared_ptr<CControlData> theControl = (*thePos);
- if (theControl->CanGainFocus()) {
- m_ControlData->m_Focus = theControl;
- m_ControlData->m_Focus->SetFocusToLastAvailable();
- theFlag = true;
- }
- }
-}
-
-//===============================================================================
-/**
-* Coverts the given point from local coordinates into global coordinates.
-* @param inPoint the point in local coordinates to be converted
-* @return The point translated to global coordinates
-*/
-CPt CControl::ClientToScreen(CPt inPoint)
-{
- CPt theFinalPt = inPoint + m_ControlData->m_Position;
-
- if (GetParent())
- theFinalPt = GetParent()->ClientToScreen(theFinalPt);
- else if (m_ControlData->m_WindowListener)
- theFinalPt = m_ControlData->m_WindowListener->ClientToScreen(theFinalPt);
-
- return theFinalPt;
-}
-
-//===============================================================================
-/**
-* Coverts the given point from screen coordinates into local space.
-* @param inPoint the point in screen coordinates to be converted
-* @return The point translated to local, client coordinates
-*/
-CPt CControl::ScreenToClient(CPt inPoint)
-{
- CPt theFinalPt = inPoint - m_ControlData->m_Position;
-
- if (GetParent())
- theFinalPt = GetParent()->ScreenToClient(theFinalPt);
- else if (m_ControlData->m_WindowListener)
- theFinalPt = m_ControlData->m_WindowListener->ScreenToClient(theFinalPt);
-
- return theFinalPt;
-}
-
-//===============================================================================
-/**
-* Adds a focus listener to this control
-*/
-void CControl::AddFocusListener(CChildFocusListener *inListener)
-{
- m_ControlData->m_FocusListeners.AddListener(inListener);
-}
-
-//===============================================================================
-/**
-* Removes a focus listener to this control
-*/
-void CControl::RemoveFocusListener(CChildFocusListener *inListener)
-{
- m_ControlData->m_FocusListeners.RemoveListener(inListener);
-}
-
-//===============================================================================
-/**
-* tells anyone listeneing that the focus of this control has changed
-*/
-void CControl::FireFocusEvent(bool inStatus)
-{
- m_ControlData->m_FocusListeners.FireEvent(&CChildFocusListener::OnChildFocusChange, inStatus);
-}
-
-//===============================================================================
-/**
- * Get the platform specific view that this is embedded into.
- * Used for when platform dependent controls have to be embedded or used.
- */
-TPlatformView CControl::GetPlatformView()
-{
- if (GetParent())
- return GetParent()->GetPlatformView();
- else if (m_ControlData->m_WindowListener)
- return m_ControlData->m_WindowListener->GetPlatformView();
- return nullptr;
-}
-
-bool CControl::IsMouseDown()
-{
- return m_ControlData->m_IsMouseDown;
-}
-
-void CControl::OnMouseClick(CPt, Qt::KeyboardModifiers)
-{
-}
-
-void CControl::GrabFocus(CControl *inControl)
-{
- if (GetParent())
- GetParent()->GrabFocus(this);
-
- std::shared_ptr<CControlData> theNewFocus;
- if (inControl)
- theNewFocus = inControl->m_ControlData;
-
- if (m_ControlData->m_Focus != theNewFocus) {
- if (m_ControlData->m_Focus)
- m_ControlData->m_Focus->OnLoseFocus();
- m_ControlData->m_Focus = theNewFocus;
- if (m_ControlData->m_Focus)
- m_ControlData->m_Focus->OnGainFocus();
- }
-}
-
-//===============================================================================
-/**
- * Used to notify scrolling views that something should be visible.
- */
-void CControl::EnsureVisible(CRct inRect)
-{
- if (GetParent()) {
- inRect.Offset(GetPosition());
- GetParent()->EnsureVisible(inRect);
- }
-}
-
-//===============================================================================
-/**
- * Call to make this control visible.
- */
-void CControl::EnsureVisible()
-{
- CRct theRect(CPt(0, 0), GetSize());
- EnsureVisible(theRect);
-}
-
-void CControl::OnParentChanged(CControl * /*inNewParent*/)
-{
-}
-
-void CControl::MarkChildrenNeedLayout()
-{
- if (m_ControlData->m_ChildrenNeedLayout == false) {
- for (ControlGraph::SIterator theIter = GetChildren(); theIter.IsDone() == false; ++theIter)
- (*theIter)->MarkNeedsLayout();
- m_ControlData->m_ChildrenNeedLayout = true;
- }
-}
-
-void CControl::NotifyParentNeedsLayout()
-{
- CControl *theParent(GetParent());
- if (theParent)
- theParent->MarkChildrenNeedLayout();
-}
-
-void CControl::MarkNeedsLayout()
-{
- m_ControlData->m_NeedsLayout = true;
-}
-// Tell this control that one of its children need to be layed out.
-void CControl::SetLayout(CPt inSize, CPt inPosition)
-{
- SetSize(inSize);
- SetPosition(inPosition);
- m_ControlData->m_NeedsLayout = false;
-}
-
-void CControl::LayoutChildren()
-{
- for (ControlGraph::SIterator theIter = GetChildren(); theIter.IsDone() == false; ++theIter) {
- std::shared_ptr<CControlData> theChild(*theIter);
- // By default the children get the exact same layout that I do.
- theChild->SetLayout(theChild->m_Size, theChild->m_Position);
- }
- m_ControlData->m_ChildrenNeedLayout = false;
-}
-
-void CControl::EnsureLayout()
-{
- if (m_ControlData->m_NeedsLayout) {
- if (IsVisible()) {
- CControl *parent = GetParent();
- if (parent)
- parent->LayoutChildren();
- }
- m_ControlData->m_NeedsLayout = false;
- }
- if (m_ControlData->m_ChildrenNeedLayout) {
- LayoutChildren();
- m_ControlData->m_ChildrenNeedLayout = false;
- }
-}
-
-void CControl::ChildrenChanged()
-{
- MarkChildrenNeedLayout();
- Invalidate();
- m_ControlData->OnHierarchyChanged();
-}
-
-void CControl::setCursorIfNotSet(long cursor)
-{
- if (cursor != m_cursorSet) {
- if (m_cursorSet != -1)
- qApp->changeOverrideCursor(CResourceCache::GetInstance()->GetCursor(cursor));
- else
- qApp->setOverrideCursor(CResourceCache::GetInstance()->GetCursor(cursor));
- m_cursorSet = cursor;
- }
-}
-
-void CControl::resetCursor()
-{
- if (m_cursorSet != -1) {
- // Restoring back to no-override state seems to not change the cursor automatically
- // to the default cursor, so let's do that manually before restoring the cursor
- qApp->changeOverrideCursor(Qt::ArrowCursor);
- qApp->restoreOverrideCursor();
- m_cursorSet = -1;
- }
-}
-
-QCursor CControl::getCursor() const
-{
- if (m_cursorSet != -1)
- return CResourceCache::GetInstance()->GetCursor(m_cursorSet);
- return QCursor();
-}