mirror of
https://bitbucket.org/mfeemster/fractorium.git
synced 2025-02-01 18:40:12 -05:00
--User changes
-Add Summary tab to the info dock, place existing bounds related info in a new Bounds tab. -Add a toolbar with the most common actions on it. -Remove old toolbar at the top of the library tab. --Code changes -Refactor code to make a color visible on a background into VisibleColor() in FractoriumCommon.h -Add IsXformLinked() to determine if an xform is linked to another. -Remove SetPaletteRefTable() and GetQRgbFromPaletteIndex() from FractoriumEmberControllerBase and its derivations, unused. -Add FillSummary() to FractoriumEmberController. Call in Update(), UpdateXform() and other places where values are changed to force an update of the summary view. -Add export statements to FractoriumInfo.cpp. -Remove image parameter from SetPaletteTableItem(), it was a bad design. -InitToolbarUI() is now empty since toolbar initialization happens automatically. Leave as a placeholder. -Refactor code to get a palette color at a given index and convert it to a QColor to ColorIndexToQColor().
This commit is contained in:
parent
fb262c2469
commit
3aa9e13194
@ -103,6 +103,7 @@ Fractorium::Fractorium(QWidget* p)
|
|||||||
InitXaosUI();
|
InitXaosUI();
|
||||||
InitPaletteUI();
|
InitPaletteUI();
|
||||||
InitLibraryUI();
|
InitLibraryUI();
|
||||||
|
InitInfoUI();
|
||||||
InitMenusUI();
|
InitMenusUI();
|
||||||
|
|
||||||
//This will init the controller and fill in the variations and palette tables with template specific instances
|
//This will init the controller and fill in the variations and palette tables with template specific instances
|
||||||
@ -175,6 +176,7 @@ Fractorium::Fractorium(QWidget* p)
|
|||||||
ui.XformPaletteRefTable->setStyleSheet("QTableWidget::item { padding: 0px; border: none; margin: 0px; }");
|
ui.XformPaletteRefTable->setStyleSheet("QTableWidget::item { padding: 0px; border: none; margin: 0px; }");
|
||||||
ui.PaletteAdjustTable->setStyleSheet("QTableWidget::item { padding: 1px; }");//Need this to avoid covering the top border pixel with the spinners.
|
ui.PaletteAdjustTable->setStyleSheet("QTableWidget::item { padding: 1px; }");//Need this to avoid covering the top border pixel with the spinners.
|
||||||
ui.statusBar->setStyleSheet("QStatusBar QLabel { padding-left: 2px; padding-right: 2px; }");
|
ui.statusBar->setStyleSheet("QStatusBar QLabel { padding-left: 2px; padding-right: 2px; }");
|
||||||
|
ui.XaosTableView->setStyleSheet("QTableView { margin: 1px}");
|
||||||
|
|
||||||
//setStyleSheet("QGroupBox { border: 2px solid gray; border-radius: 3px; } ");
|
//setStyleSheet("QGroupBox { border: 2px solid gray; border-radius: 3px; } ");
|
||||||
|
|
||||||
@ -747,7 +749,11 @@ void Fractorium::SetTabOrders()
|
|||||||
w = SetTabOrder(this, w, ui.PaletteFilterClearButton);
|
w = SetTabOrder(this, w, ui.PaletteFilterClearButton);
|
||||||
w = SetTabOrder(this, w, ui.PaletteListTable);
|
w = SetTabOrder(this, w, ui.PaletteListTable);
|
||||||
|
|
||||||
w = SetTabOrder(this, ui.InfoBoundsGroupBox, ui.InfoBoundsFrame);//Info.
|
|
||||||
|
w = SetTabOrder(this, ui.SummaryTableWidget, ui.SummaryTreeWidget);//Info summary.
|
||||||
|
|
||||||
|
w = SetTabOrder(this, ui.InfoBoundsGroupBox, ui.InfoBoundsFrame);//Info bounds.
|
||||||
|
|
||||||
w = SetTabOrder(this, w, ui.InfoBoundsTable);
|
w = SetTabOrder(this, w, ui.InfoBoundsTable);
|
||||||
w = SetTabOrder(this, w, ui.InfoFileOpeningGroupBox);
|
w = SetTabOrder(this, w, ui.InfoFileOpeningGroupBox);
|
||||||
w = SetTabOrder(this, w, ui.InfoFileOpeningTextEdit);
|
w = SetTabOrder(this, w, ui.InfoFileOpeningTextEdit);
|
||||||
|
@ -142,9 +142,6 @@ public slots:
|
|||||||
void OnActionAbout(bool checked);//Help.
|
void OnActionAbout(bool checked);//Help.
|
||||||
|
|
||||||
//Toolbar.
|
//Toolbar.
|
||||||
void OnSaveCurrentAsXmlButtonClicked(bool checked);
|
|
||||||
void OnSaveEntireFileAsXmlButtonClicked(bool checked);
|
|
||||||
void OnSaveCurrentToOpenedFileButtonClicked(bool checked);
|
|
||||||
|
|
||||||
//Library.
|
//Library.
|
||||||
void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col);
|
void OnEmberTreeItemChanged(QTreeWidgetItem* item, int col);
|
||||||
@ -275,6 +272,10 @@ public slots:
|
|||||||
void OnPaletteFilterClearButtonClicked(bool checked);
|
void OnPaletteFilterClearButtonClicked(bool checked);
|
||||||
void OnPaletteHeaderSectionClicked(int col);
|
void OnPaletteHeaderSectionClicked(int col);
|
||||||
|
|
||||||
|
//Info.
|
||||||
|
void OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize);
|
||||||
|
void OnSummaryTreeHeaderSectionClicked(int logicalIndex);
|
||||||
|
|
||||||
//Rendering/progress.
|
//Rendering/progress.
|
||||||
void StartRenderTimer();
|
void StartRenderTimer();
|
||||||
void IdleTimer();
|
void IdleTimer();
|
||||||
@ -311,6 +312,7 @@ private:
|
|||||||
void InitXaosUI();
|
void InitXaosUI();
|
||||||
void InitPaletteUI();
|
void InitPaletteUI();
|
||||||
void InitLibraryUI();
|
void InitLibraryUI();
|
||||||
|
void InitInfoUI();
|
||||||
void SetTabOrders();
|
void SetTabOrders();
|
||||||
|
|
||||||
void ToggleTableRow(QTableView* table, int logicalIndex);
|
void ToggleTableRow(QTableView* table, int logicalIndex);
|
||||||
@ -342,10 +344,13 @@ private:
|
|||||||
//Palette.
|
//Palette.
|
||||||
void ResetPaletteControls();
|
void ResetPaletteControls();
|
||||||
void SetPaletteFileComboIndex(const string& filename);
|
void SetPaletteFileComboIndex(const string& filename);
|
||||||
|
void SetPaletteTableItem(QPixmap* pixmap, QTableWidget* table, QTableWidgetItem* item, int row, int col);
|
||||||
|
|
||||||
//Info.
|
//Info.
|
||||||
|
void FillSummary();
|
||||||
void UpdateHistogramBounds();
|
void UpdateHistogramBounds();
|
||||||
void ErrorReportToQTextEdit(const vector<string>& errors, QTextEdit* textEdit, bool clear = true);
|
void ErrorReportToQTextEdit(const vector<string>& errors, QTextEdit* textEdit, bool clear = true);
|
||||||
|
void SetTableWidgetBackgroundColor();
|
||||||
|
|
||||||
//Rendering/progress.
|
//Rendering/progress.
|
||||||
bool CreateRendererFromOptions();
|
bool CreateRendererFromOptions();
|
||||||
@ -441,6 +446,14 @@ private:
|
|||||||
SpinBox* m_PaletteBlurSpin;
|
SpinBox* m_PaletteBlurSpin;
|
||||||
SpinBox* m_PaletteFrequencySpin;
|
SpinBox* m_PaletteFrequencySpin;
|
||||||
|
|
||||||
|
//Info.
|
||||||
|
QTableWidgetItem* m_InfoNameItem;
|
||||||
|
QTableWidgetItem* m_InfoPaletteItem;
|
||||||
|
QTableWidgetItem* m_Info3dItem;
|
||||||
|
QTableWidgetItem* m_InfoXaosItem;
|
||||||
|
QTableWidgetItem* m_InfoXformCountItem;
|
||||||
|
QTableWidgetItem* m_InfoFinalXformItem;
|
||||||
|
|
||||||
//Files.
|
//Files.
|
||||||
QFileDialog* m_FileDialog;
|
QFileDialog* m_FileDialog;
|
||||||
QFileDialog* m_FolderDialog;
|
QFileDialog* m_FolderDialog;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -111,3 +111,78 @@ static bool Exists(const QString& s)
|
|||||||
{
|
{
|
||||||
return s != "" && QDir(s).exists();
|
return s != "" && QDir(s).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a color to one that is displayable on any background.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">The color to convert</param>
|
||||||
|
/// <returns>The converted color</returns>
|
||||||
|
static QColor VisibleColor(const QColor& color)
|
||||||
|
{
|
||||||
|
int threshold = 105;
|
||||||
|
int delta = (color.red() * 0.299) + //Magic numbers gotten from a Stack Overflow post.
|
||||||
|
(color.green() * 0.587) +
|
||||||
|
(color.blue() * 0.114);
|
||||||
|
|
||||||
|
QColor textColor = (255 - delta < threshold) ? QColor(0, 0, 0) : QColor(255, 255, 255);
|
||||||
|
return textColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine whether an xform in an ember is linked to any other xform
|
||||||
|
/// in the ember.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ember">The ember which contains the xform</param>
|
||||||
|
/// <param name="xform">The xform to inspect</param>
|
||||||
|
/// <returns>The index of the xform that the xform argument is linked to, else -1</returns>
|
||||||
|
template <typename T>
|
||||||
|
static intmax_t IsXformLinked(Ember<T>& ember, Xform<T>* xform)
|
||||||
|
{
|
||||||
|
auto count = ember.XformCount();
|
||||||
|
auto index = ember.GetXformIndex(xform);
|
||||||
|
intmax_t linked = -1;
|
||||||
|
size_t toOneCount = 0;
|
||||||
|
size_t toZeroCount = 0;
|
||||||
|
size_t toOneIndex = 0;
|
||||||
|
size_t fromOneCount = 0;
|
||||||
|
size_t fromZeroCount = 0;
|
||||||
|
size_t fromOneIndex = 0;
|
||||||
|
|
||||||
|
if (index >= 0)
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (xform->Xaos(i) == 0)
|
||||||
|
toZeroCount++;
|
||||||
|
else if (xform->Xaos(i) == 1)
|
||||||
|
{
|
||||||
|
toOneIndex = i;
|
||||||
|
toOneCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((toZeroCount == (count - 1)) && toOneCount == 1)
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (auto fromXform = ember.GetXform(i))
|
||||||
|
{
|
||||||
|
if (fromXform->Xaos(toOneIndex) == 0)
|
||||||
|
fromZeroCount++;
|
||||||
|
else if (fromXform->Xaos(toOneIndex) == 1)
|
||||||
|
{
|
||||||
|
fromOneIndex = i;
|
||||||
|
fromOneCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fromZeroCount == (count - 1)) && fromOneCount == 1)
|
||||||
|
{
|
||||||
|
linked = toOneIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return linked;
|
||||||
|
}
|
@ -217,6 +217,7 @@ template <typename T>
|
|||||||
void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool updateRender, eProcessAction action)
|
void FractoriumEmberController<T>::Update(std::function<void (void)> func, bool updateRender, eProcessAction action)
|
||||||
{
|
{
|
||||||
func();
|
func();
|
||||||
|
FillSummary();
|
||||||
|
|
||||||
if (updateRender)
|
if (updateRender)
|
||||||
UpdateRender(action);
|
UpdateRender(action);
|
||||||
@ -294,6 +295,8 @@ void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> fu
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FillSummary();
|
||||||
|
|
||||||
if (updateRender)
|
if (updateRender)
|
||||||
UpdateRender(action);
|
UpdateRender(action);
|
||||||
}
|
}
|
||||||
@ -305,6 +308,7 @@ void FractoriumEmberController<T>::UpdateXform(std::function<void(Xform<T>*)> fu
|
|||||||
/// Resets the rendering process.
|
/// Resets the rendering process.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ember">The ember to set as the current</param>
|
/// <param name="ember">The ember to set as the current</param>
|
||||||
|
/// <param name="verbatim">If true, do not overwrite temporal samples, quality or supersample value, else overwrite.</param>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim)
|
void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool verbatim)
|
||||||
@ -335,6 +339,7 @@ void FractoriumEmberController<T>::SetEmberPrivate(const Ember<U>& ember, bool v
|
|||||||
m_GLController->ResetMouseState();
|
m_GLController->ResetMouseState();
|
||||||
FillXforms();//Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
|
FillXforms();//Must do this first because the palette setup in FillParamTablesAndPalette() uses the xforms combo.
|
||||||
FillParamTablesAndPalette();
|
FillParamTablesAndPalette();
|
||||||
|
FillSummary();
|
||||||
|
|
||||||
//If a resize happened, this won't do anything because the new size is not reflected in the scroll area yet.
|
//If a resize happened, this won't do anything because the new size is not reflected in the scroll area yet.
|
||||||
//However, it will have been taken care of in SyncSizes() in that case, so it's ok.
|
//However, it will have been taken care of in SyncSizes() in that case, so it's ok.
|
||||||
|
@ -178,7 +178,7 @@ public:
|
|||||||
virtual void XformColorSpeedChanged(double d) { }
|
virtual void XformColorSpeedChanged(double d) { }
|
||||||
virtual void XformOpacityChanged(double d) { }
|
virtual void XformOpacityChanged(double d) { }
|
||||||
virtual void XformDirectColorChanged(double d) { }
|
virtual void XformDirectColorChanged(double d) { }
|
||||||
void SetPaletteRefTable(QPixmap* pixmap);
|
virtual QColor ColorIndexToQColor(double d) { return QColor(); }
|
||||||
|
|
||||||
//Xforms Variations.
|
//Xforms Variations.
|
||||||
virtual void SetupVariationTree() { }
|
virtual void SetupVariationTree() { }
|
||||||
@ -199,11 +199,12 @@ public:
|
|||||||
virtual bool FillPaletteTable(const string& s) { return false; }
|
virtual bool FillPaletteTable(const string& s) { return false; }
|
||||||
virtual void ApplyPaletteToEmber() { }
|
virtual void ApplyPaletteToEmber() { }
|
||||||
virtual void PaletteAdjust() { }
|
virtual void PaletteAdjust() { }
|
||||||
virtual QRgb GetQRgbFromPaletteIndex(uint i) { return QRgb(); }
|
|
||||||
virtual void PaletteCellClicked(int row, int col) { }
|
virtual void PaletteCellClicked(int row, int col) { }
|
||||||
|
QImage& FinalPaletteImage() { return m_FinalPaletteImage; }
|
||||||
|
|
||||||
//Info.
|
//Info.
|
||||||
|
virtual void FillSummary() { }
|
||||||
|
|
||||||
//Rendering/progress.
|
//Rendering/progress.
|
||||||
virtual bool Render() { return false; }
|
virtual bool Render() { return false; }
|
||||||
virtual bool CreateRenderer(eRendererType renderType, uint platform, uint device, bool shared = true) { return false; }
|
virtual bool CreateRenderer(eRendererType renderType, uint platform, uint device, bool shared = true) { return false; }
|
||||||
@ -413,6 +414,7 @@ public:
|
|||||||
virtual void XformColorSpeedChanged(double d) override;
|
virtual void XformColorSpeedChanged(double d) override;
|
||||||
virtual void XformOpacityChanged(double d) override;
|
virtual void XformOpacityChanged(double d) override;
|
||||||
virtual void XformDirectColorChanged(double d) override;
|
virtual void XformDirectColorChanged(double d) override;
|
||||||
|
virtual QColor ColorIndexToQColor(double d) override;
|
||||||
void FillColorWithXform(Xform<T>* xform);
|
void FillColorWithXform(Xform<T>* xform);
|
||||||
|
|
||||||
//Xforms Variations.
|
//Xforms Variations.
|
||||||
@ -433,10 +435,10 @@ public:
|
|||||||
virtual bool FillPaletteTable(const string& s) override;
|
virtual bool FillPaletteTable(const string& s) override;
|
||||||
virtual void ApplyPaletteToEmber() override;
|
virtual void ApplyPaletteToEmber() override;
|
||||||
virtual void PaletteAdjust() override;
|
virtual void PaletteAdjust() override;
|
||||||
virtual QRgb GetQRgbFromPaletteIndex(uint i) override { return QRgb(); }
|
|
||||||
virtual void PaletteCellClicked(int row, int col) override;
|
virtual void PaletteCellClicked(int row, int col) override;
|
||||||
|
|
||||||
//Info.
|
//Info.
|
||||||
|
virtual void FillSummary() override;
|
||||||
|
|
||||||
//Rendering/progress.
|
//Rendering/progress.
|
||||||
virtual bool Render() override;
|
virtual bool Render() override;
|
||||||
|
@ -1,6 +1,219 @@
|
|||||||
#include "FractoriumPch.h"
|
#include "FractoriumPch.h"
|
||||||
#include "Fractorium.h"
|
#include "Fractorium.h"
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize the info UI.
|
||||||
|
/// </summary>
|
||||||
|
void Fractorium::InitInfoUI()
|
||||||
|
{
|
||||||
|
auto treeHeader = ui.SummaryTreeWidget->header();
|
||||||
|
auto tableHeader = ui.SummaryTableWidget->horizontalHeader();
|
||||||
|
|
||||||
|
treeHeader->setVisible(true);
|
||||||
|
treeHeader->setSectionsClickable(true);
|
||||||
|
treeHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
connect(treeHeader, SIGNAL(sectionClicked(int)), this, SLOT(OnSummaryTreeHeaderSectionClicked(int)), Qt::QueuedConnection);
|
||||||
|
connect(tableHeader, SIGNAL(sectionResized(int, int, int)), this, SLOT(OnSummaryTableHeaderResized(int, int, int)), Qt::QueuedConnection);
|
||||||
|
SetFixedTableHeader(ui.SummaryTableWidget->verticalHeader());
|
||||||
|
|
||||||
|
ui.SummaryTableWidget->setItem(0, 0, m_InfoNameItem = new QTableWidgetItem(""));
|
||||||
|
ui.SummaryTableWidget->setItem(1, 0, m_InfoPaletteItem = new QTableWidgetItem(""));
|
||||||
|
ui.SummaryTableWidget->setItem(2, 0, m_Info3dItem = new QTableWidgetItem(""));
|
||||||
|
ui.SummaryTableWidget->setItem(3, 0, m_InfoXaosItem = new QTableWidgetItem(""));
|
||||||
|
ui.SummaryTableWidget->setItem(4, 0, m_InfoXformCountItem = new QTableWidgetItem(""));
|
||||||
|
ui.SummaryTableWidget->setItem(5, 0, m_InfoFinalXformItem = new QTableWidgetItem(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the palette cell of the summary table is resized in response
|
||||||
|
/// to a resizing of the Info dock.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logicalIndex">Ignored</param>
|
||||||
|
/// <param name="oldSize">Ignored</param>
|
||||||
|
/// <param name="newSize">Ignored</param>
|
||||||
|
void Fractorium::OnSummaryTableHeaderResized(int logicalIndex, int oldSize, int newSize)
|
||||||
|
{
|
||||||
|
QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage());//Create a QPixmap out of the QImage.
|
||||||
|
SetPaletteTableItem(&pixmap, ui.SummaryTableWidget, m_InfoPaletteItem, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expand or collapse the summary tree depending on the column index clicked.
|
||||||
|
/// 0: collapse, 1: expand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logicalIndex">The column which was clicked</param>
|
||||||
|
void Fractorium::OnSummaryTreeHeaderSectionClicked(int logicalIndex)
|
||||||
|
{
|
||||||
|
auto tree = ui.SummaryTreeWidget;
|
||||||
|
|
||||||
|
if (logicalIndex)
|
||||||
|
tree->expandAll();
|
||||||
|
else
|
||||||
|
tree->collapseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fill the summary tree with values from the current ember.
|
||||||
|
/// This is meant to be a rough summary by containing only the most relevant
|
||||||
|
/// values from the ember.
|
||||||
|
/// It's also meant to be used in a fire-and-forget way. Once the tree is filled
|
||||||
|
/// individual nodes are never referenced again.
|
||||||
|
/// The entire tree is cleared and refilled for every field change.
|
||||||
|
/// This would seem inefficient, but it appears to update with no flicker.
|
||||||
|
/// If this ever presents a problem in the future, revisit with a more
|
||||||
|
/// intelligent design.
|
||||||
|
/// </summary>
|
||||||
|
template <typename T>
|
||||||
|
void FractoriumEmberController<T>::FillSummary()
|
||||||
|
{
|
||||||
|
int p = 3;
|
||||||
|
int vp = 4;
|
||||||
|
int vlen = 7;
|
||||||
|
char pc = 'f';
|
||||||
|
size_t x = 0, total = m_Ember.TotalXformCount();
|
||||||
|
Xform<T>* xform = nullptr;
|
||||||
|
QColor color;
|
||||||
|
auto table = m_Fractorium->ui.SummaryTableWidget;
|
||||||
|
auto tree = m_Fractorium->ui.SummaryTreeWidget;
|
||||||
|
QVariantList states;
|
||||||
|
QTreeWidgetItemIterator it(tree);
|
||||||
|
|
||||||
|
while (*it)
|
||||||
|
{
|
||||||
|
if (!(*it)->parent())//Top level only.
|
||||||
|
states += (*it)->isExpanded();
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
tree->blockSignals(true);
|
||||||
|
tree->clear();
|
||||||
|
m_Fractorium->m_InfoNameItem->setText(m_Ember.m_Name.c_str());
|
||||||
|
m_Fractorium->m_Info3dItem->setText(m_Ember.ProjBits() ? "Yes" : "No");
|
||||||
|
m_Fractorium->m_InfoXaosItem->setText(m_Ember.XaosPresent() ? "Yes" : "No");
|
||||||
|
m_Fractorium->m_InfoXformCountItem->setText(QString::number(m_Ember.XformCount()));
|
||||||
|
m_Fractorium->m_InfoFinalXformItem->setText(m_Ember.UseFinalXform() ? "Yes" : "No");
|
||||||
|
|
||||||
|
QPixmap pixmap = QPixmap::fromImage(m_FinalPaletteImage);//Create a QPixmap out of the QImage.
|
||||||
|
QSize size(table->columnWidth(0), table->rowHeight(1) + 1);
|
||||||
|
m_Fractorium->m_InfoPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
|
||||||
|
for (x = 0; x < total && (xform = m_Ember.GetTotalXform(x)); x++)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
QString as = "Pre";
|
||||||
|
auto item1 = new QTreeWidgetItem(tree);
|
||||||
|
intmax_t linkedIndex = IsXformLinked(m_Ember, xform);
|
||||||
|
QString linked = (linkedIndex != -1) ? (" Linked to " + QString::number(linkedIndex + 1)) : "";
|
||||||
|
auto index = m_Ember.GetXformIndex(xform);
|
||||||
|
m_Ember.CalcNormalizedWeights(m_NormalizedWeights);
|
||||||
|
|
||||||
|
if (!m_Ember.IsFinalXform(xform) && index != -1)
|
||||||
|
{
|
||||||
|
item1->setText(0, "Xform " +
|
||||||
|
QString::number(x + 1) +
|
||||||
|
" (" + QLocale::system().toString(xform->m_Weight, pc, p) + ") (" +
|
||||||
|
QLocale::system().toString(double(m_NormalizedWeights[index]), pc, p) + ") " +
|
||||||
|
linked);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
item1->setText(0, "Final xform");
|
||||||
|
|
||||||
|
item1->setText(1, xform->m_Name.c_str());
|
||||||
|
|
||||||
|
auto affineItem = new QTreeWidgetItem(item1);
|
||||||
|
affineItem->setText(0, "Affine");
|
||||||
|
|
||||||
|
if (xform->m_Affine.IsZero())
|
||||||
|
as += " Empty";
|
||||||
|
else if (xform->m_Affine.IsID())
|
||||||
|
as += " ID";
|
||||||
|
|
||||||
|
if (xform->HasPost())
|
||||||
|
{
|
||||||
|
as += ", Post";
|
||||||
|
|
||||||
|
if (xform->m_Post.IsZero())
|
||||||
|
as += " Empty";//Don't need to check further for IsID() because post is not included if it's ID.
|
||||||
|
}
|
||||||
|
|
||||||
|
affineItem->setText(1, as);
|
||||||
|
|
||||||
|
auto colorIndexItem = new QTreeWidgetItem(item1);
|
||||||
|
colorIndexItem->setText(0, "Color index");
|
||||||
|
colorIndexItem->setText(1, QLocale::system().toString(xform->m_ColorX, pc, p));
|
||||||
|
color = ColorIndexToQColor(xform->m_ColorX);
|
||||||
|
color.setAlphaF(xform->m_Opacity);
|
||||||
|
colorIndexItem->setBackgroundColor(1, color);
|
||||||
|
colorIndexItem->setTextColor(1, VisibleColor(color));
|
||||||
|
|
||||||
|
auto colorSpeedItem = new QTreeWidgetItem(item1);
|
||||||
|
colorSpeedItem->setText(0, "Color speed");
|
||||||
|
colorSpeedItem->setText(1, QLocale::system().toString(xform->m_ColorSpeed, pc, p));
|
||||||
|
|
||||||
|
auto opacityItem = new QTreeWidgetItem(item1);
|
||||||
|
opacityItem->setText(0, "Opacity");
|
||||||
|
opacityItem->setText(1, QLocale::system().toString(xform->m_Opacity, pc, p));
|
||||||
|
|
||||||
|
auto dcItem = new QTreeWidgetItem(item1);
|
||||||
|
dcItem->setText(0, "Direct color");
|
||||||
|
dcItem->setText(1, QLocale::system().toString(xform->m_DirectColor, pc, p));
|
||||||
|
|
||||||
|
while (auto var = xform->GetVariation(i++))
|
||||||
|
{
|
||||||
|
auto vitem = new QTreeWidgetItem(item1);
|
||||||
|
|
||||||
|
vitem->setText(0, QString::fromStdString(var->Name()));
|
||||||
|
vitem->setText(1, QLocale::system().toString(var->m_Weight, pc, vp).rightJustified(vlen, ' '));
|
||||||
|
|
||||||
|
if (auto parVar = dynamic_cast<ParametricVariation<T>*>(var))
|
||||||
|
{
|
||||||
|
auto params = parVar->Params();
|
||||||
|
|
||||||
|
for (auto j = 0; j < parVar->ParamCount(); j++)
|
||||||
|
{
|
||||||
|
if (!params[j].IsPrecalc())
|
||||||
|
{
|
||||||
|
auto pitem = new QTreeWidgetItem(vitem);
|
||||||
|
|
||||||
|
pitem->setText(0, params[j].Name().c_str());
|
||||||
|
pitem->setText(1, QLocale::system().toString(params[j].ParamVal(), pc, vp).rightJustified(vlen, ' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto item2 = new QTreeWidgetItem(tree);//Empty item in between xforms.
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItemIterator it2(tree);
|
||||||
|
|
||||||
|
if (!states.isEmpty())
|
||||||
|
{
|
||||||
|
while (*it2)
|
||||||
|
{
|
||||||
|
if (!(*it2)->parent())//Top level only.
|
||||||
|
{
|
||||||
|
if (!states.isEmpty())
|
||||||
|
(*it2)->setExpanded(states.takeFirst().toBool());
|
||||||
|
else
|
||||||
|
(*it2)->setExpanded(true);//Expand any remainder when going from lesser to greater number of xforms.
|
||||||
|
}
|
||||||
|
|
||||||
|
++it2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tree->expandAll();
|
||||||
|
|
||||||
|
tree->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fractorium::FillSummary()
|
||||||
|
{
|
||||||
|
m_Controller->FillSummary();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update the histogram bounds display labels.
|
/// Update the histogram bounds display labels.
|
||||||
/// This shows the user the actual bounds of what's
|
/// This shows the user the actual bounds of what's
|
||||||
@ -54,3 +267,9 @@ void Fractorium::ErrorReportToQTextEdit(const vector<string>& errors, QTextEdit*
|
|||||||
for (auto& error : errors)
|
for (auto& error : errors)
|
||||||
QMetaObject::invokeMethod(textEdit, "append", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(error) + "\n"));
|
QMetaObject::invokeMethod(textEdit, "append", Qt::QueuedConnection, Q_ARG(const QString&, QString::fromStdString(error) + "\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class FractoriumEmberController<float>;
|
||||||
|
|
||||||
|
#ifdef DO_DOUBLE
|
||||||
|
template class FractoriumEmberController<double>;
|
||||||
|
#endif
|
||||||
|
@ -226,8 +226,9 @@ void FractoriumEmberController<T>::EmberTreeItemChanged(QTreeWidgetItem* item, i
|
|||||||
m_Ember.m_Name = newName;
|
m_Ember.m_Name = newName;
|
||||||
m_LastSaveCurrent = "";//Reset will force the dialog to show on the next save current since the user probably wants a different name.
|
m_LastSaveCurrent = "";//Reset will force the dialog to show on the next save current since the user probably wants a different name.
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->blockSignals(false);
|
tree->blockSignals(false);
|
||||||
|
FillSummary();
|
||||||
}
|
}
|
||||||
else if (QTreeWidgetItem* parentItem = dynamic_cast<QTreeWidgetItem*>(item))
|
else if (QTreeWidgetItem* parentItem = dynamic_cast<QTreeWidgetItem*>(item))
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,7 @@ void FractoriumEmberController<T>::UpdateAdjustedPaletteGUI(Palette<T>& palette)
|
|||||||
memcpy(m_FinalPaletteImage.scanLine(0), v.data(), v.size() * sizeof(v[0]));//Memcpy the data in.
|
memcpy(m_FinalPaletteImage.scanLine(0), v.data(), v.size() * sizeof(v[0]));//Memcpy the data in.
|
||||||
QPixmap pixmap = QPixmap::fromImage(m_FinalPaletteImage);//Create a QPixmap out of the QImage.
|
QPixmap pixmap = QPixmap::fromImage(m_FinalPaletteImage);//Create a QPixmap out of the QImage.
|
||||||
previewPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(QSize(pixmap.width(), palettePreviewTable->rowHeight(0) + 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));//Set the pixmap on the palette tab.
|
previewPaletteItem->setData(Qt::DecorationRole, pixmap.scaled(QSize(pixmap.width(), palettePreviewTable->rowHeight(0) + 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));//Set the pixmap on the palette tab.
|
||||||
SetPaletteRefTable(&pixmap);//Set the palette ref table on the xforms | color tab.
|
m_Fractorium->SetPaletteTableItem(&pixmap, m_Fractorium->ui.XformPaletteRefTable, m_Fractorium->m_PaletteRefItem, 0, 0);//Set the palette ref table on the xforms | color tab.
|
||||||
|
|
||||||
QTableWidgetItem* previewNameItem = palettePreviewTable->item(0, 0);
|
QTableWidgetItem* previewNameItem = palettePreviewTable->item(0, 0);
|
||||||
previewNameItem->setText(paletteName);//Finally, set the name of the palette to be both the text and the tooltip.
|
previewNameItem->setText(paletteName);//Finally, set the name of the palette to be both the text and the tooltip.
|
||||||
|
@ -183,13 +183,7 @@ void FractoriumEmberController<T>::BackgroundChanged(const QColor& color)
|
|||||||
QString g = ToString(color.green());
|
QString g = ToString(color.green());
|
||||||
QString b = ToString(color.blue());
|
QString b = ToString(color.blue());
|
||||||
|
|
||||||
int threshold = 105;
|
colorTable->item(itemRow, 1)->setTextColor(VisibleColor(color));
|
||||||
int delta = (color.red() * 0.299) + //Magic numbers gotten from a Stack Overflow post.
|
|
||||||
(color.green() * 0.587) +
|
|
||||||
(color.blue() * 0.114);
|
|
||||||
|
|
||||||
QColor textColor = (255 - delta < threshold) ? QColor(0, 0, 0) : QColor(255, 255, 255);
|
|
||||||
colorTable->item(itemRow, 1)->setTextColor(textColor);
|
|
||||||
colorTable->item(itemRow, 1)->setText("rgb(" + r + ", " + g + ", " + b + ")");
|
colorTable->item(itemRow, 1)->setText("rgb(" + r + ", " + g + ", " + b + ")");
|
||||||
|
|
||||||
//Color is 0-255, normalize to 0-1.
|
//Color is 0-255, normalize to 0-1.
|
||||||
|
@ -6,16 +6,5 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void Fractorium::InitToolbarUI()
|
void Fractorium::InitToolbarUI()
|
||||||
{
|
{
|
||||||
//These aren't menus but duplicate menu functionality in a pseudo-toolbar.
|
//Empty for the moment, all functionality is handled in the designer.
|
||||||
connect(ui.SaveCurrentAsXmlButton, SIGNAL(clicked(bool)), this, SLOT(OnSaveCurrentAsXmlButtonClicked(bool)), Qt::QueuedConnection);
|
|
||||||
connect(ui.SaveEntireFileAsXmlButton, SIGNAL(clicked(bool)), this, SLOT(OnSaveEntireFileAsXmlButtonClicked(bool)), Qt::QueuedConnection);
|
|
||||||
connect(ui.SaveCurrentToOpenedFileButton, SIGNAL(clicked(bool)), this, SLOT(OnSaveCurrentToOpenedFileButtonClicked(bool)), Qt::QueuedConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Wrappers around calls to menu items.
|
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
void Fractorium::OnSaveCurrentAsXmlButtonClicked(bool checked) { OnActionSaveCurrentAsXml(checked); }
|
|
||||||
void Fractorium::OnSaveEntireFileAsXmlButtonClicked(bool checked) { OnActionSaveEntireFileAsXml(checked); }
|
|
||||||
void Fractorium::OnSaveCurrentToOpenedFileButtonClicked(bool checked) { OnActionSaveCurrentToOpenedFile(checked); }
|
|
||||||
|
@ -150,8 +150,8 @@ void Fractorium::InitXformsAffineUI()
|
|||||||
|
|
||||||
//Further, the size of the dock widget won't be properly adjusted until the xforms tab is shown.
|
//Further, the size of the dock widget won't be properly adjusted until the xforms tab is shown.
|
||||||
//So show it here and it will be switched back in Fractorium's constructor.
|
//So show it here and it will be switched back in Fractorium's constructor.
|
||||||
//ui.ParamsTabWidget->setCurrentIndex(2);
|
//ui.ParamsTabWidget->setCurrentIndex(2);
|
||||||
//ui.DockWidget->update();
|
//ui.DockWidget->update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Placing pointers to the spin boxes in arrays makes them easier to access in various places.
|
//Placing pointers to the spin boxes in arrays makes them easier to access in various places.
|
||||||
|
@ -142,7 +142,9 @@ void Fractorium::OnSoloXformCheckBoxStateChanged(int state)
|
|||||||
/// <param name="newSize">Ignored</param>
|
/// <param name="newSize">Ignored</param>
|
||||||
void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize)
|
void Fractorium::OnXformRefPaletteResized(int logicalIndex, int oldSize, int newSize)
|
||||||
{
|
{
|
||||||
m_Controller->SetPaletteRefTable(nullptr);
|
QPixmap pixmap = QPixmap::fromImage(m_Controller->FinalPaletteImage());
|
||||||
|
|
||||||
|
SetPaletteTableItem(&pixmap, ui.XformPaletteRefTable, m_PaletteRefItem, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -194,6 +196,25 @@ void Fractorium::OnCurvesRedRadioButtonToggled(bool checked) { if (checked) ui
|
|||||||
void Fractorium::OnCurvesGreenRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::GREEN); }
|
void Fractorium::OnCurvesGreenRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::GREEN); }
|
||||||
void Fractorium::OnCurvesBlueRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::BLUE); }
|
void Fractorium::OnCurvesBlueRadioButtonToggled(bool checked) { if (checked) ui.CurvesView->SetTop(CurveIndex::BLUE); }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Look up the passed in index in the current ember's palette
|
||||||
|
/// and return the QColor equivalent.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="d">The palette index to look up, 0-1.</param>
|
||||||
|
/// <returns>The palette color at the given index as a QColor</returns>
|
||||||
|
template <typename T>
|
||||||
|
QColor FractoriumEmberController<T>::ColorIndexToQColor(double d)
|
||||||
|
{
|
||||||
|
v4T entry = m_Ember.m_Palette[Clamp<int>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())];
|
||||||
|
|
||||||
|
entry.r *= 255;
|
||||||
|
entry.g *= 255;
|
||||||
|
entry.b *= 255;
|
||||||
|
|
||||||
|
QRgb rgb = uint(entry.r) << 16 | uint(entry.g) << 8 | uint(entry.b);
|
||||||
|
return QColor::fromRgb(rgb);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the selected xforms color index to the passed in value.
|
/// Set the selected xforms color index to the passed in value.
|
||||||
/// Set the color cell in the palette ref table.
|
/// Set the color cell in the palette ref table.
|
||||||
@ -207,14 +228,7 @@ void FractoriumEmberController<T>::SetCurrentXformColorIndex(double d, bool upda
|
|||||||
xform->m_ColorX = Clamp<T>(d, 0, 1);
|
xform->m_ColorX = Clamp<T>(d, 0, 1);
|
||||||
|
|
||||||
//Grab the current color from the index and assign it to the first cell of the first table.
|
//Grab the current color from the index and assign it to the first cell of the first table.
|
||||||
v4T entry = m_Ember.m_Palette[Clamp<int>(d * COLORMAP_LENGTH_MINUS_1, 0, m_Ember.m_Palette.Size())];
|
m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(ColorIndexToQColor(xform->m_ColorX)/*QColor::fromRgb(rgb)*/);
|
||||||
|
|
||||||
entry.r *= 255;
|
|
||||||
entry.g *= 255;
|
|
||||||
entry.b *= 255;
|
|
||||||
|
|
||||||
QRgb rgb = uint(entry.r) << 16 | uint(entry.g) << 8 | uint(entry.b);
|
|
||||||
m_Fractorium->ui.XformColorIndexTable->item(0, 0)->setBackgroundColor(QColor::fromRgb(rgb));
|
|
||||||
}, eXformUpdate::UPDATE_SELECTED, updateRender);
|
}, eXformUpdate::UPDATE_SELECTED, updateRender);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,22 +271,19 @@ void FractoriumEmberController<T>::FillColorWithXform(Xform<T>* xform)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the palette reference table to the passed in pixmap
|
/// Set the cell at the row and column in the passed in table to the passed in pixmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pixmap">The pixmap</param>
|
/// <param name="pixmap">The pixmap to assign</param>
|
||||||
void FractoriumEmberControllerBase::SetPaletteRefTable(QPixmap* pixmap)
|
/// <param name="table">The table whose cell will be filled with the image</param>
|
||||||
|
/// <param name="item">The QTableWidgetItem in the cell</param>
|
||||||
|
/// <param name="row">The row of the cell</param>
|
||||||
|
/// <param name="col">The column of the cell</param>
|
||||||
|
void Fractorium::SetPaletteTableItem(QPixmap* pixmap, QTableWidget* table, QTableWidgetItem* item, int row, int col)
|
||||||
{
|
{
|
||||||
QSize size(m_Fractorium->ui.XformPaletteRefTable->columnWidth(0), m_Fractorium->ui.XformPaletteRefTable->rowHeight(0) + 1);
|
|
||||||
|
|
||||||
if (pixmap)
|
if (pixmap)
|
||||||
{
|
{
|
||||||
m_Fractorium->m_PaletteRefItem->setData(Qt::DecorationRole, pixmap->scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
QSize size(table->columnWidth(col), table->rowHeight(row) + 1);
|
||||||
}
|
item->setData(Qt::DecorationRole, pixmap->scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
else if (!m_FinalPaletteImage.isNull())
|
|
||||||
{
|
|
||||||
QPixmap pixTemp = QPixmap::fromImage(m_FinalPaletteImage);
|
|
||||||
|
|
||||||
m_Fractorium->m_PaletteRefItem->setData(Qt::DecorationRole, pixTemp.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
|
|||||||
{
|
{
|
||||||
if (xformParVar->SetParamVal(sender->ParamName().c_str(), d))
|
if (xformParVar->SetParamVal(sender->ParamName().c_str(), d))
|
||||||
{
|
{
|
||||||
|
FillSummary();
|
||||||
UpdateRender();
|
UpdateRender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +204,7 @@ void FractoriumEmberController<T>::VariationSpinBoxValueChanged(double d)//Would
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FillSummary();
|
||||||
UpdateRender();
|
UpdateRender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>300</width>
|
<width>300</width>
|
||||||
<height>347</height>
|
<height>368</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -19,13 +19,13 @@
|
|||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>300</width>
|
<width>300</width>
|
||||||
<height>347</height>
|
<height>368</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize">
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>300</width>
|
<width>300</width>
|
||||||
<height>347</height>
|
<height>368</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
Loading…
Reference in New Issue
Block a user