Largely reworked the color selector. Still not perfect but is better

Thu, 04 Jul 2013 16:19:50 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Thu, 04 Jul 2013 16:19:50 +0300
changeset 327
9ea604af1319
parent 326
469bf1fe26e8
child 328
b6a814a608c6

Largely reworked the color selector. Still not perfect but is better

changelog.txt file | annotate | diff | comparison | revisions
roadmap.txt file | annotate | diff | comparison | revisions
src/addObjectDialog.cpp file | annotate | diff | comparison | revisions
src/colorSelectDialog.cpp file | annotate | diff | comparison | revisions
src/colorSelectDialog.h file | annotate | diff | comparison | revisions
src/common.h file | annotate | diff | comparison | revisions
src/configDialog.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/ui/colorsel.ui file | annotate | diff | comparison | revisions
--- a/changelog.txt	Thu Jul 04 03:42:55 2013 +0300
+++ b/changelog.txt	Thu Jul 04 16:19:50 2013 +0300
@@ -20,6 +20,7 @@
 - Improved external program fault handling: don't try to replace/append the output in case of failure, catch non-zero exit codes.
 - Added a progress box for file loading to respond to desktops while loading files. With large files
 	the no-response policy could be a bad thing.
+- Color selector is now twice as wide for easier color selection.
 - Fixed: Recent files should behave coherently now.
 - Fixed: text editing did not trigger checks while setting LDraw path, removed the Configure
 	button from the LDraw path config dialog, it's no longer needed.
--- a/roadmap.txt	Thu Jul 04 03:42:55 2013 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-================================================================================
-== LDFORGE ROADMAP
-================================================================================
-
------------------------------
--- Alpha 1
-
-REQUIRED:
-	- Do some testing to ensure that there's nothing horribly broken or misssing
-	- [Ext progs] Isecalc support. It's already half-done...
-	- [Ext progs] failure recovery
-
-RECOMMENDED:
-	- [Ext progs] Coverer, Edger2, SlicerPro interfaces
-	- [Viewport] Compile selected entries beforehand, this way picking doesn't need
-		any recompiling and will probably be a lot faster.
-
-DONE:
-	- [Plane draw] Get the thing working for non-top cameras.
-
------------------------------
--- Alpha 2
-
-REQUIRED:
-	- Undo/redo stability
-
-RECOMMENDED:
-	- [Plane draw] Option support: rectangle, line loop, circle, ellipse?, disc
-	- [Viewport] Vertex drawing and selection, if possible..
-	- [Color selector] Rewrite the viewport, don't use QPen for color edges!
-
-SUGGESTED:
-	- [Radials] Ring covering?
-
------------------------------
--- Stable 1.0
-
-REQUIRED:
-	- Anything that crashes the thing has to be obviously fixed.
-
-SUGGESTED:
-	- Texture mapping? Probably best to leave this off until future versions.
\ No newline at end of file
--- a/src/addObjectDialog.cpp	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/addObjectDialog.cpp	Thu Jul 04 16:19:50 2013 +0300
@@ -264,7 +264,7 @@
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
 void AddObjectDialog::slot_colorButtonClicked () {
-	ColorSelectDialog::staticDialog (colnum, colnum, this);
+	ColorSelector::getColor (colnum, colnum, this);
 	setButtonBackground (pb_color, colnum);
 }
 
