View Issue Details

IDProjectCategoryView StatusLast Update
0017522ScribusUser Interfacepublic2025-10-27 18:58
Reporternitramr Assigned Tonitramr  
PrioritynormalSeverityfeatureReproducibilityN/A
Status assignedResolutionopen 
PlatformDesktop PCOSUbuntuOS Version24.10 64-bit
Product Version1.7.1.svn 
Target Version1.7 milestone 
Summary0017522: New Color Slider widget
DescriptionI made a new color slider that has the render logic inside the widget.
In short term, it will replace the existing ScColorSlider.

Supported Color Modes:
- RGB
- RGB Web
- CMYK
- Lab
- HLC
- HSV <- new
- Shade <- new
- Alpha <- new

The patch implements the new color slider in color picker for alpha and shade settings.
To replace the color slider in cmykfw widget, it takes more time.
TagsNo tags attached.
Attached Files
color_slider.zip (5,944 bytes)
colorslider_2025-05-13_01.patch (10,348 bytes)   
Index: scribus/CMakeLists_Sources.txt
===================================================================
--- scribus/CMakeLists_Sources.txt	(Revision 26867)
+++ scribus/CMakeLists_Sources.txt	(Arbeitskopie)
@@ -562,6 +562,7 @@
 	ui/docks/dock_centralwidget.cpp
 	ui/docks/dock_panelbase.cpp
 	ui/widgets/color_button.cpp
+	ui/widgets/color_slider.cpp
 	ui/widgets/combo_blendmode.cpp
 	ui/widgets/combo_linestyle.cpp
 	ui/widgets/dropdown_button.cpp
Index: scribus/ui/colorpicker/colorpicker_color.cpp
===================================================================
--- scribus/ui/colorpicker/colorpicker_color.cpp	(Revision 26867)
+++ scribus/ui/colorpicker/colorpicker_color.cpp	(Arbeitskopie)
@@ -26,6 +26,9 @@
 
 	languageChange();
 
+	sliderAlpha->setMode(ColorSlider::Opacity);
+	sliderShade->setMode(ColorSlider::Shade);
+
 	connectSlots();
 	connect(sectionSwatches,    &SectionContainer::sizeChanged,				this, &ColorPickerColor::updateSize);
 }
