summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/Controls/ProceduralButton.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Studio/Controls/ProceduralButton.h')
-rw-r--r--src/Authoring/Studio/Controls/ProceduralButton.h569
1 files changed, 569 insertions, 0 deletions
diff --git a/src/Authoring/Studio/Controls/ProceduralButton.h b/src/Authoring/Studio/Controls/ProceduralButton.h
new file mode 100644
index 00000000..47b39046
--- /dev/null
+++ b/src/Authoring/Studio/Controls/ProceduralButton.h
@@ -0,0 +1,569 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+//==============================================================================
+// Prefix
+//==============================================================================
+#ifndef INCLUDED_PROCEDURAL_BUTTON_H
+#define INCLUDED_PROCEDURAL_BUTTON_H 1
+#pragma once
+
+//==============================================================================
+// Includes
+//==============================================================================
+#include "Renderer.h"
+#include "ButtonControl.h"
+#include "StudioPreferences.h"
+
+//=============================================================================
+/**
+ * Template class for making procedural buttons. A procedural button has
+ * additional drawing options compared to a normal button. You must specify
+ * a derivative of CButtonControl as the class for the procedural button to
+ * extend.
+ */
+template <typename TButton>
+class CProceduralButton : public TButton
+{
+public:
+ /// Fill color styles for procedurally drawn buttons
+ enum EFillStyle {
+ EFILLSTYLE_GRADIENT, ///< Button background is filled using a gradient
+ EFILLSTYLE_FLOOD, ///< Button background is filled in a solid color
+ EFILLSTYLE_NONE ///< Button background is not filled at all
+ };
+
+ /// Struct enabling you to specify whether or not to draw each border of the button individually
+ struct SBorderOptions
+ {
+ bool m_DrawLeft; ///< If true, you want the left border to be drawn
+ bool m_DrawTop; ///< If true, you want the top border to be drawn
+ bool m_DrawRight; ///< If true, you want the right border to be drawn
+ bool m_DrawBottom; ///< If true, you want the bottom border to be drawn
+
+ /// Default Constructor - makes all borders be drawn
+ SBorderOptions()
+ {
+ m_DrawLeft = true;
+ m_DrawTop = true;
+ m_DrawRight = true;
+ m_DrawBottom = true;
+ }
+
+ /// Constructor to initialize each member of the struct individually
+ SBorderOptions(bool inLeft, bool inTop, bool inRight, bool inBottom)
+ {
+ m_DrawLeft = inLeft;
+ m_DrawTop = inTop;
+ m_DrawRight = inRight;
+ m_DrawBottom = inBottom;
+ }
+ };
+
+public:
+ CProceduralButton();
+ virtual ~CProceduralButton();
+
+ void SetFillStyleUp(EFillStyle inStyle);
+ void SetFillStyleDown(EFillStyle inStyle);
+ void SetFillStyleDisabled(EFillStyle inStyle);
+ void SetFillStyleOver(EFillStyle inStyle);
+ void SetFillStyleAll(EFillStyle inStyle);
+ void SetFillColorUp(const CColor &inColor);
+ void SetFillColorDown(const CColor &inColor);
+ void SetFillColorDisabled(const CColor &inColor);
+ void SetFillColorOver(const CColor &inColor);
+
+ void SetBorderVisibilityAll(const SBorderOptions &inBorderOptions);
+ void SetBorderVisiblityUp(const SBorderOptions &inBorderOptions);
+ void SetBorderVisiblityDown(const SBorderOptions &inBorderOptions);
+ void SetBorderVisiblityDisabled(const SBorderOptions &inBorderOptions);
+ void SetBorderVisiblityOver(const SBorderOptions &inBorderOptions);
+
+ void SetLeftBorderColor(const CColor &inColor);
+ void SetTopBorderColor(const CColor &inColor);
+ void SetRightBorderColor(const CColor &inColor);
+ void SetBottomBorderColor(const CColor &inColor);
+
+protected:
+ virtual void Render(CRenderer *inRenderer);
+ void DrawBackground(CRenderer *inRenderer);
+ void DrawBorder(CRenderer *inRenderer);
+ EFillStyle GetCurrentFillStyle();
+ CColor GetCurrentBackgroundColor();
+ SBorderOptions GetCurrentBorderOptions();
+
+protected:
+ EFillStyle m_UpFillStyle;
+ EFillStyle m_DownFillStyle;
+ EFillStyle m_DisabledFillStyle;
+ EFillStyle m_OverFillStyle;
+ CColor m_UpColor;
+ CColor m_DownColor;
+ CColor m_DisabledColor;
+ CColor m_OverColor;
+ CColor m_LeftBorderColor;
+ CColor m_TopBorderColor;
+ CColor m_RightBorderColor;
+ CColor m_BottomBorderColor;
+ SBorderOptions m_UpBorders;
+ SBorderOptions m_DownBorders;
+ SBorderOptions m_DisabledBorders;
+ SBorderOptions m_OverBorders;
+};
+
+//==============================================================================
+// Template implemenations
+//==============================================================================
+
+//=============================================================================
+/**
+ * Constructor
+ */
+template <typename TButton>
+CProceduralButton<TButton>::CProceduralButton()
+ : TButton()
+ , m_UpFillStyle(EFILLSTYLE_GRADIENT)
+ , m_DownFillStyle(EFILLSTYLE_GRADIENT)
+ , m_DisabledFillStyle(EFILLSTYLE_NONE)
+ , m_OverFillStyle(EFILLSTYLE_GRADIENT)
+ , m_UpColor(CStudioPreferences::GetBaseColor())
+ , m_DownColor(CStudioPreferences::GetButtonDownColor())
+ , m_DisabledColor(CStudioPreferences::GetBaseColor())
+ , m_OverColor(CStudioPreferences::GetBaseColor())
+ , m_LeftBorderColor(CStudioPreferences::GetButtonShadowColor())
+ , m_TopBorderColor(CStudioPreferences::GetButtonShadowColor())
+ , m_RightBorderColor(CStudioPreferences::GetButtonShadowColor())
+ , m_BottomBorderColor(CStudioPreferences::GetButtonShadowColor())
+{
+}
+
+//=============================================================================
+/**
+ * Destructor
+ */
+template <typename TButton>
+CProceduralButton<TButton>::~CProceduralButton()
+{
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillStyleUp(EFillStyle inStyle)
+{
+ if (m_UpFillStyle != inStyle) {
+ m_UpFillStyle = inStyle;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillStyleDown(EFillStyle inStyle)
+{
+ if (m_DownFillStyle != inStyle) {
+ m_DownFillStyle = inStyle;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillStyleDisabled(EFillStyle inStyle)
+{
+ if (m_DisabledFillStyle != inStyle) {
+ m_DisabledFillStyle = inStyle;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillStyleOver(EFillStyle inStyle)
+{
+ if (m_OverFillStyle != inStyle) {
+ m_OverFillStyle = inStyle;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillStyleAll(EFillStyle inStyle)
+{
+ SetFillStyleUp(inStyle);
+ SetFillStyleDown(inStyle);
+ SetFillStyleDisabled(inStyle);
+ SetFillStyleOver(inStyle);
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillColorUp(const CColor &inColor)
+{
+ if (m_UpColor != inColor) {
+ m_UpColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillColorDown(const CColor &inColor)
+{
+ if (m_DownColor != inColor) {
+ m_DownColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillColorDisabled(const CColor &inColor)
+{
+ if (m_DisabledColor != inColor) {
+ m_DisabledColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetFillColorOver(const CColor &inColor)
+{
+ if (m_OverColor != inColor) {
+ m_OverColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+template <typename TButton>
+void CProceduralButton<TButton>::SetBorderVisibilityAll(const SBorderOptions &inBorderOptions)
+{
+ SetBorderVisiblityUp(inBorderOptions);
+ SetBorderVisiblityDown(inBorderOptions);
+ SetBorderVisiblityDisabled(inBorderOptions);
+ SetBorderVisiblityOver(inBorderOptions);
+}
+
+template <typename TButton>
+void CProceduralButton<TButton>::SetBorderVisiblityUp(const SBorderOptions &inBorderOptions)
+{
+ m_UpBorders = inBorderOptions;
+}
+
+template <typename TButton>
+void CProceduralButton<TButton>::SetBorderVisiblityDown(const SBorderOptions &inBorderOptions)
+{
+ m_DownBorders = inBorderOptions;
+}
+
+template <typename TButton>
+void CProceduralButton<TButton>::SetBorderVisiblityDisabled(const SBorderOptions &inBorderOptions)
+{
+ m_DisabledBorders = inBorderOptions;
+}
+
+template <typename TButton>
+void CProceduralButton<TButton>::SetBorderVisiblityOver(const SBorderOptions &inBorderOptions)
+{
+ m_OverBorders = inBorderOptions;
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetLeftBorderColor(const CColor &inColor)
+{
+ if (m_LeftBorderColor != inColor) {
+ m_LeftBorderColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetTopBorderColor(const CColor &inColor)
+{
+ if (m_TopBorderColor != inColor) {
+ m_TopBorderColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetRightBorderColor(const CColor &inColor)
+{
+ if (m_RightBorderColor != inColor) {
+ m_RightBorderColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::SetBottomBorderColor(const CColor &inColor)
+{
+ if (m_BottomBorderColor != inColor) {
+ m_BottomBorderColor = inColor;
+ TButton::Invalidate();
+ }
+}
+
+//=============================================================================
+/**
+ * xxx
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::Render(CRenderer *inRenderer)
+{
+ // Fill the background if desired
+ DrawBackground(inRenderer);
+
+ // Draw the button icon
+ TButton::Render(inRenderer);
+
+ // Draw the border
+ DrawBorder(inRenderer);
+}
+
+//=============================================================================
+/**
+ * Fills the background of this button with the appropriate color and style.
+ * The style is specified by calling "GetCurrentFillStyle" which may indicate
+ * not to fill the background at all.
+ * @param inRenderer the renderer to draw to
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::DrawBackground(CRenderer *inRenderer)
+{
+ CPt theSize = TButton::GetSize();
+
+ // Fill in the background color if necessary
+ EFillStyle theFillStyle = GetCurrentFillStyle();
+
+ switch (theFillStyle) {
+ // Perform a gradient fill (block of color that varies slightly along the y-axis)
+ case EFILLSTYLE_GRADIENT: {
+ // The gradient inverts if the button is currently in the down state
+ bool theInvertGradientFlag = (TButton::GetButtonState() == TButton::EBUTTONSTATE_DOWN) ? true : false;
+ inRenderer->DrawGradientBitmap(QRect(0, 0, theSize.x, theSize.y), GetCurrentBackgroundColor(), theInvertGradientFlag,
+ 0.75);
+ } break;
+
+ // Fill the whole area with a block of solid color
+ case EFILLSTYLE_FLOOD:
+ inRenderer->FillSolidRect(QRect(0, 0, theSize.x, theSize.y), GetCurrentBackgroundColor());
+ break;
+
+ // Do not fill the background at all
+ case EFILLSTYLE_NONE:
+ // No break
+ default:
+ // No filling in of the background
+ break;
+ }
+}
+
+//=============================================================================
+/**
+ * Draws the borders around this button as specified in the border options for
+ * the current state of the button. You can turn border drawing on and off
+ * per side of the button, and you can also specify different colors for each
+ * side of the button.
+ * @param inRenderer renderer to draw to
+ */
+template <typename TButton>
+void CProceduralButton<TButton>::DrawBorder(CRenderer *inRenderer)
+{
+ CPt theSize = TButton::GetSize();
+ SBorderOptions theBorders = CProceduralButton::GetCurrentBorderOptions();
+
+ if (theBorders.m_DrawLeft) {
+ inRenderer->PushPen(m_LeftBorderColor);
+ inRenderer->MoveTo(CPt(0, theSize.y - 1));
+ inRenderer->LineTo(CPt(0, 0));
+ inRenderer->PopPen();
+ }
+
+ if (theBorders.m_DrawTop) {
+ inRenderer->PushPen(m_TopBorderColor);
+ inRenderer->MoveTo(CPt(0, 0));
+ inRenderer->LineTo(CPt(theSize.x - 1, 0));
+ inRenderer->PopPen();
+ }
+
+ if (theBorders.m_DrawRight) {
+ inRenderer->PushPen(m_RightBorderColor);
+ if (!theBorders.m_DrawTop)
+ inRenderer->MoveTo(CPt(theSize.x - 1, 0));
+ else
+ inRenderer->MoveTo(CPt(theSize.x - 1, 1));
+ inRenderer->LineTo(CPt(theSize.x - 1, theSize.y - 1));
+ inRenderer->PopPen();
+ }
+
+ if (theBorders.m_DrawBottom) {
+ inRenderer->PushPen(m_BottomBorderColor);
+ inRenderer->MoveTo(CPt(theSize.x - 1, theSize.y - 1));
+ if (!theBorders.m_DrawLeft)
+ inRenderer->LineTo(CPt(0, theSize.y - 1));
+ else
+ inRenderer->LineTo(CPt(1, theSize.y - 1));
+ inRenderer->PopPen();
+ }
+}
+
+//=============================================================================
+/**
+ * @return the current fill style based upon state (up, down, mouse over, disabled) of the button
+ */
+template <typename TButton>
+typename CProceduralButton<TButton>::EFillStyle
+CProceduralButton<TButton>::GetCurrentFillStyle()
+{
+ // Default to the up state
+ EFillStyle theFillStyle = m_UpFillStyle;
+
+ typename TButton::EButtonState theState = TButton::GetButtonState();
+
+ // If the mouse is over the button, switch to the mouse over style
+ if (TButton::IsMouseOver())
+ theFillStyle = m_OverFillStyle;
+
+ // If the button is currently pressed, this cancels the up and over states, so return the down
+ // style
+ if (theState == TButton::EBUTTONSTATE_DOWN)
+ theFillStyle = m_DownFillStyle;
+
+ // If this button is disabled just return the disabled style (overrides any other states)
+ if (!TButton::IsEnabled())
+ theFillStyle = m_DisabledFillStyle;
+
+ return theFillStyle;
+}
+
+//=============================================================================
+/**
+ * @return the current background color based upon state (up, down, mouse over, disabled) of the
+ * button
+ */
+template <typename TButton>
+::CColor CProceduralButton<TButton>::GetCurrentBackgroundColor()
+{
+ // Default to the up color
+ ::CColor theColor = m_UpColor;
+
+ typename TButton::EButtonState theState = TButton::GetButtonState();
+
+ // If the mouse is over the button, switch to the mouse over color
+ if (TButton::IsMouseOver())
+ theColor = m_OverColor;
+
+ // If the button is currently pressed, this cancels the up and over states, so return the down
+ // color
+ if (theState == TButton::EBUTTONSTATE_DOWN)
+ theColor = m_DownColor;
+
+ // If this button is disabled just return the disabled color (overrides any other states)
+ if (!TButton::IsEnabled())
+ theColor = m_DisabledColor;
+
+ return theColor;
+}
+
+//=============================================================================
+/**
+ * @return the current border drawing options based upon state (up, down, mouse over, disabled) of
+ * the button
+ */
+template <typename TButton>
+typename CProceduralButton<TButton>::SBorderOptions
+CProceduralButton<TButton>::GetCurrentBorderOptions()
+{
+ SBorderOptions theOptions = m_UpBorders;
+ typename TButton::EButtonState theState = TButton::GetButtonState();
+
+ // If the mouse is over the button, switch to the mouse over border options
+ if (TButton::IsMouseOver())
+ theOptions = m_OverBorders;
+
+ // If the button is currently pressed, this cancels the up and over states, so return the over
+ // border options
+ if (theState == TButton::EBUTTONSTATE_DOWN)
+ theOptions = m_DownBorders;
+
+ // If this button is disabled just return the disabled border options (overrides any other
+ // states)
+ if (!TButton::IsEnabled())
+ theOptions = m_DisabledBorders;
+
+ return theOptions;
+}
+
+#endif // INCLUDED_PROCEDURAL_BUTTON_H