--- a/src/colorSelectDialog.cpp	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/colorSelectDialog.cpp	Thu Jul 04 16:19:50 2013 +0300
@@ -1,29 +1,25 @@
 /*
  *  LDForge: LDraw parts authoring CAD
  *  Copyright (C) 2013 Santeri Piippo
- *  
+ *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <QGraphicsScene>
-#include <QGraphicsView>
-#include <QBoxLayout>
 #include <QGraphicsItem>
 #include <QMouseEvent>
 #include <QScrollBar>
-#include <QLabel>
-#include <QDialogButtonBox>
 
 #include "common.h"
 #include "gui.h"
@@ -31,99 +27,99 @@
 #include "colors.h"
 #include "config.h"
 #include "misc.h"
+#include "ui_colorsel.h"
 
-static const short g_numCols = 8;
-static const short g_numRows = 10;
+static const int g_numColumns = 16;
 static const short g_squareSize = 32;
-static const long g_width = (g_numCols * g_squareSize);
-static const long g_height = (g_numRows * g_squareSize);
-static const long g_maxHeight = ((MAX_COLORS / g_numCols) * g_squareSize);
 
-extern_cfg (str, gl_maincolor);
-extern_cfg (float, gl_maincolor_alpha);
+extern_cfg( str, gl_maincolor );
+extern_cfg( float, gl_maincolor_alpha );
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-ColorSelectDialog::ColorSelectDialog (short int defval, QWidget* parent) : QDialog (parent) {
+ColorSelector::ColorSelector( short defval, QWidget* parent ) : QDialog( parent )
+{
 	// Remove the default color if it's invalid
-	if (!getColor (defval))
+	if( !::getColor( defval ))
 		defval = -1;
 	
-	gs_scene = new QGraphicsScene;
-	gv_view = new QGraphicsView (gs_scene);
-	selColor = defval;
+	m_firstResize = true;
+	ui = new Ui_ColorSelUI;
+	ui->setupUi( this );
+	
+	m_scene = new QGraphicsScene;
+	ui->viewport->setScene( m_scene );
+	setSelection( ::getColor( defval ));
 	
 	// not really an icon but eh
-	gs_scene->setBackgroundBrush (getIcon ("checkerboard"));
-	
-	gs_scene->setSceneRect (0, 0, g_width, g_maxHeight);
-	gv_view->setSceneRect (0, 0, g_width, g_maxHeight);
-	
-	drawScene ();
+	m_scene->setBackgroundBrush( getIcon( "checkerboard" ));
 	
-	// Set the size of the view
-	const long viewWidth = g_width + 21; // HACK: 21 for scrollbar
-	gv_view->setMaximumWidth (viewWidth);
-	gv_view->setMinimumWidth (viewWidth);
-	gv_view->setMaximumHeight (g_height);
-	gv_view->setMinimumHeight (g_height);
-	gv_view->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
+	drawScene();
 	
-	// If we have a default color selected, scroll down so that it is visible.
-	// HACK: find a better way to do this
-	if (defval >= ((g_numCols * g_numRows) - 2)) {
-		ulong ulNewY = ((defval / g_numCols) - 3) * g_squareSize;
-		gv_view->verticalScrollBar ()->setSliderPosition (ulNewY);
-	}
+	int width = viewportWidth();
+	ui->viewport->setMinimumWidth( width );
+	ui->viewport->setMaximumWidth( width );
 	
-	lb_colorInfo = new QLabel;
-	drawColorInfo ();
-	
-	QVBoxLayout* layout = new QVBoxLayout;
-	layout->addWidget (gv_view);
-	layout->addWidget (lb_colorInfo);
-	layout->addWidget (makeButtonBox (*this));
-	setLayout (layout);
-	
-	setWindowIcon (getIcon ("palette"));
-	setWindowTitle (APPNAME);
+	drawColorInfo();
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void ColorSelectDialog::drawScene () {
+ColorSelector::~ColorSelector()
+{
+	delete ui;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void ColorSelector::drawScene()
+{
+	const int numCols = g_numColumns;
+	const int square = g_squareSize;
+	const int g_maxHeight = ( numRows() * square );
+	QRect sceneRect( 0, 0, viewportWidth(), g_maxHeight );
+	
+	m_scene->setSceneRect( sceneRect );
+	ui->viewport->setSceneRect( sceneRect );
+	
 	const double penWidth = 1.0f;
-	QPen pen (Qt::black, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+	QPen pen( Qt::black, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin );
 	
 	// Draw the color rectangles.
-	gs_scene->clear ();
-	for (short i = 0; i < MAX_COLORS; ++i) {
-		color* meta = getColor (i);
-		if (!meta)
+	m_scene->clear();
+	
+	for( short i = 0; i < MAX_COLORS; ++i )
+	{
+		color* info = ::getColor( i );
+		
+		if( !info )
 			continue;
 		
-		const double x = (i % g_numCols) * g_squareSize;
-		const double y = (i / g_numCols) * g_squareSize;
-		const double w = (g_squareSize) - (penWidth / 2);
+		const double x = ( i % numCols ) * square;
+		const double y = ( i / numCols ) * square;
+		const double w = square - ( penWidth / 2 );
+		
+		QColor col = info->faceColor;
 		
-		QColor col = meta->faceColor;
-		
-		if (i == maincolor) {
+		if( i == maincolor )
+		{
 			// Use the user preferences for main color here
-			col = gl_maincolor.value;
-			col.setAlpha (gl_maincolor_alpha * 255.0f);
+			col = QColor( gl_maincolor );
+			col.setAlpha( gl_maincolor_alpha * 255.0f );
 		}
 		
-		gs_scene->addRect (x, y, w, w, pen, col);
-		QGraphicsTextItem* numtext = gs_scene->addText (fmt ("%1", i));
-		numtext->setDefaultTextColor ((luma (col) < 80) ? Qt::white : Qt::black);
-		numtext->setPos (x, y);
+		m_scene->addRect( x, y, w, w, pen, col );
+		QGraphicsTextItem* numtext = m_scene->addText( fmt( "%1", i ));
+		numtext->setDefaultTextColor(( luma( col ) < 80 ) ? Qt::white : Qt::black );
+		numtext->setPos( x, y );
 		
-		if (i == selColor) {
-			auto curspic = gs_scene->addPixmap (getIcon ("colorcursor"));
-			curspic->setPos (x, y);
+		if( i == sel()->index )
+		{
+			auto curspic = m_scene->addPixmap( getIcon( "colorcursor" ));
+			curspic->setPos( x, y );
 		}
 	}
 }
@@ -131,47 +127,90 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void ColorSelectDialog::drawColorInfo () {
-	color* col = getColor (selColor);
-	
-	if (selColor == -1 || !col) {
-		lb_colorInfo->setText ("---");
+int ColorSelector::numRows() const
+{
+	return ( MAX_COLORS / g_numColumns );
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+int ColorSelector::viewportWidth() const
+{
+	return g_numColumns * g_squareSize + 21;
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+void ColorSelector::drawColorInfo()
+{
+	if( !sel() )
+	{
+		ui->colorLabel->setText( "---" );
 		return;
 	}
 	
-	lb_colorInfo->setText (fmt ("%1 - %2",
-		selColor, col->name));
+	ui->colorLabel->setText( fmt( "%1 - %2", sel()->index, sel()->name ));
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void ColorSelectDialog::mousePressEvent (QMouseEvent* event) {
-	QPointF scenepos = gv_view->mapToScene (event->pos ());
-	
-	ulong x = ((ulong) scenepos.x () - (g_squareSize / 2)) / g_squareSize;
-	ulong y = ((ulong) scenepos.y () - (g_squareSize / 2)) / g_squareSize;
-	ulong idx = (y * g_numCols) + x;
+void ColorSelector::resizeEvent( QResizeEvent* ev )
+{
+	// If this is the first resize, check if we need to scroll down to see the
+	// currently selected color. We cannot do this in the constructor because the
+	// height is not set properly there.
+	if( m_firstResize )
+	{
+		int visibleColors = ( ui->viewport->height() / g_squareSize ) * g_numColumns;
+		
+		if( sel() && sel()->index >= visibleColors )
+		{
+			int y = ( sel()->index / g_numColumns ) * g_squareSize;
+			ui->viewport->verticalScrollBar()->setValue( y );
+		}
+		
+		m_firstResize = false;
+	}
 	
-	color* col = getColor (idx);
-	if (!col)
-		return;
-	
-	selColor = idx;
-	drawScene ();
-	drawColorInfo ();
+	drawScene();
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-bool ColorSelectDialog::staticDialog (short& val, short int defval, QWidget* parent) {
-	ColorSelectDialog dlg (defval, parent);
+void ColorSelector::mousePressEvent( QMouseEvent* event )
+{
+	QPointF scenepos = ui->viewport->mapToScene( event->pos() );
+	
+	ulong x = (( ulong ) scenepos.x() - ( g_squareSize / 2 )) / g_squareSize;
+	ulong y = (( ulong ) scenepos.y() - ( g_squareSize / 2 )) / g_squareSize;
+	ulong idx = ( y * g_numColumns ) + x;
+	
+	color* col = ::getColor( idx );
+	
+	if( !col )
+		return;
 	
-	if (dlg.exec () && dlg.selColor != -1) {
-		val = dlg.selColor;
+	setSelection( col );
+	drawScene();
+	drawColorInfo();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
+bool ColorSelector::getColor( short& val, short int defval, QWidget* parent )
+{
+	ColorSelector dlg( defval, parent );
+	
+	if( dlg.exec() && dlg.sel() != null )
+	{
+		val = dlg.sel()->index;
 		return true;
 	}
 	
 	return false;
-}
\ No newline at end of file
+}
--- a/src/colorSelectDialog.h	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/colorSelectDialog.h	Thu Jul 04 16:19:50 2013 +0300
@@ -1,17 +1,17 @@
 /*
  *  LDForge: LDraw parts authoring CAD
  *  Copyright (C) 2013 Santeri Piippo
- *  
+ *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
@@ -22,27 +22,33 @@
 #include <QDialog>
 #include "common.h"
 
-class QLabel;
-class QGraphicsView;
+class color;
+class Ui_ColorSelUI;
 class QGraphicsScene;
-class ColorSelectDialog : public QDialog {
+
+class ColorSelector : public QDialog
+{
 	Q_OBJECT
+	READ_PROPERTY( color*, sel, setSelection )
 	
 public:
-	explicit ColorSelectDialog (short defval = -1, QWidget* parent = null);
-	static bool staticDialog (short& val, short defval = -1, QWidget* parent = null);
+	explicit ColorSelector( short defval = -1, QWidget* parent = null );
+	virtual ~ColorSelector();
+	static bool getColor( short& val, short defval = -1, QWidget* parent = null );
 	
-	QGraphicsScene* gs_scene;
-	QGraphicsView* gv_view;
-	QLabel* lb_colorInfo;
-	short selColor;
+protected:
+	void mousePressEvent( QMouseEvent* event );
+	void resizeEvent( QResizeEvent* ev );
 	
 private:
-	void drawScene ();
-	void drawColorInfo ();
+	Ui_ColorSelUI* ui;
+	QGraphicsScene* m_scene;
+	bool m_firstResize;
 	
-private slots:
-	void mousePressEvent (QMouseEvent* event);
+	int numRows() const;
+	int viewportWidth() const;
+	void drawScene();
+	void drawColorInfo();
 };
 
-#endif // COLORSELECTOR_H
\ No newline at end of file
+#endif // COLORSELECTOR_H
--- a/src/common.h	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/common.h	Thu Jul 04 16:19:50 2013 +0300
@@ -134,6 +134,16 @@
 public: \
 	READ_ACCESSOR (T, GET) { return PROP_NAME (GET); }
 
+// Property whose set accessor is a public slot
+// TODO: make this replace PROPERTY
+#define SLOT_PROPERTY( T, GET, SET ) \
+private: \
+	T PROP_NAME( GET ); \
+public: \
+	READ_ACCESSOR( T, GET ) { return PROP_NAME (GET); } \
+public slots: \
+	SET_ACCESSOR( T, SET ) { PROP_NAME (GET) = val; }
+
 #ifdef null
 #undef null
 #endif // null
--- a/src/configDialog.cpp	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/configDialog.cpp	Thu Jul 04 16:19:50 2013 +0300
@@ -449,7 +449,7 @@
 	short dDefault = entry ? entry->col->index : -1;
 	short dValue;
 	
-	if (ColorSelectDialog::staticDialog (dValue, dDefault, this) == false)
+	if (ColorSelector::getColor (dValue, dDefault, this) == false)
 		return;
 	
 	if (entry)
--- a/src/gui_editactions.cpp	Thu Jul 04 03:42:55 2013 +0300
+++ b/src/gui_editactions.cpp	Thu Jul 04 16:19:50 2013 +0300
@@ -208,7 +208,7 @@
 	defcol = g_win->getSelectedColor ();
 	
 	// Show the dialog to the user now and ask for a color.
-	if (ColorSelectDialog::staticDialog (colnum, defcol, g_win)) {
+	if (ColorSelector::getColor (colnum, defcol, g_win)) {
 		for (LDObject* obj : objs) {
 			if (obj->isColored () == false)
 				continue;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ui/colorsel.ui	Thu Jul 04 16:19:50 2013 +0300
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ColorSelUI</class>
+ <widget class="QDialog" name="ColorSelUI">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>382</width>
+    <height>442</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Pick a Color</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGraphicsView" name="viewport">
+     <property name="verticalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOn</enum>
+     </property>
+     <property name="horizontalScrollBarPolicy">
+      <enum>Qt::ScrollBarAlwaysOff</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="colorLabel">
+       <property name="text">
+        <string>[[ COLOR HERE ]]</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ColorSelUI</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ColorSelUI</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

mercurial