@@ -34,7 +37,9 @@
 {
 	connect(swatches,			&ColorPickerColorSwatches::colorChanged,	this, &ColorPickerColor::updateColorFromSwatches);	
 	connect(numberShade,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorShade);
+	connect(sliderShade,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorShade);
 	connect(numberAlpha,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
+	connect(sliderAlpha,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
 }
 
 void ColorPickerColor::disconnectSlots()
@@ -41,7 +46,9 @@
 {
 	disconnect(swatches,		&ColorPickerColorSwatches::colorChanged,	this, &ColorPickerColor::updateColorFromSwatches);
 	disconnect(numberShade,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorShade);
+	disconnect(sliderShade,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorShade);
 	disconnect(numberAlpha,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
+	disconnect(sliderAlpha,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
 }
 
 /* ********************************************************************************* *
@@ -73,8 +80,10 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(false);
 		labelShade->setVisible(false);
+		sliderShade->setVisible(false);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Text:
 	case Context::TextBackground:
@@ -82,22 +91,28 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Fill:
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Line:
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::FillMask:
 	case Context::LineMask:
@@ -104,8 +119,10 @@
 		sectionSwatches->setVisible(false);
 		numberShade->setVisible(false);
 		labelShade->setVisible(false);
+		sliderShade->setVisible(false);
 		numberAlpha->setVisible(true);
 		labelAlpha->setVisible(true);
+		sliderAlpha->setVisible(true);
 		isMask = true;
 		break;
 	case Context::DropShadow:
@@ -112,8 +129,10 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	}
 
@@ -183,12 +202,19 @@
 void ColorPickerColor::setDoc(ScribusDoc *doc)
 {
 	m_doc = doc;
+	sliderAlpha->setDoc(m_doc);
+	sliderShade->setDoc(m_doc);
 }
 
 void ColorPickerColor::setColorData(const CPColorData& color)
 {
+	if (!m_doc)
+		return;
+
 	m_color = color;
 
+	bool hasColor = m_color.Name != CommonStrings::tr_NoneColor;
+
 	// update UI + controls
 	QSignalBlocker sigSwatches(swatches);
 	swatches->setCurrentColor(m_color.Name);
@@ -195,12 +221,20 @@
 
 	QSignalBlocker sigShade(numberShade);
 	numberShade->setValue(m_color.Shade);
-	numberShade->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
+	numberShade->setEnabled(hasColor);
 
 	QSignalBlocker sigAlpha(numberAlpha);
 	numberAlpha->setValue(qRound(100 - (m_color.Opacity * 100)));
-	numberAlpha->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
+	numberAlpha->setEnabled(hasColor);
 
+	QSignalBlocker sigAlphaSlider(sliderAlpha);
+	sliderAlpha->setEnabled(hasColor);
+	sliderAlpha->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
+	QSignalBlocker sigShadeSlider(sliderShade);
+	sliderShade->setEnabled(hasColor);
+	sliderShade->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
 }
 
 void ColorPickerColor::languageChange()
@@ -211,14 +245,33 @@
 void ColorPickerColor::updateColorFromSwatches()
 {
 	m_color.Name = swatches->currentColor();
-	numberShade->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
-	numberAlpha->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
 
+	bool hasColor = m_color.Name != CommonStrings::tr_NoneColor;
+
+	numberShade->setEnabled(hasColor);
+	sliderShade->setEnabled(hasColor);
+	sliderShade->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+	numberAlpha->setEnabled(hasColor);
+	sliderAlpha->setEnabled(hasColor);
+	sliderAlpha->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
 	updateColor();
 }
 
 void ColorPickerColor::updateColorShade()
 {
+	QObject* obj = sender();
+	if( obj == sliderShade )
+	{
+		QSignalBlocker sigBlocker(numberShade);
+		numberShade->setValue(sliderShade->value());
+	}
+	else if( obj == numberShade )
+	{
+		QSignalBlocker sigBlocker(sliderShade);
+		sliderShade->setValue(numberShade->value());
+	}
+
 	m_color.Shade = numberShade->value();
 	updateColor();
 }
@@ -225,6 +278,18 @@
 
 void ColorPickerColor::updateColorAlpha()
 {
+	QObject* obj = sender();
+	if( obj == sliderAlpha )
+	{
+		QSignalBlocker sigBlocker(numberAlpha);
+		numberAlpha->setValue(sliderAlpha->value());
+	}
+	else if( obj == numberAlpha )
+	{
+		QSignalBlocker sigBlocker(sliderAlpha);
+		sliderAlpha->setValue(numberAlpha->value());
+	}
+
 	m_color.Opacity = (100 - numberAlpha->value()) / 100.0;
 	updateColor();
 }
@@ -242,5 +307,3 @@
 	resize(w, sizeHint().height());
 	emit sizeChanged();
 }
-
-
Index: scribus/ui/colorpicker/colorpicker_color.ui
===================================================================
--- scribus/ui/colorpicker/colorpicker_color.ui	(Revision 26867)
+++ scribus/ui/colorpicker/colorpicker_color.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>300</width>
-    <height>122</height>
+    <height>112</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -46,8 +46,28 @@
      <property name="spacing">
       <number>4</number>
      </property>
-     <item row="1" column="2">
-      <widget class="ScrSpinBox" name="numberAlpha">
+     <item row="0" column="1">
+      <widget class="ColorSlider" name="sliderShade">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="tickPosition">
+        <enum>QSlider::TickPosition::TicksAbove</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="ColorSlider" name="sliderAlpha">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="tickPosition">
+        <enum>QSlider::TickPosition::TicksAbove</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="ScrSpinBox" name="numberShade">
        <property name="suffix">
         <string> %</string>
        </property>
@@ -59,28 +79,28 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
+     <item row="1" column="0">
       <widget class="QLabel" name="labelAlpha">
        <property name="text">
         <string>Opacity:</string>
        </property>
        <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
+     <item row="0" column="0">
       <widget class="QLabel" name="labelShade">
        <property name="text">
         <string>Shade:</string>
        </property>
        <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
        </property>
       </widget>
      </item>
-     <item row="0" column="2">
-      <widget class="ScrSpinBox" name="numberShade">
+     <item row="1" column="2">
+      <widget class="ScrSpinBox" name="numberAlpha">
        <property name="suffix">
         <string> %</string>
        </property>
@@ -92,19 +112,6 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="0">
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
     </layout>
    </item>
    <item>
@@ -136,6 +143,11 @@
    <header>ui/colorpicker/colorpicker_color_swatches.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>ColorSlider</class>
+   <extends>QSlider</extends>
+   <header>ui/widgets/color_slider.h</header>
+  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>numberShade</tabstop>
colorslider_2025-05-13_01.patch (10,348 bytes)   
preview.png (18,821 bytes)   
preview.png (18,821 bytes)   
PatchYes

Relationships

duplicate of 0006434 assignedfschmid Implement sliders as control for values such as opacity 
child of 0017540 new Metabug: UI fixes for the release of Scribus 1.8 

Activities

cbradney

2025-05-13 21:06

administrator   ~0052524

Not sure what's different on Mac. No numbers on the slider.. slider is higher
image.png (20,951 bytes)   
image.png (20,951 bytes)   

nitramr

2025-10-25 14:16

developer   ~0053120

@cbradney I fixed the style issue.

The new patch requires the ScribusProxyStyle class from this patch:
https://bugs.scribus.net/view.php?id=17571
colorslider_2025-10-25_01.patch (21,671 bytes)   
Index: scribus/CMakeLists_Sources.txt
===================================================================
--- scribus/CMakeLists_Sources.txt	(Revision 27094)
+++ scribus/CMakeLists_Sources.txt	(Arbeitskopie)
@@ -565,7 +565,8 @@
 	ui/delegates/sclistitemdelegate.cpp
 	ui/docks/dock_centralwidget.cpp
 	ui/docks/dock_panelbase.cpp
	ui/factories/scribusproxystyle.cpp
	ui/widgets/buttongroup.cpp
 	ui/widgets/color_button.cpp
+	ui/widgets/color_slider.cpp
 	ui/widgets/combo_blendmode.cpp
 	ui/widgets/combo_linestyle.cpp
 	ui/widgets/dropdown_button.cpp
Index: scribus/ui/colorpicker/colorpicker_color.cpp
===================================================================
--- scribus/ui/colorpicker/colorpicker_color.cpp	(Revision 27094)
+++ scribus/ui/colorpicker/colorpicker_color.cpp	(Arbeitskopie)
@@ -26,6 +26,9 @@
 
 	languageChange();
 
+	sliderAlpha->setMode(ColorSlider::Opacity);
+	sliderShade->setMode(ColorSlider::Shade);
+
 	connectSlots();
 	connect(sectionSwatches,    &SectionContainer::sizeChanged,				this, &ColorPickerColor::updateSize);
 }
@@ -34,7 +37,9 @@
 {
 	connect(swatches,			&ColorPickerColorSwatches::colorChanged,	this, &ColorPickerColor::updateColorFromSwatches);	
 	connect(numberShade,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorShade);
+	connect(sliderShade,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorShade);
 	connect(numberAlpha,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
+	connect(sliderAlpha,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
 }
 
 void ColorPickerColor::disconnectSlots()
@@ -41,7 +46,9 @@
 {
 	disconnect(swatches,		&ColorPickerColorSwatches::colorChanged,	this, &ColorPickerColor::updateColorFromSwatches);
 	disconnect(numberShade,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorShade);
+	disconnect(sliderShade,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorShade);
 	disconnect(numberAlpha,		&ScrSpinBox::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
+	disconnect(sliderAlpha,		&ColorSlider::valueChanged,					this, &ColorPickerColor::updateColorAlpha);
 }
 
 /* ********************************************************************************* *
@@ -73,8 +80,10 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(false);
 		labelShade->setVisible(false);
+		sliderShade->setVisible(false);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Text:
 	case Context::TextBackground:
@@ -82,22 +91,28 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Fill:
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::Line:
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	case Context::FillMask:
 	case Context::LineMask:
@@ -104,8 +119,10 @@
 		sectionSwatches->setVisible(false);
 		numberShade->setVisible(false);
 		labelShade->setVisible(false);
+		sliderShade->setVisible(false);
 		numberAlpha->setVisible(true);
 		labelAlpha->setVisible(true);
+		sliderAlpha->setVisible(true);
 		isMask = true;
 		break;
 	case Context::DropShadow:
@@ -112,8 +129,10 @@
 		sectionSwatches->setVisible(true);
 		numberShade->setVisible(true);
 		labelShade->setVisible(true);
+		sliderShade->setVisible(true);
 		numberAlpha->setVisible(false);
 		labelAlpha->setVisible(false);
+		sliderAlpha->setVisible(false);
 		break;
 	}
 
@@ -183,12 +202,19 @@
 void ColorPickerColor::setDoc(ScribusDoc *doc)
 {
 	m_doc = doc;
+	sliderAlpha->setDoc(m_doc);
+	sliderShade->setDoc(m_doc);
 }
 
 void ColorPickerColor::setColorData(const CPColorData& color)
 {
+	if (!m_doc)
+		return;
+
 	m_color = color;
 
+	bool hasColor = m_color.Name != CommonStrings::tr_NoneColor;
+
 	// update UI + controls
 	QSignalBlocker sigSwatches(swatches);
 	swatches->setCurrentColor(m_color.Name);
@@ -195,12 +221,20 @@
 
 	QSignalBlocker sigShade(numberShade);
 	numberShade->setValue(m_color.Shade);
-	numberShade->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
+	numberShade->setEnabled(hasColor);
 
 	QSignalBlocker sigAlpha(numberAlpha);
 	numberAlpha->setValue(qRound(100 - (m_color.Opacity * 100)));
-	numberAlpha->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
+	numberAlpha->setEnabled(hasColor);
 
+	QSignalBlocker sigAlphaSlider(sliderAlpha);
+	sliderAlpha->setEnabled(hasColor);
+	sliderAlpha->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
+	QSignalBlocker sigShadeSlider(sliderShade);
+	sliderShade->setEnabled(hasColor);
+	sliderShade->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
 }
 
 void ColorPickerColor::languageChange()
@@ -211,14 +245,33 @@
 void ColorPickerColor::updateColorFromSwatches()
 {
 	m_color.Name = swatches->currentColor();
-	numberShade->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
-	numberAlpha->setEnabled(m_color.Name != CommonStrings::tr_NoneColor);
 
+	bool hasColor = m_color.Name != CommonStrings::tr_NoneColor;
+
+	numberShade->setEnabled(hasColor);
+	sliderShade->setEnabled(hasColor);
+	sliderShade->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+	numberAlpha->setEnabled(hasColor);
+	sliderAlpha->setEnabled(hasColor);
+	sliderAlpha->setValues(m_color.Name, numberAlpha->value(), numberShade->value());
+
 	updateColor();
 }
 
 void ColorPickerColor::updateColorShade()
 {
+	QObject* obj = sender();
+	if( obj == sliderShade )
+	{
+		QSignalBlocker sigBlocker(numberShade);
+		numberShade->setValue(sliderShade->value());
+	}
+	else if( obj == numberShade )
+	{
+		QSignalBlocker sigBlocker(sliderShade);
+		sliderShade->setValue(numberShade->value());
+	}
+
 	m_color.Shade = numberShade->value();
 	updateColor();
 }
@@ -225,6 +278,18 @@
 
 void ColorPickerColor::updateColorAlpha()
 {
+	QObject* obj = sender();
+	if( obj == sliderAlpha )
+	{
+		QSignalBlocker sigBlocker(numberAlpha);
+		numberAlpha->setValue(sliderAlpha->value());
+	}
+	else if( obj == numberAlpha )
+	{
+		QSignalBlocker sigBlocker(sliderAlpha);
+		sliderAlpha->setValue(numberAlpha->value());
+	}
+
 	m_color.Opacity = (100 - numberAlpha->value()) / 100.0;
 	updateColor();
 }
@@ -242,5 +307,3 @@
 	resize(w, sizeHint().height());
 	emit sizeChanged();
 }
-
-
Index: scribus/ui/colorpicker/colorpicker_color.ui
===================================================================
--- scribus/ui/colorpicker/colorpicker_color.ui	(Revision 27094)
+++ scribus/ui/colorpicker/colorpicker_color.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>300</width>
-    <height>122</height>
+    <height>112</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -46,8 +46,28 @@
      <property name="spacing">
       <number>4</number>
      </property>
-     <item row="1" column="2">
-      <widget class="ScrSpinBox" name="numberAlpha">
+     <item row="0" column="1">
+      <widget class="ColorSlider" name="sliderShade">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="tickPosition">
+        <enum>QSlider::TickPosition::TicksAbove</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="ColorSlider" name="sliderAlpha">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="tickPosition">
+        <enum>QSlider::TickPosition::TicksAbove</enum>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="ScrSpinBox" name="numberShade">
        <property name="suffix">
         <string> %</string>
        </property>
@@ -59,28 +79,28 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="1">
+     <item row="1" column="0">
       <widget class="QLabel" name="labelAlpha">
        <property name="text">
         <string>Opacity:</string>
        </property>
        <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
        </property>
       </widget>
      </item>
-     <item row="0" column="1">
+     <item row="0" column="0">
       <widget class="QLabel" name="labelShade">
        <property name="text">
         <string>Shade:</string>
        </property>
        <property name="alignment">
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        <set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
        </property>
       </widget>
      </item>
-     <item row="0" column="2">
-      <widget class="ScrSpinBox" name="numberShade">
+     <item row="1" column="2">
+      <widget class="ScrSpinBox" name="numberAlpha">
        <property name="suffix">
         <string> %</string>
        </property>
@@ -92,19 +112,6 @@
        </property>
       </widget>
      </item>
-     <item row="1" column="0">
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
     </layout>
    </item>
    <item>
@@ -136,6 +143,11 @@
    <header>ui/colorpicker/colorpicker_color_swatches.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>ColorSlider</class>
+   <extends>QSlider</extends>
+   <header>ui/widgets/color_slider.h</header>
+  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>numberShade</tabstop>
Index: scribus/ui/dasheditor.cpp
===================================================================
--- scribus/ui/dasheditor.cpp	(Revision 27094)
+++ scribus/ui/dasheditor.cpp	(Arbeitskopie)
@@ -55,7 +55,6 @@
  *
  * ********************************************************************************* */
 
-const int RADIUS = 6;
 const double HAIRLINE = 0.001;
 
 DashPreview::DashPreview(QWidget *pa) : QFrame(pa)
Index: scribus/ui/factories/scribusproxystyle.cpp
===================================================================
--- scribus/ui/factories/scribusproxystyle.cpp	(Revision 27094)
+++ scribus/ui/factories/scribusproxystyle.cpp	(Arbeitskopie)
@@ -16,6 +16,8 @@
 #include "prefsmanager.h"
 #include "scribus.h"
 #include "ui/widgets/buttongroup.h"
+#include "ui/widgets/color_slider.h"
+#include "util_gui.h"
 
 // https://doc.qt.io/qt-6/qstyle.html#standardPalette
 QPalette createLightPalette()
@@ -32,7 +34,7 @@
 
 QPalette createDarkPalette()
 {
-	QPalette darkPalette/*(QColor(53, 53, 53))*/;
+	QPalette darkPalette;
 	darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
 	darkPalette.setColor(QPalette::WindowText, Qt::white);
 	darkPalette.setColor(QPalette::Base, QColor(42, 42, 42));
@@ -65,15 +67,17 @@
 {
 	QRect rect = QProxyStyle::subControlRect(cc, opt, sc, widget);
 
-	if (cc == CC_ToolButton)
+	switch (cc)
 	{
-		const ToolButton *tb = qobject_cast<const ToolButton*>(widget);
-		if (!tb)
+	case QStyle::ComplexControl::CC_ToolButton:
+	{
+		const ToolButton *wdg = qobject_cast<const ToolButton *>(widget);
+		if (!wdg)
 			return rect;
 
-		if (const QStyleOptionToolButton *button = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
+		if (const QStyleOptionToolButton *styleOption = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
 		{
-			switch (tb->position())
+			switch (wdg->position())
 			{
 			case ToolButton::Left:
 				rect.adjust(0, 0, rect.width(), 0);
@@ -89,30 +93,92 @@
 				break;
 			}
 
-			return visualRect(button->direction, button->rect, rect);
+			return visualRect(styleOption->direction, styleOption->rect, rect);
 		}
 	}
+	break;
+	case QStyle::ComplexControl::CC_Slider:
+	{
+		const ColorSlider *wdg = qobject_cast<const ColorSlider *>(widget);
+		if (!wdg)
+			return rect;
+
+		if (const QStyleOptionSlider *styleOption = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+		{
+			QRect ret;
+			bool horizontal = styleOption->orientation == Qt::Horizontal;
+			int thickness = RADIUS * 2;
+			int center = (horizontal) ? (styleOption->rect.height() - thickness) / 2 : (styleOption->rect.width() - thickness) / 2;
+			int sliderOffset = (styleOption->tickPosition != QSlider::NoTicks) ? thickness : center;
+
+			switch (sc)
+			{
+			case SC_SliderHandle:
+			{
+				int len = thickness + 2; //proxy()->pixelMetric(PM_SliderLength, styleOption, widget);
+				int sliderPos = sliderPositionFromValue(styleOption->minimum, styleOption->maximum, styleOption->sliderPosition, (horizontal ? styleOption->rect.width() : styleOption->rect.height()) - len, styleOption->upsideDown);
+
+				if (horizontal)
+					ret.setRect(styleOption->rect.x() + sliderPos, styleOption->rect.y() + sliderOffset, len, thickness);
+				else
+					ret.setRect(styleOption->rect.x() + 1, styleOption->rect.y() + sliderPos, thickness, len);
+
+				break;
+			}
+			case SC_SliderGroove:
+				if (horizontal)
+					ret.setRect(styleOption->rect.x(), styleOption->rect.y() + sliderOffset + 1, styleOption->rect.width(), thickness - 3);
+				else
+					ret.setRect(styleOption->rect.x() + 2, styleOption->rect.y(), thickness - 3, styleOption->rect.height());
+
+				break;
+			case SC_SliderTickmarks:
+			{
+				int tickOffset = (styleOption->tickPosition != QSlider::NoTicks) ? thickness : 0;
+
+				if (styleOption->tickPosition != QSlider::NoTicks)
+				{
+					if (horizontal)
+						ret.setRect(styleOption->rect.x() + 1, styleOption->rect.y(), styleOption->rect.width() - 3, thickness);
+					else
+						ret.setRect(styleOption->rect.x() + tickOffset, styleOption->rect.y() + 1, thickness, styleOption->rect.height() - 3);
+				}
+				break;
+			}
+			default:
+				break;
+			}
+
+			return visualRect(styleOption->direction, styleOption->rect, ret);
+		}
+	}
+	break;
+	default:
+		break;
+	}
 
 	return rect;
 
 }
 
-void ScribusProxyStyle::drawControl(ControlElement el, const QStyleOption *opt, QPainter *painter, const QWidget *widget) const
+void ScribusProxyStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *painter, const QWidget *widget) const
 {
-	if (el == CE_ToolButtonLabel)
+	switch (ce)
+	{
+	case QStyle::ControlElement::CE_ToolButtonLabel:
 	{
 		QStyleOptionToolButton styleOption = *static_cast<const QStyleOptionToolButton *>(opt);
-		const ToolButton *tb = qobject_cast<const ToolButton*>(widget);
+		const ToolButton *wdg = qobject_cast<const ToolButton*>(widget);
 
-		if (!tb)
-			return QProxyStyle::drawControl(el, opt, painter, widget);
+		if (!wdg)
+			return QProxyStyle::drawControl(ce, opt, painter, widget);
 
 		QRect rect = styleOption.rect;
 		int t = widget->rect().top() + 4;
 		int b = widget->rect().bottom() - 4;
 		int r = widget->rect().right();
 
-		switch (tb->position())
+		switch (wdg->position())
 		{
 		case ToolButton::Right:
 			styleOption.rect.adjust(0, 0, rect.width() / 2, 0);
@@ -132,10 +198,113 @@
 			break;
 		}
 
-		return QProxyStyle::drawControl(el, &styleOption, painter, widget);
+		return QProxyStyle::drawControl(ce, &styleOption, painter, widget);
+	}
+	break;
+	default:
+		break;
 	}
 
-	return QProxyStyle::drawControl(el, opt, painter, widget);
+	return QProxyStyle::drawControl(ce, opt, painter, widget);
+}
+
+void ScribusProxyStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *painter, const QWidget *widget) const
+{
+	switch (cc)
+	{
+	case QStyle::ComplexControl::CC_Slider:
+	{
+		const ColorSlider *wdg = qobject_cast<const ColorSlider*>(widget);
+
+		if (!wdg)
+			return QProxyStyle::drawComplexControl(cc, opt, painter, widget);
+
+		if (const QStyleOptionSlider *styleOption = qstyleoption_cast<const QStyleOptionSlider *>(opt))
+		{
+			painter->save();
+			painter->setRenderHint(QPainter::Antialiasing, true);
+
+			QRect groove = subControlRect(CC_Slider, styleOption, SC_SliderGroove, widget);
+			QRect handle = subControlRect(CC_Slider, styleOption, SC_SliderHandle, widget);
+			QRect tickmarks = subControlRect(CC_Slider, styleOption, SC_SliderTickmarks, widget);
+
+			// Draw Slider
+			if ((styleOption->subControls & SC_SliderGroove) && groove.isValid())
+			{
+				double radius = (styleOption->orientation == Qt::Horizontal) ? groove.height() / 2 + 0.5 : groove.width() / 2 + 0.5;
+
+				QPainterPath border;
+				border.addRoundedRect(groove.toRectF().adjusted(0.5, 0.5, -0.5, -0.5), radius, radius);
+
+				// Draw Slider Gradients
+				painter->setClipPath(border);
+				if (wdg->m_background.isNull() || !widget->isEnabled())
+					painter->fillRect(groove, widget->palette().color(QPalette::Window));
+				else
+				{
+					renderCheckerPattern(painter, groove);
+					painter->drawImage(groove, wdg->m_background);
+				}
+				painter->setClipping(false);
+
+				// Draw Slider Border
+				painter->setPen(widget->palette().color(QPalette::Mid));
+				painter->setBrush(Qt::NoBrush);
+				painter->drawPath(border);
+				painter->setPen(Qt::NoPen);
+
+			}
+
+			// Draw Handle
+			if ((styleOption->subControls & SC_SliderHandle) && handle.isValid())
+			{
+				drawCircularHandle(painter, handle.center() + QPointF(0.5, 0.5), RADIUS * 2, Qt::NoBrush, widget->isEnabled());
+			}
+
+			// Draw Tickmarks
+			if ((styleOption->subControls & SC_SliderTickmarks) && tickmarks.isValid() && styleOption->tickInterval > 0)
+			{
+				QFont font = widget->font();
+				font.setPixelSize(8);
+				painter->setFont(font);
+
+				if (styleOption->orientation == Qt::Horizontal)
+				{
+					double ratio = double(tickmarks.width() - (2 * RADIUS)) / double(styleOption->tickInterval);
+
+					for (int x = 0; x <= styleOption->tickInterval; x++)
+					{
+						QRect tick(double(x) * ratio + RADIUS + 1, tickmarks.bottom() - 3, 1, 2);
+						QString label = QString::number((x * styleOption->maximum / styleOption->tickInterval) - abs(styleOption->minimum));
+						int offset = QFontMetrics(painter->font()).size(Qt::TextSingleLine, label).width() / 2;
+
+						painter->setPen(widget->palette().color(QPalette::WindowText));
+						painter->drawText(qBound(0, tick.left() - offset, tickmarks.width()), tickmarks.bottom() - 4, label);
+						painter->fillRect(tick, widget->palette().color(QPalette::WindowText));
+					}
+				}
+				else
+				{
+					double ratio = double(tickmarks.height() - (2 * RADIUS)) / double(styleOption->tickInterval);
+
+					for (int y = 0; y <= styleOption->tickInterval; y++)
+					{
+						QRect tick(tickmarks.left() + 2, double(y) * ratio + RADIUS + 1, 2, 1);
+						painter->fillRect(tick, widget->palette().color(QPalette::WindowText));
+					}
+				}
+			}
+
+			painter->restore();
+			return;
+		}
+	}
+	break;
+	default:
+		break;
+	}
+
+	QProxyStyle::drawComplexControl(cc, opt, painter, widget);
 }
 
 bool ScribusProxyStyle::eventFilter(QObject *object, QEvent *event)
Index: scribus/ui/factories/scribusproxystyle.h
===================================================================
--- scribus/ui/factories/scribusproxystyle.h	(Revision 27094)
+++ scribus/ui/factories/scribusproxystyle.h	(Arbeitskopie)
@@ -21,7 +21,9 @@
 	static ScribusProxyStyle* instance();
 
 	QRect subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QStyle::SubControl sc, const QWidget *widget = nullptr) const override;
-	void drawControl(QStyle::ControlElement el, const QStyleOption *opt, QPainter *painter, const QWidget *widget = nullptr) const override;
+	void drawControl(QStyle::ControlElement ce, const QStyleOption *opt, QPainter *painter, const QWidget *widget = nullptr) const override;
+	void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *painter, const QWidget *widget) const override;
+
 
 protected:
 	bool eventFilter(QObject *object, QEvent *event) override;
Index: scribus/ui/gradientpreview.cpp
===================================================================
--- scribus/ui/gradientpreview.cpp	(Revision 27094)
+++ scribus/ui/gradientpreview.cpp	(Arbeitskopie)
@@ -29,7 +29,6 @@
 #include "gradientpreview.h"
 #include "util_gui.h"
 
-const int RADIUS = 6;
 const int GRADIENT_HEIGHT = 20;
 
 /* ********************************************************************************* *
Index: scribus/util_gui.h
===================================================================
--- scribus/util_gui.h	(Revision 27094)
+++ scribus/util_gui.h	(Arbeitskopie)
@@ -9,6 +9,8 @@
 class VColorStop;
 class ScPattern;
 
+const int RADIUS = 6;
+
 void SCRIBUS_API drawCircularHandle(QPainter * painter, QPointF center, qreal width, QBrush background, bool isEnabled = true);
 void SCRIBUS_API drawPointerHandle(QPainter * painter, QPointF pointer, qreal width, QColor background, bool isEnabled = true, bool isEmpty = false);
 void SCRIBUS_API renderCheckerPattern(QPainter *painter, QRectF rect);
colorslider_2025-10-25_01.patch (21,671 bytes)   
scribus.zip (5,099 bytes)
colorslider_mac.png (9,552 bytes)   
colorslider_mac.png (9,552 bytes)   

cbradney

2025-10-25 19:36

administrator   ~0053124

Works ok here, pending Jeans review of the other patch first
thanks

Issue History

Date Modified Username Field Change
2025-05-13 20:33 nitramr New Issue
2025-05-13 20:33 nitramr Status new => assigned
2025-05-13 20:33 nitramr Assigned To => nitramr
2025-05-13 20:33 nitramr File Added: color_slider.zip
2025-05-13 20:33 nitramr File Added: colorslider_2025-05-13_01.patch
2025-05-13 20:33 nitramr File Added: preview.png
2025-05-13 21:06 cbradney Note Added: 0052524
2025-05-13 21:06 cbradney File Added: image.png
2025-05-30 05:47 ale Relationship added child of 0017540
2025-10-25 14:16 nitramr Note Added: 0053120
2025-10-25 14:16 nitramr File Added: colorslider_2025-10-25_01.patch
2025-10-25 14:16 nitramr File Added: scribus.zip
2025-10-25 14:16 nitramr File Added: colorslider_mac.png
2025-10-25 19:36 cbradney Note Added: 0053124
2025-10-27 18:58 nitramr Relationship added duplicate of 0006434