summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/salnativewidgets.hxx1
-rw-r--r--include/vcl/status.hxx2
-rw-r--r--include/vcl/toolkit/prgsbar.hxx10
-rw-r--r--include/vcl/weld.hxx9
-rw-r--r--toolkit/source/awt/vclxtoolkit.cxx2
-rw-r--r--vcl/inc/ControlCacheKey.hxx1
-rw-r--r--vcl/inc/salvtables.hxx2
-rw-r--r--vcl/source/app/salvtables.cxx24
-rw-r--r--vcl/source/control/prgsbar.cxx27
-rw-r--r--vcl/source/gdi/FileDefinitionWidgetDraw.cxx2
-rw-r--r--vcl/source/gdi/WidgetDefinitionReader.cxx1
-rw-r--r--vcl/source/window/builder.cxx8
-rw-r--r--vcl/source/window/status.cxx22
-rw-r--r--vcl/unx/gtk3/gtkinst.cxx29
-rw-r--r--vcl/win/gdi/salnativewidgets-luna.cxx33
15 files changed, 152 insertions, 21 deletions
diff --git a/include/vcl/salnativewidgets.hxx b/include/vcl/salnativewidgets.hxx
index 907c3b618f88..aa856a16c35d 100644
--- a/include/vcl/salnativewidgets.hxx
+++ b/include/vcl/salnativewidgets.hxx
@@ -92,6 +92,7 @@ enum class ControlType {
// application but not for the splash
// screen (used in desktop/)
IntroProgress = 132,
+ LevelBar = 133,
// tool tips
Tooltip = 140,
// to draw the implemented theme
diff --git a/include/vcl/status.hxx b/include/vcl/status.hxx
index 4e59481671fd..0c287ddbc1b1 100644
--- a/include/vcl/status.hxx
+++ b/include/vcl/status.hxx
@@ -36,7 +36,7 @@ struct ImplStatusItem;
void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
tools::Long nOffset, tools::Long nPrgsWidth, tools::Long nPrgsHeight,
sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
- const tools::Rectangle& rFramePosSize);
+ const tools::Rectangle& rFramePosSize, ControlType eControlType);
enum class StatusBarItemBits {
diff --git a/include/vcl/toolkit/prgsbar.hxx b/include/vcl/toolkit/prgsbar.hxx
index dd9423178dda..1fcba74fdaba 100644
--- a/include/vcl/toolkit/prgsbar.hxx
+++ b/include/vcl/toolkit/prgsbar.hxx
@@ -52,6 +52,13 @@
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) ProgressBar final : public vcl::Window
{
+public:
+ enum class BarStyle
+ {
+ Progress,
+ Level,
+ };
+
private:
Point maPos;
tools::Long mnPrgsWidth;
@@ -59,6 +66,7 @@ private:
sal_uInt16 mnPercent;
sal_uInt16 mnPercentCount;
bool mbCalcNew;
+ BarStyle meBarStyle;
using Window::ImplInit;
SAL_DLLPRIVATE void ImplInit();
@@ -66,7 +74,7 @@ private:
SAL_DLLPRIVATE void ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16 nNewPerc);
public:
- ProgressBar( vcl::Window* pParent, WinBits nWinBits );
+ ProgressBar( vcl::Window* pParent, WinBits nWinBits, BarStyle eBarStyle );
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
virtual void Resize() override;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index e37bd36f65f4..2d8c4db085d6 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -1714,6 +1714,14 @@ public:
virtual void set_text(const OUString& rText) = 0;
};
+class VCL_DLLPUBLIC LevelBar : virtual public Widget
+{
+public:
+ /// Sets LevelBar fill percentage.
+ /// @param fPercentage bar's fill percentage, [0.0, 100.0]
+ virtual void set_percentage(double fPercentage) = 0;
+};
+
class VCL_DLLPUBLIC Entry : virtual public Widget
{
private:
@@ -2622,6 +2630,7 @@ public:
virtual std::unique_ptr<Entry> weld_entry(const OUString& id) = 0;
virtual std::unique_ptr<Scale> weld_scale(const OUString& id) = 0;
virtual std::unique_ptr<ProgressBar> weld_progress_bar(const OUString& id) = 0;
+ virtual std::unique_ptr<LevelBar> weld_level_bar(const OUString& id) = 0;
virtual std::unique_ptr<Spinner> weld_spinner(const OUString& id) = 0;
virtual std::unique_ptr<Image> weld_image(const OUString& id) = 0;
virtual std::unique_ptr<Calendar> weld_calendar(const OUString& id) = 0;
diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx
index 7f6bd757b914..fc6b7b9df8d9 100644
--- a/toolkit/source/awt/vclxtoolkit.cxx
+++ b/toolkit/source/awt/vclxtoolkit.cxx
@@ -1781,7 +1781,7 @@ vcl::Window* VCLXToolkit::ImplCreateWindow( rtl::Reference<VCLXWindow>* ppNewCom
}
else if (aServiceName == "progressbar")
{
- pNewWindow = VclPtr<ProgressBar>::Create( pParent, nWinBits );
+ pNewWindow = VclPtr<ProgressBar>::Create( pParent, nWinBits, ProgressBar::BarStyle::Progress );
*ppNewComp = new VCLXProgressBar;
}
else if (aServiceName == "filecontrol")
diff --git a/vcl/inc/ControlCacheKey.hxx b/vcl/inc/ControlCacheKey.hxx
index 658d05bc84a2..e422004ca58e 100644
--- a/vcl/inc/ControlCacheKey.hxx
+++ b/vcl/inc/ControlCacheKey.hxx
@@ -55,6 +55,7 @@ public:
case ControlType::Radiobutton:
case ControlType::ListNode:
case ControlType::Slider:
+ case ControlType::LevelBar:
case ControlType::Progress:
// FIXME: these guys have complex state hidden in ImplControlValue
// structs which affects rendering, needs to be a and needs to be
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 8648db8e5143..4074e097a4f4 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -91,6 +91,8 @@ public:
virtual std::unique_ptr<weld::ProgressBar> weld_progress_bar(const OUString& id) override;
+ virtual std::unique_ptr<weld::LevelBar> weld_level_bar(const OUString& id) override;
+
virtual std::unique_ptr<weld::Spinner> weld_spinner(const OUString& id) override;
virtual std::unique_ptr<weld::Image> weld_image(const OUString& id) override;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index ce78cf1e235c..fa9e7fa6d476 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -3302,6 +3302,24 @@ public:
virtual void set_text(const OUString& rText) override { m_xProgressBar->SetText(rText); }
};
+
+class SalInstanceLevelBar : public SalInstanceWidget, public virtual weld::LevelBar
+{
+private:
+ VclPtr<::ProgressBar> m_xLevelBar;
+
+public:
+ SalInstanceLevelBar(::ProgressBar* pLevelBar, SalInstanceBuilder* pBuilder, bool bTakeOwnership)
+ : SalInstanceWidget(pLevelBar, pBuilder, bTakeOwnership)
+ , m_xLevelBar(pLevelBar)
+ {
+ }
+
+ virtual void set_percentage(double fPercentage) override
+ {
+ m_xLevelBar->SetValue(static_cast<sal_uInt16>(fPercentage));
+ }
+};
}
IMPL_LINK_NOARG(SalInstanceCalendar, SelectHdl, ::Calendar*, void)
@@ -7212,6 +7230,12 @@ std::unique_ptr<weld::ProgressBar> SalInstanceBuilder::weld_progress_bar(const O
return pProgress ? std::make_unique<SalInstanceProgressBar>(pProgress, this, false) : nullptr;
}
+std::unique_ptr<weld::LevelBar> SalInstanceBuilder::weld_level_bar(const OUString& id)
+{
+ ::ProgressBar* pLevel = m_xBuilder->get<::ProgressBar>(id);
+ return pLevel ? std::make_unique<SalInstanceLevelBar>(pLevel, this, false) : nullptr;
+}
+
std::unique_ptr<weld::Spinner> SalInstanceBuilder::weld_spinner(const OUString& id)
{
Throbber* pThrobber = m_xBuilder->get<Throbber>(id);
diff --git a/vcl/source/control/prgsbar.cxx b/vcl/source/control/prgsbar.cxx
index 6b7a7007c599..e15c7c055dbe 100644
--- a/vcl/source/control/prgsbar.cxx
+++ b/vcl/source/control/prgsbar.cxx
@@ -39,12 +39,15 @@ void ProgressBar::ImplInit()
ImplInitSettings( true, true, true );
}
-static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits nOrgStyle )
+static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits nOrgStyle, ProgressBar::BarStyle eBarStyle )
{
WinBits nOutStyle = nOrgStyle;
if( pParent && (nOrgStyle & WB_BORDER) != 0 )
{
- if( pParent->IsNativeControlSupported( ControlType::Progress, ControlPart::Entire ) )
+ if (pParent->IsNativeControlSupported(eBarStyle == ProgressBar::BarStyle::Progress
+ ? ControlType::Progress
+ : ControlType::LevelBar,
+ ControlPart::Entire))
nOutStyle &= WB_BORDER;
}
return nOutStyle;
@@ -52,11 +55,12 @@ static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits nOrg
Size ProgressBar::GetOptimalSize() const
{
- return Size(150, 20);
+ return meBarStyle == BarStyle::Progress ? Size(150, 20) : Size(150,10);
}
-ProgressBar::ProgressBar( vcl::Window* pParent, WinBits nWinStyle ) :
- Window( pParent, clearProgressBarBorder( pParent, nWinStyle ) )
+ProgressBar::ProgressBar( vcl::Window* pParent, WinBits nWinStyle, BarStyle eBarStyle ) :
+ Window( pParent, clearProgressBarBorder( pParent, nWinStyle, eBarStyle ) ),
+ meBarStyle(eBarStyle)
{
SetOutputSizePixel( GetOptimalSize() );
ImplInit();
@@ -74,8 +78,10 @@ void ProgressBar::ImplInitSettings( bool bFont,
if ( bBackground )
{
- if( !IsControlBackground() &&
- IsNativeControlSupported( ControlType::Progress, ControlPart::Entire ) )
+ if (!IsControlBackground()
+ && IsNativeControlSupported(meBarStyle == BarStyle::Progress ? ControlType::Progress
+ : ControlType::LevelBar,
+ ControlPart::Entire))
{
if( GetStyle() & WB_BORDER )
SetBorderStyle( WindowBorderStyle::REMOVEBORDER );
@@ -144,9 +150,10 @@ void ProgressBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt1
maPos.setX( (aSize.Width() - nMaxWidth) / 2 );
}
- ::DrawProgress(this, rRenderContext, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, mnPrgsHeight,
- /*nPercent1=*/0, nNewPerc * 100, mnPercentCount,
- tools::Rectangle(Point(), GetSizePixel()));
+ ::DrawProgress(
+ this, rRenderContext, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, mnPrgsHeight,
+ /*nPercent1=*/0, nNewPerc * 100, mnPercentCount, tools::Rectangle(Point(), GetSizePixel()),
+ meBarStyle == BarStyle::Progress ? ControlType::Progress : ControlType::LevelBar);
}
void ProgressBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
diff --git a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
index 442111571dd8..6426491f25d7 100644
--- a/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
+++ b/vcl/source/gdi/FileDefinitionWidgetDraw.cxx
@@ -188,6 +188,7 @@ bool FileDefinitionWidgetDraw::isNativeControlSupported(ControlType eType, Contr
case ControlType::MenuPopup:
return true;
case ControlType::Progress:
+ case ControlType::LevelBar:
return true;
case ControlType::IntroProgress:
return false;
@@ -750,6 +751,7 @@ bool FileDefinitionWidgetDraw::drawNativeControl(ControlType eType, ControlPart
}
break;
case ControlType::Progress:
+ case ControlType::LevelBar:
{
bOK = resolveDefinition(eType, ePart, eState, rValue, nX, nY, nWidth, nHeight);
}
diff --git a/vcl/source/gdi/WidgetDefinitionReader.cxx b/vcl/source/gdi/WidgetDefinitionReader.cxx
index b635c5e3f9b0..a36c62564ea2 100644
--- a/vcl/source/gdi/WidgetDefinitionReader.cxx
+++ b/vcl/source/gdi/WidgetDefinitionReader.cxx
@@ -160,6 +160,7 @@ bool getControlTypeForXmlString(OString const& rString, ControlType& reType)
{ "slider", ControlType::Slider },
{ "fixedline", ControlType::Fixedline },
{ "progress", ControlType::Progress },
+ { "levelbar", ControlType::LevelBar },
{ "tabitem", ControlType::TabItem },
{ "tabheader", ControlType::TabHeader },
{ "tabpane", ControlType::TabPane },
diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx
index 3d9456432164..bc307ba85561 100644
--- a/vcl/source/window/builder.cxx
+++ b/vcl/source/window/builder.cxx
@@ -2025,7 +2025,13 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OUString
{
extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
bVertical = extractOrientation(rMap);
- xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ);
+ xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ, ProgressBar::BarStyle::Progress);
+ }
+ else if (name == "GtkLevelBar")
+ {
+ extractAdjustmentToMap(id, rMap, m_pParserState->m_aScrollAdjustmentMaps);
+ bVertical = extractOrientation(rMap);
+ xWindow = VclPtr<ProgressBar>::Create(pParent, bVertical ? WB_VERT : WB_HORZ, ProgressBar::BarStyle::Level);
}
else if (name == "GtkScrolledWindow")
{
diff --git a/vcl/source/window/status.cxx b/vcl/source/window/status.cxx
index 23f4cfc086bf..fc14762bef7a 100644
--- a/vcl/source/window/status.cxx
+++ b/vcl/source/window/status.cxx
@@ -474,9 +474,9 @@ void StatusBar::ImplDrawItem(vcl::RenderContext& rRenderContext, bool bOffScreen
void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, const Point& rPos,
tools::Long nOffset, tools::Long nPrgsWidth, tools::Long nPrgsHeight,
sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount,
- const tools::Rectangle& rFramePosSize)
+ const tools::Rectangle& rFramePosSize, ControlType eControlType)
{
- if (rRenderContext.IsNativeControlSupported(ControlType::Progress, ControlPart::Entire))
+ if (rRenderContext.IsNativeControlSupported(eControlType, ControlPart::Entire))
{
bool bNeedErase = ImplGetSVData()->maNWFData.mbProgressNeedsErase;
@@ -514,7 +514,7 @@ void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, cons
rRenderContext.IntersectClipRegion(rFramePosSize);
}
- bool bNativeOK = rRenderContext.DrawNativeControl(ControlType::Progress, ControlPart::Entire, aControlRegion,
+ bool bNativeOK = rRenderContext.DrawNativeControl(eControlType, ControlPart::Entire, aControlRegion,
ControlState::ENABLED, aValue, OUString());
if (bNeedErase)
rRenderContext.Pop();
@@ -522,6 +522,18 @@ void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, cons
return;
}
+ if (eControlType == ControlType::LevelBar)
+ {
+ if (nPercent2 < 2500)
+ rRenderContext.SetFillColor({ 0xFF0000 });
+ else if (nPercent2 < 5000)
+ rRenderContext.SetFillColor({ 0xFFFF00 });
+ else if (nPercent2 < 7500)
+ rRenderContext.SetFillColor({ 0x0000FF });
+ else
+ rRenderContext.SetFillColor({ 0x00FF00 });
+ }
+
// precompute values
sal_uInt16 nPerc1 = nPercent1 / nPercentCount;
sal_uInt16 nPerc2 = nPercent2 / nPercentCount;
@@ -570,7 +582,7 @@ void DrawProgress(vcl::Window* pWindow, vcl::RenderContext& rRenderContext, cons
while (nPerc1 < nPerc2);
// if greater than 100%, set rectangle to blink
- if (nPercent2 > 10000)
+ if (nPercent2 > 10000 && eControlType == ControlType::Progress)
{
// define on/off status
if (((nPercent2 / nPercentCount) & 0x01) == (nPercentCount & 0x01))
@@ -603,7 +615,7 @@ void StatusBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16
nPrgsHeight = maPrgsFrameRect.GetHeight();
}
DrawProgress(this, rRenderContext, aPos, mnPrgsSize / 2, mnPrgsSize, nPrgsHeight,
- 0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect);
+ 0, nPercent2 * 100, mnPercentCount, maPrgsFrameRect, ControlType::Progress);
}
void StatusBar::ImplCalcProgressRect()
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index aaddf24bce32..22b0e0273381 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -12843,6 +12843,25 @@ public:
}
};
+class GtkInstanceLevelBar : public GtkInstanceWidget, public virtual weld::LevelBar
+{
+private:
+ GtkLevelBar* m_pLevelBar;
+
+public:
+ GtkInstanceLevelBar(GtkLevelBar* pLevelBar, GtkInstanceBuilder* pBuilder,
+ bool bTakeOwnership)
+ : GtkInstanceWidget(GTK_WIDGET(pLevelBar), pBuilder, bTakeOwnership)
+ , m_pLevelBar(pLevelBar)
+ {
+ }
+
+ virtual void set_percentage(double fPercentage) override
+ {
+ gtk_level_bar_set_value(m_pLevelBar, fPercentage / 100.0);
+ }
+};
+
class GtkInstanceSpinner : public GtkInstanceWidget, public virtual weld::Spinner
{
private:
@@ -24341,6 +24360,16 @@ public:
return std::make_unique<GtkInstanceProgressBar>(pProgressBar, this, false);
}
+ virtual std::unique_ptr<weld::LevelBar> weld_level_bar(const OUString& id) override
+ {
+ GtkLevelBar* pLevelBar = GTK_LEVEL_BAR(gtk_builder_get_object(
+ m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr()));
+ if (!pLevelBar)
+ return nullptr;
+ auto_add_parentless_widgets_to_container(GTK_WIDGET(pLevelBar));
+ return std::make_unique<GtkInstanceLevelBar>(pLevelBar, this, false);
+ }
+
virtual std::unique_ptr<weld::Spinner> weld_spinner(const OUString &id) override
{
GtkSpinner* pSpinner = GTK_SPINNER(gtk_builder_get_object(m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr()));
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx b/vcl/win/gdi/salnativewidgets-luna.cxx
index 0dd5b2dd7442..c5a368c8c52c 100644
--- a/vcl/win/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/gdi/salnativewidgets-luna.cxx
@@ -190,6 +190,7 @@ bool WinSalGraphics::isNativeControlSupported( ControlType nType, ControlPart nP
}
break;
case ControlType::Progress:
+ case ControlType::LevelBar:
if( nPart == ControlPart::Entire )
hTheme = getThemeHandle(mhWnd, L"Progress", mWinSalGraphicsImplBase);
break;
@@ -1003,12 +1004,19 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
}
}
- if( nType == ControlType::Progress )
+ if( nType == ControlType::Progress || nType == ControlType::LevelBar )
{
if( nPart != ControlPart::Entire )
return false;
- if( ! ImplDrawTheme( hTheme, hDC, PP_BAR, iState, rc, aCaption) )
+ int nPartIdBackground = PP_BAR;
+ if( nType == ControlType::LevelBar )
+ {
+ nPartIdBackground = PP_TRANSPARENTBAR;
+ iState = PBBS_PARTIAL;
+ }
+
+ if( ! ImplDrawTheme( hTheme, hDC, nPartIdBackground, iState, rc, aCaption) )
return false;
RECT aProgressRect = rc;
if( GetThemeBackgroundContentRect( hTheme, hDC, PP_BAR, iState, &rc, &aProgressRect) != S_OK )
@@ -1022,6 +1030,26 @@ static bool ImplDrawNativeControl( HDC hDC, HTHEME hTheme, RECT rc,
else
aProgressRect.right = aProgressRect.left + nProgressWidth;
+ if (nType == ControlType::LevelBar)
+ {
+ const auto nPercentage
+ = aValue.getNumericVal() * 100 / std::max(LONG{ 1 }, (rc.right - rc.left));
+
+ COLORREF aBrushColor{};
+ if (nPercentage < 25)
+ aBrushColor = RGB(255, 0, 0);
+ else if (nPercentage < 50)
+ aBrushColor = RGB(255, 255, 0);
+ else if (nPercentage < 75)
+ aBrushColor = RGB(0, 0, 255);
+ else
+ aBrushColor = RGB(0, 255, 0);
+
+ ScopedHBRUSH hBrush(CreateSolidBrush(aBrushColor));
+ FillRect(hDC, &aProgressRect, hBrush.get());
+ return true;
+ }
+
return ImplDrawTheme( hTheme, hDC, PP_CHUNK, iState, aProgressRect, aCaption );
}
@@ -1272,6 +1300,7 @@ bool WinSalGraphics::drawNativeControl( ControlType nType,
}
break;
case ControlType::Progress:
+ case ControlType::LevelBar:
if( nPart == ControlPart::Entire )
hTheme = getThemeHandle(mhWnd, L"Progress", mWinSalGraphicsImplBase);
break;