2014-07-08 03:11:14 -04:00
# include "FractoriumPch.h"
# include "DoubleSpinBox.h"
2016-02-12 00:38:21 -05:00
QTimer DoubleSpinBox : : s_Timer ;
2015-05-15 21:45:15 -04:00
2014-07-08 03:11:14 -04:00
/// <summary>
/// Constructor that passes parent to the base and sets up height and step.
/// Specific focus policy is used to allow the user to hover over the control
/// and change its value using the mouse wheel without explicitly having to click
/// inside of it.
/// </summary>
2015-01-02 18:11:36 -05:00
/// <param name="p">The parent widget. Default: nullptr.</param>
2014-07-08 03:11:14 -04:00
/// <param name="height">The height of the spin box. Default: 16.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param>
2014-12-11 00:50:15 -05:00
DoubleSpinBox : : DoubleSpinBox ( QWidget * p , int h , double step )
: QDoubleSpinBox ( p )
2014-07-08 03:11:14 -04:00
{
m_DoubleClick = false ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_DoubleClickLowVal = 0 ;
2014-07-08 03:11:14 -04:00
m_DoubleClickNonZero = 0 ;
m_DoubleClickZero = 1 ;
m_Step = step ;
m_SmallStep = step / 10.0 ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
m_Settings = FractoriumSettings : : DefInstance ( ) ;
2014-07-08 03:11:14 -04:00
setSingleStep ( step ) ;
setFrame ( false ) ;
setButtonSymbols ( QAbstractSpinBox : : NoButtons ) ;
setFocusPolicy ( Qt : : StrongFocus ) ;
2014-12-11 00:50:15 -05:00
setMinimumHeight ( h ) ; //setGeometry() has no effect, so must set both of these instead.
setMaximumHeight ( h ) ;
2015-05-15 21:45:15 -04:00
setContextMenuPolicy ( Qt : : PreventContextMenu ) ;
2014-07-08 03:11:14 -04:00
lineEdit ( ) - > installEventFilter ( this ) ;
lineEdit ( ) - > setAlignment ( Qt : : AlignLeft | Qt : : AlignVCenter ) ;
2015-05-15 21:45:15 -04:00
connect ( this , SIGNAL ( valueChanged ( double ) ) , this , SLOT ( OnSpinBoxValueChanged ( double ) ) , Qt : : QueuedConnection ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Set the value of the control without triggering signals.
/// </summary>
/// <param name="d">The value to set it to</param>
void DoubleSpinBox : : SetValueStealth ( double d )
{
blockSignals ( true ) ;
setValue ( d ) ;
blockSignals ( false ) ;
}
/// <summary>
/// Set whether to respond to double click events.
/// </summary>
/// <param name="b">True if this should respond to double click events, else false.</param>
void DoubleSpinBox : : DoubleClick ( bool b )
{
m_DoubleClick = b ;
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
/// <summary>
/// Set the value to be used instead of zero to represent the lower value
/// used when responding to a double click.
/// </summary>
/// <param name="val">The value to be used for the lower value instead of zero</param>
void DoubleSpinBox : : DoubleClickLowVal ( double val )
{
m_DoubleClickLowVal = val ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the value to be used when the user double clicks the spinner while
/// it contains zero.
/// </summary>
/// <param name="val">The value to be used</param>
void DoubleSpinBox : : DoubleClickZero ( double val )
{
m_DoubleClickZero = val ;
}
/// <summary>
/// Set the value to be used when the user double clicks the spinner while
/// it contains a non-zero value.
/// </summary>
/// <param name="val">The value to be used</param>
void DoubleSpinBox : : DoubleClickNonZero ( double val )
{
m_DoubleClickNonZero = val ;
}
2015-02-03 20:11:16 -05:00
/// <summary>
/// Get the default step used when the user scrolls.
/// </summary>
2018-01-30 01:14:48 -05:00
/// <returns>The default step as a double.</returns>
2015-02-03 20:11:16 -05:00
double DoubleSpinBox : : Step ( )
{
return m_Step ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the default step to be used when the user scrolls.
/// </summary>
/// <param name="step">The step to use for scrolling</param>
void DoubleSpinBox : : Step ( double step )
{
m_Step = step ;
}
2015-02-03 20:11:16 -05:00
/// <summary>
/// Get the small step to be used when the user holds down shift while scrolling.
/// </summary>
2018-01-30 01:14:48 -05:00
/// <returns>The small step as a double.</returns>
2015-02-03 20:11:16 -05:00
double DoubleSpinBox : : SmallStep ( )
{
return m_SmallStep ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Set the small step to be used when the user holds down shift while scrolling.
/// The default is step / 10, so use this if something else is needed.
/// </summary>
/// <param name="step">The small step to use for scrolling while the shift key is down</param>
void DoubleSpinBox : : SmallStep ( double step )
{
m_SmallStep = step ;
}
/// <summary>
/// Expose the underlying QLineEdit control to the caller.
/// </summary>
/// <returns>A pointer to the QLineEdit</returns>
QLineEdit * DoubleSpinBox : : lineEdit ( )
{
return QDoubleSpinBox : : lineEdit ( ) ;
}
/// <summary>
/// Another workaround for the persistent text selection bug in Qt.
/// </summary>
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
void DoubleSpinBox : : OnSpinBoxValueChanged ( double )
2014-07-08 03:11:14 -04:00
{
lineEdit ( ) - > deselect ( ) ; //Gets rid of nasty "feature" that always has text selected.
}
2015-05-15 21:45:15 -04:00
/// <summary>
/// Called while the timer is activated due to the right mouse button being held down.
/// </summary>
void DoubleSpinBox : : OnTimeout ( )
{
int xdistance = m_MouseMovePoint . x ( ) - m_MouseDownPoint . x ( ) ;
int ydistance = m_MouseMovePoint . y ( ) - m_MouseDownPoint . y ( ) ;
int distance = abs ( xdistance ) > abs ( ydistance ) ? xdistance : ydistance ;
2018-08-10 21:06:04 -04:00
distance = Sqr ( distance ) * ( distance < 0 ? - 1 : 1 ) ;
2015-05-15 21:45:15 -04:00
double scale , val ;
double d = value ( ) ;
bool shift = QGuiApplication : : keyboardModifiers ( ) . testFlag ( Qt : : ShiftModifier ) ;
2016-02-20 21:44:52 -05:00
bool ctrl = QGuiApplication : : keyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ;
2015-05-15 21:45:15 -04:00
double amount = ( m_SmallStep + m_Step ) * 0.5 ;
if ( shift )
scale = 0.0001 ;
2016-02-20 21:44:52 -05:00
else if ( ctrl )
2015-05-15 21:45:15 -04:00
scale = 0.01 ;
else
scale = 0.001 ;
val = d + ( distance * amount * scale ) ;
setValue ( val ) ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Event filter for taking special action on double click events.
/// </summary>
/// <param name="o">The object</param>
/// <param name="e">The eevent</param>
/// <returns>false</returns>
bool DoubleSpinBox : : eventFilter ( QObject * o , QEvent * e )
{
2017-07-22 16:43:35 -04:00
auto me = dynamic_cast < QMouseEvent * > ( e ) ;
2015-05-15 21:45:15 -04:00
2016-12-05 22:04:33 -05:00
if ( isEnabled ( ) & & me )
2014-07-08 03:11:14 -04:00
{
2017-07-22 21:30:25 -04:00
bool isRight = me - > button ( ) = = Qt : : RightButton ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
if ( ! m_Settings - > ToggleType ( ) & & //Ensure double click toggles, not right click.
2016-12-05 22:04:33 -05:00
me - > type ( ) = = QMouseEvent : : MouseButtonPress & &
2017-07-22 21:30:25 -04:00
isRight )
2016-12-05 22:04:33 -05:00
{
m_MouseDownPoint = m_MouseMovePoint = me - > pos ( ) ;
StartTimer ( ) ;
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
else if ( ! m_Settings - > ToggleType ( ) & &
2016-12-05 22:04:33 -05:00
me - > type ( ) = = QMouseEvent : : MouseButtonRelease & &
2017-07-22 21:30:25 -04:00
isRight )
2016-12-05 22:04:33 -05:00
{
StopTimer ( ) ;
m_MouseDownPoint = m_MouseMovePoint = me - > pos ( ) ;
}
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
else if ( ! m_Settings - > ToggleType ( ) & &
2016-12-05 22:04:33 -05:00
me - > type ( ) = = QMouseEvent : : MouseMove & &
QGuiApplication : : mouseButtons ( ) & Qt : : RightButton )
{
m_MouseMovePoint = me - > pos ( ) ;
}
else if ( m_DoubleClick & &
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
( ( ! m_Settings - > ToggleType ( ) & & e - > type ( ) = = QMouseEvent : : MouseButtonDblClick & & me - > button ( ) = = Qt : : LeftButton ) | |
2017-07-22 21:30:25 -04:00
( m_Settings - > ToggleType ( ) & & me - > type ( ) = = QMouseEvent : : MouseButtonRelease & & isRight ) ) )
2016-12-05 22:04:33 -05:00
{
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
if ( IsClose ( m_DoubleClickLowVal , value ( ) ) )
2016-12-05 22:04:33 -05:00
setValue ( m_DoubleClickZero ) ;
else
setValue ( m_DoubleClickNonZero ) ;
2017-07-22 21:30:25 -04:00
return true ;
2016-12-05 22:04:33 -05:00
}
2014-07-08 03:11:14 -04:00
}
else
{
if ( e - > type ( ) = = QEvent : : Wheel )
{
//Take special action for shift to reduce the scroll amount. Control already
//increases it automatically.
2014-12-11 00:50:15 -05:00
if ( QWheelEvent * we = dynamic_cast < QWheelEvent * > ( e ) )
2014-07-08 03:11:14 -04:00
{
2014-12-11 00:50:15 -05:00
Qt : : KeyboardModifiers mod = we - > modifiers ( ) ;
2014-07-08 03:11:14 -04:00
if ( mod . testFlag ( Qt : : ShiftModifier ) )
setSingleStep ( m_SmallStep ) ;
else
setSingleStep ( m_Step ) ;
}
}
}
return QDoubleSpinBox : : eventFilter ( o , e ) ;
}
2018-07-31 00:39:41 -04:00
/// <summary>
/// Override which is for handling specific key presses while this control is focused.
/// In particular, + = and up arrow increase the value, equivalent to scrolling the mouse wheel up, while also observing shift/ctrl modifiers.
/// Values are decreased in the same way by pressing - _ or down arrow.
/// </summary>
/// <param name="ke">The key event</param>
void DoubleSpinBox : : keyPressEvent ( QKeyEvent * ke )
{
bool shift = QGuiApplication : : keyboardModifiers ( ) . testFlag ( Qt : : ShiftModifier ) ;
bool ctrl = QGuiApplication : : keyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ;
if ( ke - > key ( ) = = Qt : : Key_Plus | | ke - > key ( ) = = Qt : : Key_Equal | | ke - > key ( ) = = Qt : : Key_Up )
{
if ( shift )
{
setSingleStep ( m_SmallStep ) ;
setValue ( value ( ) + m_SmallStep ) ;
}
else
{
setSingleStep ( m_Step ) ;
setValue ( value ( ) + ( ctrl ? m_Step * 10 : m_Step ) ) ;
}
}
else if ( ke - > key ( ) = = Qt : : Key_Minus | | ke - > key ( ) = = Qt : : Key_Underscore | | ke - > key ( ) = = Qt : : Key_Down )
{
if ( shift )
{
setSingleStep ( m_SmallStep ) ;
setValue ( value ( ) - m_SmallStep ) ;
}
else
{
setSingleStep ( m_Step ) ;
setValue ( value ( ) - ( ctrl ? m_Step * 10 : m_Step ) ) ;
}
}
else
QDoubleSpinBox : : keyPressEvent ( ke ) ;
}
2014-07-08 03:11:14 -04:00
/// <summary>
/// Called when focus enters the spinner.
/// </summary>
/// <param name="e">The event</param>
void DoubleSpinBox : : focusInEvent ( QFocusEvent * e )
{
2015-05-15 21:45:15 -04:00
StopTimer ( ) ;
2014-07-08 03:11:14 -04:00
QDoubleSpinBox : : focusInEvent ( e ) ;
}
/// <summary>
/// Called when focus leaves the spinner.
/// Qt has a nasty "feature" that leaves the text in a spinner selected
/// and the cursor visible, regardless of whether it has the focus.
/// Manually clear both here.
/// </summary>
/// <param name="e">The event</param>
void DoubleSpinBox : : focusOutEvent ( QFocusEvent * e )
{
2015-05-15 21:45:15 -04:00
StopTimer ( ) ;
QDoubleSpinBox : : focusOutEvent ( e ) ;
2014-07-08 03:11:14 -04:00
}
/// <summary>
/// Called when focus enters the spinner.
/// Must set the focus to make sure key down messages don't erroneously go to the GLWidget.
/// </summary>
/// <param name="e">The event</param>
void DoubleSpinBox : : enterEvent ( QEvent * e )
{
2015-05-15 21:45:15 -04:00
StopTimer ( ) ;
2014-07-08 03:11:14 -04:00
QDoubleSpinBox : : enterEvent ( e ) ;
}
/// <summary>
/// Called when focus leaves the spinner.
/// Must clear the focus to make sure key down messages don't erroneously go to the GLWidget.
/// </summary>
/// <param name="e">The event</param>
void DoubleSpinBox : : leaveEvent ( QEvent * e )
{
2015-05-15 21:45:15 -04:00
StopTimer ( ) ;
2014-07-08 03:11:14 -04:00
QDoubleSpinBox : : leaveEvent ( e ) ;
}
2015-05-15 21:45:15 -04:00
/// <summary>
/// Start the timer in response to the right mouse button being pressed.
/// </summary>
void DoubleSpinBox : : StartTimer ( )
{
2016-02-12 00:38:21 -05:00
s_Timer . stop ( ) ;
connect ( & s_Timer , SIGNAL ( timeout ( ) ) , this , SLOT ( OnTimeout ( ) ) ) ;
s_Timer . start ( 300 ) ;
2015-05-15 21:45:15 -04:00
}
/// <summary>
/// Stop the timer in response to the left mouse button being pressed.
/// </summary>
void DoubleSpinBox : : StopTimer ( )
{
2016-02-12 00:38:21 -05:00
s_Timer . stop ( ) ;
disconnect ( & s_Timer , SIGNAL ( timeout ( ) ) , this , SLOT ( OnTimeout ( ) ) ) ;
--User changes
-Add a palette editor.
-Add support for reading .ugr/.gradient/.gradients palette files.
-Allow toggling on spinners whose minimum value is not zero.
-Allow toggling display of image, affines and grid.
-Add new variations: cylinder2, circlesplit, tile_log, truchet_fill, waves2_radial.
--Bug fixes
-cpow2 was wrong.
-Palettes with rapid changes in color would produce slightly different outputs from Apo/Chaotica. This was due to a long standing bug from flam3.
-Use exec() on Apple and show() on all other OSes for dialog boxes.
-Trying to render a sequence with no frames would crash.
-Selecting multiple xforms and rotating them would produce the wrong rotation.
-Better handling when parsing flames using different encoding, such as unicode and UTF-8.
-Switching between SP/DP didn't reselect the selected flame in the Library tab.
--Code changes
-Make all types concerning palettes be floats, including PaletteTableWidgetItem.
-PaletteTableWidgetItem is no longer templated because all palettes are float.
-Include the source colors for user created gradients.
-Change parallel_for() calls to work with very old versions of TBB which are lingering on some systems.
-Split conditional out of accumulation loop on the CPU for better performance.
-Vectorize summing when doing density filter for better performance.
-Make all usage of palettes be of type float, double is pointless.
-Allow palettes to reside in multiple folders, while ensuring only one of each name is added.
-Refactor some palette path searching code.
-Make ReadFile() throw and catch an exception if the file operation fails.
-A little extra safety in foci and foci3D with a call to Zeps().
-Cast to (real_t) in the OpenCL string for the w variation, which was having trouble compiling on Mac.
-Fixing missing comma between paths in InitPaletteList().
-Move Xml and PaletteList classes into cpp to shorten build times when working on them.
-Remove default param values for IterOpenCLKernelCreator<T>::SharedDataIndexDefines in cpp file.
-Change more NULL to nullptr.
2017-02-26 03:02:21 -05:00
}
2017-07-22 16:43:35 -04:00
2017-07-22 21:30:25 -04:00
/// <summary>
/// Constructor that does nothing but pass arguments to the base.
/// </summary>
/// <param name="p">The parent widget</param>
/// <param name="h">The height of the spin box. Default: 16.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param>
SpecialDoubleSpinBox : : SpecialDoubleSpinBox ( QWidget * p , int h , double step )
: DoubleSpinBox ( p , h , step )
{
}
/// <summary>
/// Event filter for taking special action on right click events.
/// </summary>
/// <param name="o">The object</param>
/// <param name="e">The eevent</param>
/// <returns>True to stop processing the event, else false./</returns>
bool SpecialDoubleSpinBox : : eventFilter ( QObject * o , QEvent * e )
{
if ( isEnabled ( ) )
{
auto me = dynamic_cast < QMouseEvent * > ( e ) ;
auto cme = dynamic_cast < QContextMenuEvent * > ( e ) ;
if ( m_DoubleClick & & m_Settings - > ToggleType ( ) ) //If they use right click to toggle...
{
if ( me )
{
if ( me - > type ( ) = = QMouseEvent : : MouseButtonRelease & & me - > button ( ) = = Qt : : RightButton )
{
if ( me - > modifiers ( ) . testFlag ( Qt : : ShiftModifier ) ) //...then do not take the action if shift was pressed.
return false ; //Shift was pressed, so continue normal event processing to show the menu, but do not call the base to toggle the value.
}
}
else if ( cme ) //Context menu.
{
if ( ! cme - > modifiers ( ) . testFlag ( Qt : : ShiftModifier ) ) //If they are not holding shift, call the base to toggle, and do not process further which suppresses showing the menu.
{
DoubleSpinBox : : eventFilter ( o , e ) ;
return true ;
}
}
}
}
return DoubleSpinBox : : eventFilter ( o , e ) ;
}
2017-07-22 16:43:35 -04:00
/// <summary>
/// Constructor that passes agruments to the base and assigns the m_Param and m_Variation members.
/// It also sets up the context menu for special numerical values.
/// </summary>
/// <param name="p">The parent widget</param>
/// <param name="widgetItem">The widget item this spinner is contained in</param>
/// <param name="id">The variation this spinner is for</param>
/// <param name="param">The name of the parameter this is for</param>
/// <param name="h">The height of the spin box. Default: 16.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.05.</param>
VariationTreeDoubleSpinBox : : VariationTreeDoubleSpinBox ( QWidget * p , VariationTreeWidgetItem * widgetItem , eVariationId id , const string & param , int h , double step )
2017-07-22 21:30:25 -04:00
: SpecialDoubleSpinBox ( p , h , step )
2017-07-22 16:43:35 -04:00
{
m_WidgetItem = widgetItem ;
m_Param = param ;
m_Id = id ;
2018-01-28 20:51:19 -05:00
setDecimals ( 7 ) ;
2017-07-22 16:43:35 -04:00
//PI
auto piAction = new QAction ( " PI " , this ) ;
connect ( piAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( PiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( piAction ) ;
//PI * 2
auto twoPiAction = new QAction ( " 2 PI " , this ) ;
connect ( twoPiAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( TwoPiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( twoPiAction ) ;
//PI / 2
auto piOver2Action = new QAction ( " PI / 2 " , this ) ;
connect ( piOver2Action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( PiOver2ActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( piOver2Action ) ;
//PI / 3
auto piOver3Action = new QAction ( " PI / 3 " , this ) ;
connect ( piOver3Action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( PiOver3ActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( piOver3Action ) ;
//PI / 4
auto piOver4Action = new QAction ( " PI / 4 " , this ) ;
connect ( piOver4Action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( PiOver4ActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( piOver4Action ) ;
//PI / 6
auto piOver6Action = new QAction ( " PI / 6 " , this ) ;
connect ( piOver6Action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( PiOver6ActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( piOver6Action ) ;
//1 / PI
auto oneOverPiAction = new QAction ( " 1 / PI " , this ) ;
connect ( oneOverPiAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( OneOverPiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( oneOverPiAction ) ;
//2 / PI
auto twoOverPiAction = new QAction ( " 2 / PI " , this ) ;
connect ( twoOverPiAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( TwoOverPiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( twoOverPiAction ) ;
//3 / PI
auto threeOverPiAction = new QAction ( " 3 / PI " , this ) ;
connect ( threeOverPiAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( ThreeOverPiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( threeOverPiAction ) ;
//4 / PI
auto fourOverPiAction = new QAction ( " 4 / PI " , this ) ;
connect ( fourOverPiAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( FourOverPiActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( fourOverPiAction ) ;
//Sqrt(2)
auto sqrtTwoAction = new QAction ( " Sqrt(2) " , this ) ;
connect ( sqrtTwoAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( SqrtTwoActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( sqrtTwoAction ) ;
//Sqrt(2)
auto sqrtThreeAction = new QAction ( " Sqrt(3) " , this ) ;
connect ( sqrtThreeAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( SqrtThreeActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( sqrtThreeAction ) ;
//Need this for it to show up properly.
this - > setContextMenuPolicy ( Qt : : ActionsContextMenu ) ;
2018-01-28 14:40:34 -05:00
lineEdit ( ) - > setValidator ( new QDoubleValidator ( this ) ) ;
2017-07-22 16:43:35 -04:00
}
void VariationTreeDoubleSpinBox : : PiActionTriggered ( bool checked ) { setValue ( M_PI ) ; }
void VariationTreeDoubleSpinBox : : TwoPiActionTriggered ( bool checked ) { setValue ( M_PI * 2 ) ; }
void VariationTreeDoubleSpinBox : : PiOver2ActionTriggered ( bool checked ) { setValue ( M_PI_2 ) ; }
void VariationTreeDoubleSpinBox : : PiOver3ActionTriggered ( bool checked ) { setValue ( M_PI / 3 ) ; }
void VariationTreeDoubleSpinBox : : PiOver4ActionTriggered ( bool checked ) { setValue ( M_PI / 4 ) ; }
void VariationTreeDoubleSpinBox : : PiOver6ActionTriggered ( bool checked ) { setValue ( M_PI / 6 ) ; }
void VariationTreeDoubleSpinBox : : OneOverPiActionTriggered ( bool checked ) { setValue ( 1 / M_PI ) ; }
void VariationTreeDoubleSpinBox : : TwoOverPiActionTriggered ( bool checked ) { setValue ( 2 / M_PI ) ; }
void VariationTreeDoubleSpinBox : : ThreeOverPiActionTriggered ( bool checked ) { setValue ( 3 / M_PI ) ; }
void VariationTreeDoubleSpinBox : : FourOverPiActionTriggered ( bool checked ) { setValue ( 4 / M_PI ) ; }
void VariationTreeDoubleSpinBox : : SqrtTwoActionTriggered ( bool checked ) { setValue ( M_SQRT2 ) ; }
void VariationTreeDoubleSpinBox : : SqrtThreeActionTriggered ( bool checked ) { setValue ( std : : sqrt ( 3.0 ) ) ; }
2018-01-30 01:14:48 -05:00
/// <summary>
/// Override which converts the passed in double to text.
/// </summary>
/// <returns>Text showing decimals() decimal places, or sometimes scientific notation.</returns>
2018-01-28 14:40:34 -05:00
QString VariationTreeDoubleSpinBox : : textFromValue ( double value ) const
{
2018-01-28 20:51:19 -05:00
return QWidget : : locale ( ) . toString ( value , ' g ' , decimals ( ) ) ;
}
2018-01-30 01:14:48 -05:00
/// <summary>
/// Override which converts the passed in text to a double
/// </summary>
/// <returns>The converted double</returns>
2018-01-28 20:51:19 -05:00
double VariationTreeDoubleSpinBox : : valueFromText ( const QString & text ) const
{
return QWidget : : locale ( ) . toDouble ( text ) ;
2018-01-28 14:40:34 -05:00
}
2017-07-22 16:43:35 -04:00
/// <summary>
/// Constructor that sets up the context menu for special numerical values specific to affine spinners.
/// </summary>
/// <param name="p">The parent widget</param>
/// <param name="h">The height of the spin box. Default: 20.</param>
/// <param name="step">The step used to increment/decrement the spin box when using the mouse wheel. Default: 0.01.</param>
AffineDoubleSpinBox : : AffineDoubleSpinBox ( QWidget * p , int h , double step )
2017-07-22 21:30:25 -04:00
: SpecialDoubleSpinBox ( p , h , step )
2017-07-22 16:43:35 -04:00
{
//-1
auto neg1Action = new QAction ( " -1 " , this ) ;
connect ( neg1Action , SIGNAL ( triggered ( bool ) ) , this , SLOT ( NegOneActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( neg1Action ) ;
//0
auto zeroAction = new QAction ( " 0 " , this ) ;
connect ( zeroAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( ZeroActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( zeroAction ) ;
//1
auto oneAction = new QAction ( " 1 " , this ) ;
connect ( oneAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( OneActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( oneAction ) ;
//45
auto fortyFiveAction = new QAction ( " 45 " , this ) ;
connect ( fortyFiveAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( FortyFiveActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( fortyFiveAction ) ;
//-45
auto negFortyFiveAction = new QAction ( " -45 " , this ) ;
connect ( negFortyFiveAction , SIGNAL ( triggered ( bool ) ) , this , SLOT ( NegFortyFiveActionTriggered ( bool ) ) , Qt : : QueuedConnection ) ;
this - > addAction ( negFortyFiveAction ) ;
//Need this for it to show up properly.
this - > setContextMenuPolicy ( Qt : : ActionsContextMenu ) ;
}
void AffineDoubleSpinBox : : NegOneActionTriggered ( bool checked ) { setValue ( - 1 ) ; }
void AffineDoubleSpinBox : : ZeroActionTriggered ( bool checked ) { setValue ( 0 ) ; }
void AffineDoubleSpinBox : : OneActionTriggered ( bool checked ) { setValue ( 1 ) ; }
void AffineDoubleSpinBox : : FortyFiveActionTriggered ( bool checked ) { setValue ( 0.707107 ) ; }
2017-07-22 21:30:25 -04:00
void AffineDoubleSpinBox : : NegFortyFiveActionTriggered ( bool checked ) { setValue ( - 0.707107 ) ; }