mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-01-21 13:10:04 -05:00
--User changes
Allow for setting rendering thread priorities from the command line and final render dialog. Currently only implemented on Windows. Show estimated time left on the final render dialog. Sort palette list by name, instead of by index in the palette file. Sorting can be flipped by clicking the column headers of the palette table. --Code changes Remove unnecessary connect() statement in Variations tab.
This commit is contained in:
parent
c97946c660
commit
5bd593b42f
@ -824,6 +824,7 @@ xcopy /F /Y /R /D "$(SolutionDir)..\..\..\Data\flam3-palettes.xml" "$(OutDir)"</
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\FractoriumCommon.h" />
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\FractoriumEmberController.h" />
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\GLEmberController.h" />
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\PaletteTableWidgetItem.h" />
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\resource.h" />
|
||||
<ClInclude Include="GeneratedFiles\ui_AboutDialog.h" />
|
||||
<ClInclude Include="GeneratedFiles\ui_FinalRenderDialog.h" />
|
||||
|
@ -297,6 +297,9 @@
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\FractoriumCommon.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Source\Fractorium\PaletteTableWidgetItem.h">
|
||||
<Filter>Widgets</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\..\Source\Fractorium\Fractorium.qrc">
|
||||
|
@ -74,7 +74,8 @@ HEADERS += \
|
||||
../../../Source/EmberCommon/JpegUtils.h \
|
||||
../../../Source/EmberCommon/EmberCommonPch.h \
|
||||
../../../Source/Fractorium/FractoriumCommon.h \
|
||||
../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h
|
||||
../../../Source/Fractorium/DoubleSpinBoxTableItemDelegate.h \
|
||||
../../../Source/Fractorium/PaletteTableWidgetItem.h
|
||||
|
||||
FORMS += \
|
||||
../../../Source/Fractorium/AboutDialog.ui \
|
||||
|
@ -976,8 +976,8 @@ public:
|
||||
//were directly written to, must manually call them here.
|
||||
CacheXforms();
|
||||
|
||||
//Need to merge chaos. Original does chaos all the time, but really only need to do it if at least one xform in at least one ember uses it, else skip.
|
||||
//Omit final xform from chaos processing.
|
||||
//Need to merge xaos. Original does xaos all the time, but really only need to do it if at least one xform in at least one ember uses it, else skip.
|
||||
//Omit final xform from xaos processing.
|
||||
if (Interpolater<T>::AnyXaosPresent(embers, size))
|
||||
{
|
||||
for (size_t i = 0; i < XformCount(); i++)
|
||||
|
@ -1216,7 +1216,7 @@ EmberStats Renderer<T, bucketT>::Iterate(size_t iterCount, size_t temporalSample
|
||||
{
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
//SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||
SetThreadPriority(GetCurrentThread(), m_Priority);
|
||||
#endif
|
||||
//Timing t;
|
||||
IterParams<T> params;
|
||||
|
@ -28,6 +28,7 @@ RendererBase::RendererBase()
|
||||
m_LastIter = 0;
|
||||
m_LastIterPercent = 0;
|
||||
m_InteractiveFilter = FILTER_LOG;
|
||||
m_Priority = eThreadPriority::NORMAL;
|
||||
m_ProcessState = NONE;
|
||||
m_ProcessAction = FULL_RENDER;
|
||||
m_InRender = false;
|
||||
@ -546,6 +547,15 @@ void RendererBase::BytesPerChannel(size_t bytesPerChannel)
|
||||
/// <returns>The number of channels per pixel in the output image</returns>
|
||||
size_t RendererBase::NumChannels() const { return m_NumChannels; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get/set the priority used for the CPU rendering threads.
|
||||
/// This does not affect OpenCL rendering.
|
||||
/// </summary>
|
||||
/// <param name="priority">The priority to use for the CPU rendering threads</param>
|
||||
eThreadPriority RendererBase::Priority() const { return m_Priority; }
|
||||
void RendererBase::Priority(eThreadPriority priority) { m_Priority = priority; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the type of filter to use for preview renders during interactive rendering.
|
||||
/// Using basic log scaling is quicker, but doesn't provide any bluring.
|
||||
|
@ -157,6 +157,8 @@ public:
|
||||
size_t BytesPerChannel() const;
|
||||
void BytesPerChannel(size_t bytesPerChannel);
|
||||
size_t NumChannels() const;
|
||||
eThreadPriority Priority() const;
|
||||
void Priority(eThreadPriority priority);
|
||||
eInteractiveFilter InteractiveFilter() const;
|
||||
void InteractiveFilter(eInteractiveFilter filter);
|
||||
|
||||
@ -216,6 +218,7 @@ protected:
|
||||
size_t m_LastTemporalSample;
|
||||
size_t m_LastIter;
|
||||
double m_LastIterPercent;
|
||||
eThreadPriority m_Priority;
|
||||
eProcessAction m_ProcessAction;
|
||||
eProcessState m_ProcessState;
|
||||
eInteractiveFilter m_InteractiveFilter;
|
||||
|
@ -8,6 +8,26 @@
|
||||
/// </summary>
|
||||
namespace EmberNs
|
||||
{
|
||||
#ifndef _WIN32
|
||||
#define THREAD_PRIORITY_LOWEST 1
|
||||
#define THREAD_PRIORITY_BELOW_NORMAL 25
|
||||
#define THREAD_PRIORITY_NORMAL 50
|
||||
#define THREAD_PRIORITY_ABOVE_NORMAL 75
|
||||
#define THREAD_PRIORITY_HIGHEST 99
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Enum to encapsulate and add type safety to the thread priority defines.
|
||||
/// </summary>
|
||||
enum eThreadPriority
|
||||
{
|
||||
LOWEST = THREAD_PRIORITY_LOWEST,//-2
|
||||
BELOW_NORMAL = THREAD_PRIORITY_BELOW_NORMAL,//-1
|
||||
NORMAL = THREAD_PRIORITY_NORMAL,//0
|
||||
ABOVE_NORMAL = THREAD_PRIORITY_ABOVE_NORMAL,//1
|
||||
HIGHEST = THREAD_PRIORITY_HIGHEST//2
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Thin wrapper around std::find_if() to relieve the caller of having to
|
||||
/// pass the implicitly obvious .begin() and .end(), and then compare the results to .end().
|
||||
|
@ -258,6 +258,7 @@ bool EmberAnimate(EmberOptions& opt)
|
||||
renderer->Transparency(opt.Transparency());
|
||||
renderer->NumChannels(channels);
|
||||
renderer->BytesPerChannel(opt.BitsPerChannel() / 8);
|
||||
renderer->Priority((eThreadPriority)Clamp<uint>((uint)eThreadPriority::LOWEST, (uint)eThreadPriority::HIGHEST, opt.Priority()));
|
||||
renderer->Callback(opt.DoProgress() ? progress.get() : nullptr);
|
||||
|
||||
std::function<void(uint)> saveFunc = [&](uint threadVecIndex)
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
|
||||
cout << "\r" << string(m_S.length() * 2, ' ');//Clear what was previously here, * 2 just to be safe because the end parts of previous strings might be longer.
|
||||
m_SS.str("");//Begin new output.
|
||||
m_SS << "\rStage = " << (stage ? "filtering" : "chaos");
|
||||
m_SS << "\rStage = " << (stage ? "filtering" : "iterating");
|
||||
m_SS << ", progress = " << int(fraction) << "%";
|
||||
m_SS << ", eta = " << t.Format(etaMs);
|
||||
m_S = m_SS.str();
|
||||
|
@ -80,6 +80,7 @@ enum eOptionIDs
|
||||
OPT_REPEAT,
|
||||
OPT_TRIES,
|
||||
OPT_MAX_XFORMS,
|
||||
OPT_PRIORITY,
|
||||
|
||||
OPT_SS,//Float value args.
|
||||
OPT_QS,
|
||||
@ -341,18 +342,19 @@ public:
|
||||
"\t\t\t\t\t33: Histogram: float, Accumulator: float.\n"//This differs from the original which used an int hist for bits 33.
|
||||
"\t\t\t\t\t64: Histogram: double, Accumulator: double.\n"));
|
||||
|
||||
INITUINTOPTION(PrintEditDepth, Eou(OPT_USE_ALL, OPT_PRINT_EDIT_DEPTH, _T("--print_edit_depth"), 0, SO_REQ_SEP, "\t--print_edit_depth=<val> Depth to truncate <edit> tag structure when converting a flame to xml. 0 prints all <edit> tags [default: 0].\n"));
|
||||
INITUINTOPTION(JpegQuality, Eou(OPT_RENDER_ANIM, OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg=<val> Jpeg quality 0-100 for compression [default: 95].\n"));
|
||||
INITUINTOPTION(FirstFrame, Eou(OPT_USE_ANIMATE, OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin=<val> Time of first frame to render [default: first time specified in file].\n"));
|
||||
INITUINTOPTION(LastFrame, Eou(OPT_USE_ANIMATE, OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, "\t--end=<val> Time of last frame to render [default: last time specified in the input file].\n"));
|
||||
INITUINTOPTION(Time, Eou(OPT_ANIM_GENOME, OPT_TIME, _T("--time"), 0, SO_REQ_SEP, "\t--time=<val> Time of first and last frame (ie do one frame).\n"));
|
||||
INITUINTOPTION(Frame, Eou(OPT_ANIM_GENOME, OPT_FRAME, _T("--frame"), 0, SO_REQ_SEP, "\t--frame=<val> Synonym for \"time\".\n"));
|
||||
INITUINTOPTION(Dtime, Eou(OPT_USE_ANIMATE, OPT_DTIME, _T("--dtime"), 1, SO_REQ_SEP, "\t--dtime=<val> Time between frames [default: 1].\n"));
|
||||
INITUINTOPTION(Frames, Eou(OPT_USE_GENOME, OPT_NFRAMES, _T("--nframes"), 20, SO_REQ_SEP, "\t--nframes=<val> Number of frames for each stage of the animation [default: 20].\n"));
|
||||
INITUINTOPTION(Loops, Eou(OPT_USE_GENOME, OPT_LOOPS, _T("--loops"), 1, SO_REQ_SEP, "\t--loops=<val> Number of times to rotate each control point in sequence [default: 1].\n"));
|
||||
INITUINTOPTION(Repeat, Eou(OPT_USE_GENOME, OPT_REPEAT, _T("--repeat"), 1, SO_REQ_SEP, "\t--repeat=<val> Number of new flames to create. Ignored if sequence, inter or rotate were specified [default: 1].\n"));
|
||||
INITUINTOPTION(Tries, Eou(OPT_USE_GENOME, OPT_TRIES, _T("--tries"), 10, SO_REQ_SEP, "\t--tries=<val> Number times to try creating a flame that meets the specified constraints. Ignored if sequence, inter or rotate were specified [default: 10].\n"));
|
||||
INITUINTOPTION(MaxXforms, Eou(OPT_USE_GENOME, OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, "\t--maxxforms=<val> The maximum number of xforms allowed in the final output.\n"));
|
||||
INITUINTOPTION(PrintEditDepth, Eou(OPT_USE_ALL, OPT_PRINT_EDIT_DEPTH, _T("--print_edit_depth"), 0, SO_REQ_SEP, "\t--print_edit_depth=<val> Depth to truncate <edit> tag structure when converting a flame to xml. 0 prints all <edit> tags [default: 0].\n"));
|
||||
INITUINTOPTION(JpegQuality, Eou(OPT_RENDER_ANIM, OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg=<val> Jpeg quality 0-100 for compression [default: 95].\n"));
|
||||
INITUINTOPTION(FirstFrame, Eou(OPT_USE_ANIMATE, OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin=<val> Time of first frame to render [default: first time specified in file].\n"));
|
||||
INITUINTOPTION(LastFrame, Eou(OPT_USE_ANIMATE, OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, "\t--end=<val> Time of last frame to render [default: last time specified in the input file].\n"));
|
||||
INITUINTOPTION(Time, Eou(OPT_ANIM_GENOME, OPT_TIME, _T("--time"), 0, SO_REQ_SEP, "\t--time=<val> Time of first and last frame (ie do one frame).\n"));
|
||||
INITUINTOPTION(Frame, Eou(OPT_ANIM_GENOME, OPT_FRAME, _T("--frame"), 0, SO_REQ_SEP, "\t--frame=<val> Synonym for \"time\".\n"));
|
||||
INITUINTOPTION(Dtime, Eou(OPT_USE_ANIMATE, OPT_DTIME, _T("--dtime"), 1, SO_REQ_SEP, "\t--dtime=<val> Time between frames [default: 1].\n"));
|
||||
INITUINTOPTION(Frames, Eou(OPT_USE_GENOME, OPT_NFRAMES, _T("--nframes"), 20, SO_REQ_SEP, "\t--nframes=<val> Number of frames for each stage of the animation [default: 20].\n"));
|
||||
INITUINTOPTION(Loops, Eou(OPT_USE_GENOME, OPT_LOOPS, _T("--loops"), 1, SO_REQ_SEP, "\t--loops=<val> Number of times to rotate each control point in sequence [default: 1].\n"));
|
||||
INITUINTOPTION(Repeat, Eou(OPT_USE_GENOME, OPT_REPEAT, _T("--repeat"), 1, SO_REQ_SEP, "\t--repeat=<val> Number of new flames to create. Ignored if sequence, inter or rotate were specified [default: 1].\n"));
|
||||
INITUINTOPTION(Tries, Eou(OPT_USE_GENOME, OPT_TRIES, _T("--tries"), 10, SO_REQ_SEP, "\t--tries=<val> Number times to try creating a flame that meets the specified constraints. Ignored if sequence, inter or rotate were specified [default: 10].\n"));
|
||||
INITUINTOPTION(MaxXforms, Eou(OPT_USE_GENOME, OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, "\t--maxxforms=<val> The maximum number of xforms allowed in the final output.\n"));
|
||||
INITUINTOPTION(Priority, Eou(OPT_RENDER_ANIM, OPT_PRIORITY, _T("--priority"), eThreadPriority::NORMAL, SO_REQ_SEP, "\t--priority=<val> The priority of the CPU rendering threads from -2 - 2. This does not apply to OpenCL rendering.\n"));
|
||||
|
||||
//Double.
|
||||
INITDOUBLEOPTION(SizeScale, Eod(OPT_RENDER_ANIM, OPT_SS, _T("--ss"), 1, SO_REQ_SEP, "\t--ss=<val> Size scale. All dimensions are scaled by this amount [default: 1.0].\n"));
|
||||
@ -482,6 +484,7 @@ public:
|
||||
PARSEUINTOPTION(OPT_REPEAT, Repeat);
|
||||
PARSEUINTOPTION(OPT_TRIES, Tries);
|
||||
PARSEUINTOPTION(OPT_MAX_XFORMS, MaxXforms);
|
||||
PARSEUINTOPTION(OPT_PRIORITY, Priority);
|
||||
|
||||
PARSEDOUBLEOPTION(OPT_SS, SizeScale);//Float args.
|
||||
PARSEDOUBLEOPTION(OPT_QS, QualityScale);
|
||||
@ -697,6 +700,7 @@ public:
|
||||
EmberOptionEntry<uint> Repeat;
|
||||
EmberOptionEntry<uint> Tries;
|
||||
EmberOptionEntry<uint> MaxXforms;
|
||||
EmberOptionEntry<uint> Priority;
|
||||
|
||||
EmberOptionEntry<double> SizeScale;//Value double.
|
||||
EmberOptionEntry<double> QualityScale;
|
||||
|
@ -154,6 +154,7 @@ bool EmberRender(EmberOptions& opt)
|
||||
renderer->Transparency(opt.Transparency());
|
||||
renderer->NumChannels(channels);
|
||||
renderer->BytesPerChannel(opt.BitsPerChannel() / 8);
|
||||
renderer->Priority((eThreadPriority)Clamp<uint>((uint)eThreadPriority::LOWEST, (uint)eThreadPriority::HIGHEST, opt.Priority()));
|
||||
renderer->Callback(opt.DoProgress() ? progress.get() : nullptr);
|
||||
|
||||
for (i = 0; i < embers.size(); i++)
|
||||
|
@ -109,15 +109,16 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
|
||||
ui.FinalRenderOpenCLCheckBox->setEnabled(false);
|
||||
}
|
||||
|
||||
ui.FinalRenderEarlyClipCheckBox->setChecked( m_Settings->FinalEarlyClip());
|
||||
ui.FinalRenderYAxisUpCheckBox->setChecked( m_Settings->FinalYAxisUp());
|
||||
ui.FinalRenderTransparencyCheckBox->setChecked( m_Settings->FinalTransparency());
|
||||
ui.FinalRenderDoublePrecisionCheckBox->setChecked(m_Settings->FinalDouble());
|
||||
ui.FinalRenderSaveXmlCheckBox->setChecked( m_Settings->FinalSaveXml());
|
||||
ui.FinalRenderDoAllCheckBox->setChecked( m_Settings->FinalDoAll());
|
||||
ui.FinalRenderDoSequenceCheckBox->setChecked( m_Settings->FinalDoSequence());
|
||||
ui.FinalRenderKeepAspectCheckBox->setChecked( m_Settings->FinalKeepAspect());
|
||||
ui.FinalRenderThreadCountSpin->setValue( m_Settings->FinalThreadCount());
|
||||
ui.FinalRenderEarlyClipCheckBox->setChecked( m_Settings->FinalEarlyClip());
|
||||
ui.FinalRenderYAxisUpCheckBox->setChecked( m_Settings->FinalYAxisUp());
|
||||
ui.FinalRenderTransparencyCheckBox->setChecked( m_Settings->FinalTransparency());
|
||||
ui.FinalRenderDoublePrecisionCheckBox->setChecked( m_Settings->FinalDouble());
|
||||
ui.FinalRenderSaveXmlCheckBox->setChecked( m_Settings->FinalSaveXml());
|
||||
ui.FinalRenderDoAllCheckBox->setChecked( m_Settings->FinalDoAll());
|
||||
ui.FinalRenderDoSequenceCheckBox->setChecked( m_Settings->FinalDoSequence());
|
||||
ui.FinalRenderKeepAspectCheckBox->setChecked( m_Settings->FinalKeepAspect());
|
||||
ui.FinalRenderThreadCountSpin->setValue( m_Settings->FinalThreadCount());
|
||||
ui.FinalRenderThreadPriorityComboBox->setCurrentIndex(m_Settings->FinalThreadPriority() + 2);
|
||||
|
||||
m_QualitySpin->setValue(m_Settings->FinalQuality());
|
||||
m_TemporalSamplesSpin->setValue(m_Settings->FinalTemporalSamples());
|
||||
@ -141,7 +142,10 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
|
||||
|
||||
s.setHeight(std::min(s.height(), int(double(desktopHeight * 0.90))));
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, qApp->desktop()->availableGeometry()));
|
||||
|
||||
ui.FinalRenderThreadHorizontalLayout->setAlignment(Qt::AlignLeft);
|
||||
ui.FinalRenderThreadHorizontalLayout->setAlignment(ui.FinalRenderThreadCountSpin, Qt::AlignLeft);
|
||||
ui.FinalRenderThreadHorizontalLayout->setAlignment(ui.FinalRenderThreadPriorityLabel, Qt::AlignLeft);
|
||||
ui.FinalRenderThreadHorizontalLayout->setAlignment(ui.FinalRenderThreadPriorityComboBox, Qt::AlignLeft);
|
||||
QWidget* w = SetTabOrder(this, ui.FinalRenderEarlyClipCheckBox, ui.FinalRenderYAxisUpCheckBox);
|
||||
|
||||
//Update these with new controls.
|
||||
@ -155,6 +159,7 @@ FractoriumFinalRenderDialog::FractoriumFinalRenderDialog(FractoriumSettings* set
|
||||
w = SetTabOrder(this, w, ui.FinalRenderPlatformCombo);
|
||||
w = SetTabOrder(this, w, ui.FinalRenderDeviceCombo);
|
||||
w = SetTabOrder(this, w, ui.FinalRenderThreadCountSpin);
|
||||
w = SetTabOrder(this, w, ui.FinalRenderThreadPriorityComboBox);
|
||||
w = SetTabOrder(this, w, ui.FinalRenderApplyToAllCheckBox);
|
||||
w = SetTabOrder(this, w, m_WidthScaleSpin);
|
||||
w = SetTabOrder(this, w, m_HeightScaleSpin);
|
||||
@ -201,6 +206,7 @@ uint FractoriumFinalRenderDialog::Current() { return ui.FinalRenderCurrentSpin->
|
||||
uint FractoriumFinalRenderDialog::PlatformIndex() { return ui.FinalRenderPlatformCombo->currentIndex(); }
|
||||
uint FractoriumFinalRenderDialog::DeviceIndex() { return ui.FinalRenderDeviceCombo->currentIndex(); }
|
||||
uint FractoriumFinalRenderDialog::ThreadCount() { return ui.FinalRenderThreadCountSpin->value(); }
|
||||
uint FractoriumFinalRenderDialog::ThreadPriority() { return ui.FinalRenderThreadPriorityComboBox->currentIndex() - 2; }
|
||||
double FractoriumFinalRenderDialog::WidthScale() { return m_WidthScaleSpin->value(); }
|
||||
double FractoriumFinalRenderDialog::HeightScale() { return m_HeightScaleSpin->value(); }
|
||||
double FractoriumFinalRenderDialog::Quality() { return m_QualitySpin->value(); }
|
||||
@ -234,6 +240,7 @@ FinalRenderGuiState FractoriumFinalRenderDialog::State()
|
||||
state.m_PlatformIndex = PlatformIndex();
|
||||
state.m_DeviceIndex = DeviceIndex();
|
||||
state.m_ThreadCount = ThreadCount();
|
||||
state.m_ThreadPriority = ThreadPriority();
|
||||
state.m_WidthScale = WidthScale();
|
||||
state.m_HeightScale = HeightScale();
|
||||
state.m_Quality = Quality();
|
||||
@ -327,6 +334,7 @@ void FractoriumFinalRenderDialog::OnOpenCLCheckBoxStateChanged(int state)
|
||||
ui.FinalRenderPlatformCombo->setEnabled(checked);
|
||||
ui.FinalRenderDeviceCombo->setEnabled(checked);
|
||||
ui.FinalRenderThreadCountSpin->setEnabled(!checked);
|
||||
ui.FinalRenderThreadPriorityComboBox->setEnabled(!checked);
|
||||
SetMemory();
|
||||
}
|
||||
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
uint PlatformIndex();
|
||||
uint DeviceIndex();
|
||||
uint ThreadCount();
|
||||
uint ThreadPriority();
|
||||
double WidthScale();
|
||||
double HeightScale();
|
||||
double Quality();
|
||||
|
@ -284,26 +284,84 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="FinalRenderThreadCountSpin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The number of threads to use with CPU rendering.</p><p>Decrease for a more responsive system during rendering, increase for better performance.</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Threads </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="FinalRenderThreadHorizontalLayout" stretch="0,0,0">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="FinalRenderThreadCountSpin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The number of threads to use with CPU rendering.</p><p>Decrease for a more responsive system during rendering, increase for better performance.</p></body></html></string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Threads </string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="FinalRenderThreadPriorityLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Priority: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="FinalRenderThreadPriorityComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maxCount">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Lowest</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Below Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Above Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Highest</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="FinalRenderApplyToAllCheckBox">
|
||||
@ -1063,7 +1121,6 @@
|
||||
<tabstop>FinalRenderOpenCLCheckBox</tabstop>
|
||||
<tabstop>FinalRenderPlatformCombo</tabstop>
|
||||
<tabstop>FinalRenderDeviceCombo</tabstop>
|
||||
<tabstop>FinalRenderThreadCountSpin</tabstop>
|
||||
<tabstop>FinalRenderParamsTable</tabstop>
|
||||
<tabstop>FinalRenderTextOutput</tabstop>
|
||||
<tabstop>StartRenderButton</tabstop>
|
||||
|
@ -170,6 +170,7 @@ FinalRenderEmberController<T>::FinalRenderEmberController(FractoriumFinalRenderD
|
||||
m_Renderer->EarlyClip(m_GuiState.m_EarlyClip);
|
||||
m_Renderer->YAxisUp(m_GuiState.m_YAxisUp);
|
||||
m_Renderer->ThreadCount(m_GuiState.m_ThreadCount);
|
||||
m_Renderer->Priority((eThreadPriority)m_GuiState.m_ThreadPriority);
|
||||
m_Renderer->Transparency(m_GuiState.m_Transparency);
|
||||
m_Renderer->m_ProgressParameter = reinterpret_cast<void*>(¤tStripForProgress);
|
||||
|
||||
@ -488,8 +489,9 @@ int FinalRenderEmberController<T>::ProgressFunc(Ember<T>& ember, void* foo, doub
|
||||
else if (stage == 2)
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderAccumProgress, "setValue", Qt::QueuedConnection, Q_ARG(int, intFract));
|
||||
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderImageCountLabel, "setText", Qt::QueuedConnection, Q_ARG(const QString&, ToString(m_FinishedImageCount) + " / " + ToString(m_ImageCount) + " Eta: " + QString::fromStdString(m_RenderTimer.Format(etaMs))));
|
||||
QMetaObject::invokeMethod(m_FinalRenderDialog->ui.FinalRenderTextOutput, "update", Qt::QueuedConnection);
|
||||
//QApplication::processEvents();
|
||||
|
||||
return m_Run ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -670,6 +672,7 @@ void FinalRenderEmberController<T>::RenderComplete(Ember<T>& ember)
|
||||
m_Settings->FinalScale(m_GuiState.m_Scale);
|
||||
m_Settings->FinalExt(m_GuiState.m_Ext);
|
||||
m_Settings->FinalThreadCount(m_GuiState.m_ThreadCount);
|
||||
m_Settings->FinalThreadPriority(m_GuiState.m_ThreadPriority);
|
||||
m_Settings->FinalQuality(m_GuiState.m_Quality);
|
||||
m_Settings->FinalTemporalSamples(m_GuiState.m_TemporalSamples);
|
||||
m_Settings->FinalSupersample(m_GuiState.m_Supersample);
|
||||
|
@ -38,6 +38,7 @@ struct FinalRenderGuiState
|
||||
uint m_PlatformIndex;
|
||||
uint m_DeviceIndex;
|
||||
uint m_ThreadCount;
|
||||
uint m_ThreadPriority;
|
||||
double m_WidthScale;
|
||||
double m_HeightScale;
|
||||
double m_Quality;
|
||||
|
@ -26,6 +26,7 @@ Fractorium::Fractorium(QWidget* p)
|
||||
|
||||
m_FontSize = 9;
|
||||
m_VarSortMode = 1;//Sort by weight by default.
|
||||
m_PaletteSortMode = 0;//Sort by palette ascending by default.
|
||||
m_ColorDialog = new QColorDialog(this);
|
||||
m_Settings = new FractoriumSettings(this);
|
||||
|
||||
|
@ -268,6 +268,9 @@ public slots:
|
||||
void OnPaletteCellDoubleClicked(int row, int col);
|
||||
void OnPaletteRandomSelectButtonClicked(bool checked);
|
||||
void OnPaletteRandomAdjustButtonClicked(bool checked);
|
||||
void OnPaletteFilterLineEditTextChanged(const QString& text);
|
||||
void OnPaletteFilterClearButtonClicked(bool checked);
|
||||
void OnPaletteHeaderSectionClicked(int col);
|
||||
|
||||
//Rendering/progress.
|
||||
void StartRenderTimer();
|
||||
@ -458,6 +461,7 @@ private:
|
||||
|
||||
int m_FontSize;
|
||||
int m_VarSortMode;
|
||||
int m_PaletteSortMode;
|
||||
int m_PreviousPaletteRow;
|
||||
OpenCLWrapper m_Wrapper;
|
||||
unique_ptr<FractoriumEmberControllerBase> m_Controller;
|
||||
|
@ -4866,7 +4866,7 @@ SpinBox
|
||||
<attribute name="toolTip">
|
||||
<string>List of available palette files and their palettes</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_16" rowstretch="0,0,0,0,0" columnstretch="0">
|
||||
<layout class="QGridLayout" name="gridLayout_16" rowstretch="0,0,0,0,0,0" columnstretch="0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
@ -5100,7 +5100,7 @@ SpinBox
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QTableWidget" name="PaletteListTable">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
@ -5237,6 +5237,50 @@ SpinBox
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="PaletteFilenameCombo"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="PaletteTabHLayout2" stretch="0,0">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="PaletteFilterLineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="PaletteFilterClearButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="InfoTab">
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "FractoriumPch.h"
|
||||
#include "Fractorium.h"
|
||||
#include "PaletteTableWidgetItem.h"
|
||||
|
||||
#define PALETTE_CELL_HEIGHT 16
|
||||
|
||||
@ -20,7 +21,7 @@ void Fractorium::InitPaletteUI()
|
||||
//Palette adjustment table.
|
||||
QTableWidget* table = ui.PaletteAdjustTable;
|
||||
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//Split width over all columns evenly.
|
||||
|
||||
|
||||
SetupSpinner<SpinBox, int>(table, this, row, 1, m_PaletteHueSpin, spinHeight, -180, 180, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0);
|
||||
SetupSpinner<SpinBox, int>(table, this, row, 1, m_PaletteSaturationSpin, spinHeight, -100, 100, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0);
|
||||
SetupSpinner<SpinBox, int>(table, this, row, 1, m_PaletteBrightnessSpin, spinHeight, -255, 255, 1, SIGNAL(valueChanged(int)), SLOT(OnPaletteAdjust(int)), true, 0, 0, 0);
|
||||
@ -41,8 +42,11 @@ void Fractorium::InitPaletteUI()
|
||||
QTableWidgetItem* previewPaletteItem = new QTableWidgetItem();
|
||||
palettePreviewTable->setItem(0, 1, previewPaletteItem);
|
||||
|
||||
connect(ui.PaletteFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnPaletteFilterLineEditTextChanged(const QString&)));
|
||||
connect(ui.PaletteFilterClearButton, SIGNAL(clicked(bool)), this, SLOT(OnPaletteFilterClearButtonClicked(bool)));
|
||||
paletteTable->setColumnWidth(1, 260);//256 plus small margin on each side.
|
||||
paletteTable->horizontalHeader()->setSectionsClickable(false);
|
||||
paletteTable->horizontalHeader()->setSectionsClickable(true);
|
||||
connect(paletteTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(OnPaletteHeaderSectionClicked(int)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -109,18 +113,20 @@ bool FractoriumEmberController<T>::FillPaletteTable(const string& s)
|
||||
//Palette list table.
|
||||
for (size_t i = 0; i < paletteSize; i++)
|
||||
{
|
||||
Palette<T>* p = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, i);
|
||||
vector<byte> v = p->MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);
|
||||
QTableWidgetItem* nameCol = new QTableWidgetItem(p->m_Name.c_str());
|
||||
if (auto p = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, i))
|
||||
{
|
||||
auto v = p->MakeRgbPaletteBlock(PALETTE_CELL_HEIGHT);
|
||||
auto nameCol = new QTableWidgetItem(p->m_Name.c_str());
|
||||
|
||||
nameCol->setToolTip(p->m_Name.c_str());
|
||||
paletteTable->setItem(i, 0, nameCol);
|
||||
nameCol->setToolTip(p->m_Name.c_str());
|
||||
paletteTable->setItem(i, 0, nameCol);
|
||||
|
||||
QImage image(v.data(), p->Size(), PALETTE_CELL_HEIGHT, QImage::Format_RGB888);
|
||||
QTableWidgetItem* paletteItem = new QTableWidgetItem();
|
||||
QImage image(v.data(), p->Size(), PALETTE_CELL_HEIGHT, QImage::Format_RGB888);
|
||||
auto paletteItem = new PaletteTableWidgetItem<T>(p);
|
||||
|
||||
paletteItem->setData(Qt::DecorationRole, QPixmap::fromImage(image));
|
||||
paletteTable->setItem(i, 1, paletteItem);
|
||||
paletteItem->setData(Qt::DecorationRole, QPixmap::fromImage(image));
|
||||
paletteTable->setItem(i, 1, paletteItem);
|
||||
}
|
||||
}
|
||||
|
||||
paletteTable->blockSignals(false);
|
||||
@ -138,7 +144,11 @@ bool FractoriumEmberController<T>::FillPaletteTable(const string& s)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Fractorium::OnPaletteFilenameComboChanged(const QString& text) { m_Controller->FillPaletteTable(text.toStdString()); }
|
||||
void Fractorium::OnPaletteFilenameComboChanged(const QString& text)
|
||||
{
|
||||
m_Controller->FillPaletteTable(text.toStdString());
|
||||
ui.PaletteListTable->sortItems(0, m_PaletteSortMode == 0 ? Qt::AscendingOrder : Qt::DescendingOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply adjustments to the current ember's palette.
|
||||
@ -222,13 +232,11 @@ void Fractorium::OnPaletteAdjust(int d) { m_Controller->PaletteAdjust(); }
|
||||
/// Resets the rendering process.
|
||||
/// </summary>
|
||||
/// <param name="row">The table row clicked</param>
|
||||
/// <param name="col">The table col clicked</param>
|
||||
/// <param name="col">The table column clicked</param>
|
||||
template <typename T>
|
||||
void FractoriumEmberController<T>::PaletteCellClicked(int row, int col)
|
||||
{
|
||||
Palette<T>* palette = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, row);
|
||||
|
||||
if (palette)
|
||||
if (auto palette = m_PaletteList.GetPalette(m_CurrentPaletteFilePath, row))
|
||||
{
|
||||
m_TempPalette = *palette;//Deep copy.
|
||||
ApplyPaletteToEmber();//Copy temp palette to ember palette and apply adjustments.
|
||||
@ -236,12 +244,25 @@ void FractoriumEmberController<T>::PaletteCellClicked(int row, int col)
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Map the palette in the clicked row index to the index
|
||||
/// in the palette list, then pass that index to PaletteCellClicked().
|
||||
/// This resolves the case where the sort order of the palette table
|
||||
/// is different than the internal order of the palette list.
|
||||
/// </summary>
|
||||
/// <param name="row">The table row clicked</param>
|
||||
/// <param name="col">The table column clicked, ignored</param>
|
||||
void Fractorium::OnPaletteCellClicked(int row, int col)
|
||||
{
|
||||
if (m_PreviousPaletteRow != row)
|
||||
if (auto item = dynamic_cast<PaletteTableWidgetItemBase*>(ui.PaletteListTable->item(row, 1)))
|
||||
{
|
||||
m_Controller->PaletteCellClicked(row, col);
|
||||
m_PreviousPaletteRow = row;//Save for comparison on next click.
|
||||
auto index = item->Index();
|
||||
|
||||
if (m_PreviousPaletteRow != index)
|
||||
{
|
||||
m_Controller->PaletteCellClicked(index, col);
|
||||
m_PreviousPaletteRow = index;//Save for comparison on next click.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,7 +273,7 @@ void Fractorium::OnPaletteCellClicked(int row, int col)
|
||||
/// Resets the rendering process.
|
||||
/// </summary>
|
||||
/// <param name="row">The table row clicked</param>
|
||||
/// <param name="col">The table col clicked</param>
|
||||
/// <param name="col">The table column clicked</param>
|
||||
void Fractorium::OnPaletteCellDoubleClicked(int row, int col)
|
||||
{
|
||||
ResetPaletteControls();
|
||||
@ -309,6 +330,54 @@ void Fractorium::OnPaletteRandomAdjustButtonClicked(bool checked)
|
||||
OnPaletteAdjust(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply the text in the palette filter text box to only show palettes whose names
|
||||
/// contain the substring.
|
||||
/// Called when the user types in the palette filter text box.
|
||||
/// </summary>
|
||||
/// <param name="text">The text to filter on</param>
|
||||
void Fractorium::OnPaletteFilterLineEditTextChanged(const QString& text)
|
||||
{
|
||||
auto table = ui.PaletteListTable;
|
||||
|
||||
table->setUpdatesEnabled(false);
|
||||
|
||||
for (uint i = 0; i < uint(table->rowCount()); i++)
|
||||
{
|
||||
if (auto item = table->item(i, 0))
|
||||
{
|
||||
if (!item->text().contains(text, Qt::CaseInsensitive))
|
||||
table->hideRow(i);
|
||||
else
|
||||
table->showRow(i);
|
||||
}
|
||||
}
|
||||
|
||||
ui.PaletteListTable->sortItems(0, m_PaletteSortMode == 0 ? Qt::AscendingOrder : Qt::DescendingOrder);//Must re-sort every time the filter changes.
|
||||
table->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the palette name filter, which will display all palettes.
|
||||
/// Called when clear palette filter button is clicked.
|
||||
/// </summary>
|
||||
/// <param name="checked">Ignored</param>
|
||||
void Fractorium::OnPaletteFilterClearButtonClicked(bool checked)
|
||||
{
|
||||
ui.PaletteFilterLineEdit->clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the sorting to be either ascending or descending.
|
||||
/// Called when user clicks the table headers.
|
||||
/// </summary>
|
||||
/// <param name="col">Column index of the header clicked, ignored.</param>
|
||||
void Fractorium::OnPaletteHeaderSectionClicked(int col)
|
||||
{
|
||||
m_PaletteSortMode = !m_PaletteSortMode;
|
||||
ui.PaletteListTable->sortItems(0, m_PaletteSortMode == 0 ? Qt::AscendingOrder : Qt::DescendingOrder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the palette controls.
|
||||
/// Usually in response to a palette cell double click.
|
||||
|
@ -44,6 +44,8 @@ void FractoriumSettings::EnsureDefaults()
|
||||
if (FinalThreadCount() == 0 || FinalThreadCount() > Timing::ProcessorCount())
|
||||
FinalThreadCount(Timing::ProcessorCount());
|
||||
|
||||
FinalThreadPriority(Clamp<uint>((uint)eThreadPriority::LOWEST, (uint)eThreadPriority::HIGHEST, FinalThreadPriority()));
|
||||
|
||||
if (CpuSubBatch() < 1)
|
||||
CpuSubBatch(1);
|
||||
|
||||
@ -184,6 +186,9 @@ void FractoriumSettings::FinalDeviceIndex(uint i) { setValue(FINALDEVICEINDE
|
||||
uint FractoriumSettings::FinalThreadCount() { return value(FINALTHREADCOUNT).toUInt(); }
|
||||
void FractoriumSettings::FinalThreadCount(uint i) { setValue(FINALTHREADCOUNT, i); }
|
||||
|
||||
uint FractoriumSettings::FinalThreadPriority() { return value(FINALTHREADPRIORITY).toUInt(); }
|
||||
void FractoriumSettings::FinalThreadPriority(uint i) { setValue(FINALTHREADPRIORITY, i); }
|
||||
|
||||
uint FractoriumSettings::FinalQuality() { return value(FINALQUALITY).toUInt(); }
|
||||
void FractoriumSettings::FinalQuality(uint i) { setValue(FINALQUALITY, i); }
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define FINALPLATFORMINDEX "finalrender/platformindex"
|
||||
#define FINALDEVICEINDEX "finalrender/deviceindex"
|
||||
#define FINALTHREADCOUNT "finalrender/threadcount"
|
||||
#define FINALTHREADPRIORITY "finalrender/threadpriority"
|
||||
#define FINALQUALITY "finalrender/quality"
|
||||
#define FINALTEMPORALSAMPLES "finalrender/temporalsamples"
|
||||
#define FINALSUPERSAMPLE "finalrender/supersample"
|
||||
@ -151,6 +152,9 @@ public:
|
||||
uint FinalThreadCount();
|
||||
void FinalThreadCount(uint b);
|
||||
|
||||
uint FinalThreadPriority();
|
||||
void FinalThreadPriority(uint b);
|
||||
|
||||
uint FinalQuality();
|
||||
void FinalQuality(uint i);
|
||||
|
||||
|
@ -12,7 +12,6 @@ void Fractorium::InitXformsVariationsUI()
|
||||
tree->header()->setSectionsClickable(true);
|
||||
connect(tree->header(), SIGNAL(sectionClicked(int)), this, SLOT(OnTreeHeaderSectionClicked(int)));
|
||||
connect(ui.VariationsFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVariationsFilterLineEditTextChanged(const QString&)));
|
||||
connect(ui.VariationsFilterLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(OnVariationsFilterLineEditTextChanged(const QString&)));
|
||||
connect(ui.VariationsFilterClearButton, SIGNAL(clicked(bool)), this, SLOT(OnVariationsFilterClearButtonClicked(bool)));
|
||||
|
||||
//Setting dimensions in the designer with a layout is futile, so must hard code here.
|
||||
@ -268,7 +267,7 @@ void FractoriumEmberController<T>::FillVariationTreeWithXform(Xform<T>* xform)
|
||||
|
||||
/// <summary>
|
||||
/// Change the sorting to be either by variation ID, or by weight.
|
||||
/// If sorting by variation ID, repeated clicks will altername ascending or descending.
|
||||
/// If sorting by variation ID, repeated clicks will alternate ascending or descending.
|
||||
/// Called when user clicks the tree headers.
|
||||
/// </summary>
|
||||
/// <param name="logicalIndex">Column index of the header clicked. Sort by name if 0, sort by weight if 1.</param>
|
||||
@ -277,7 +276,7 @@ void Fractorium::OnTreeHeaderSectionClicked(int logicalIndex)
|
||||
m_VarSortMode = logicalIndex;
|
||||
ui.VariationsTree->sortItems(m_VarSortMode, m_VarSortMode == 0 ? Qt::AscendingOrder : Qt::DescendingOrder);
|
||||
|
||||
if (logicalIndex == 1)
|
||||
if (m_VarSortMode == 1)
|
||||
ui.VariationsTree->scrollToTop();
|
||||
}
|
||||
|
||||
|
38
Source/Fractorium/PaletteTableWidgetItem.h
Normal file
38
Source/Fractorium/PaletteTableWidgetItem.h
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "FractoriumPch.h"
|
||||
|
||||
/// <summary>
|
||||
/// PaletteTableWidgetItem class.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// A thin derivation of QTableWidgetItem which keeps a pointer to a palette object.
|
||||
/// The lifetime of the palette object must be greater than or equal to
|
||||
/// the lifetime of this object.
|
||||
/// </summary>
|
||||
class PaletteTableWidgetItemBase : public QTableWidgetItem
|
||||
{
|
||||
public:
|
||||
PaletteTableWidgetItemBase()
|
||||
{
|
||||
}
|
||||
|
||||
virtual size_t Index() const { return 0; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class PaletteTableWidgetItem : public PaletteTableWidgetItemBase
|
||||
{
|
||||
public:
|
||||
PaletteTableWidgetItem(Palette<T>* palette)
|
||||
: m_Palette(palette)
|
||||
{
|
||||
}
|
||||
|
||||
virtual size_t Index() const override { return m_Palette->m_Index; }
|
||||
Palette<T>* GetPalette() const { return m_Palette; }
|
||||
|
||||
private:
|
||||
Palette<T>* m_Palette;
|
||||
};
|
Loading…
Reference in New Issue
Block a user