--User changes

-Add new style sheet called uranium that is reminiscent of the old Winamp color scheme of the same name.
 -All for keyboard presses to edit affines.
 --Q: rotate counter clockwise.
 --E: rotate clockwise.
 --W: move up.
 --S: move down.
 --A: move left.
 --D: move right.
 --G: shrink.
 --H: grow.
 --Hold shift to decrease amount, control to increase amount.
 -Change some menu shortcuts to accommodate these new affine editing shortcuts.
 -Random xaos now just provides values of either 0 or 1. Hold control to get the old behavior.

--Bug fixes
 -Waffle variation was broken in OpenCL.
This commit is contained in:
Person
2020-01-14 20:08:27 -08:00
parent 75ffc2f665
commit ed35622928
13 changed files with 1067 additions and 42 deletions

View File

@ -360,6 +360,14 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
static int fcount = 0;//Qt seems to deliver three events for every key press. So a count must be kept to only respond to the third event.
static int xfupcount = 0;
static int xfdncount = 0;
static int wcount = 0;
static int scount = 0;
static int acount = 0;
static int dcount = 0;
static int qcount = 0;
static int ecount = 0;
static int gcount = 0;
static int hcount = 0;
if (o == ui.GLParentScrollArea && e->type() == QEvent::Resize)
{
@ -406,10 +414,45 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
auto focusedctrlEdit = dynamic_cast<QLineEdit*>(this->focusWidget());
auto focusedctrlSpin = dynamic_cast<QSpinBox*>(this->focusWidget());
auto focusedctrlDblSpin = dynamic_cast<QDoubleSpinBox*>(this->focusWidget());
auto focusedctrlCombo = dynamic_cast<QComboBox*>(this->focusWidget());
if (!focusedctrlEdit && !focusedctrlSpin && !focusedctrlDblSpin)//Must exclude these because otherwise, typing a minus key in any of the spinners will switch the xform.
if (!focusedctrlEdit &&
!focusedctrlSpin &&
!focusedctrlDblSpin &&
!focusedctrlCombo)//Must exclude these because otherwise, typing a minus key in any of the spinners will switch the xform.
{
unsigned int index = combo->currentIndex();
double vdist = 0.01;
double hdist = 0.01;
double rot = 1;
double grow = 0.01;
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
bool pre = true;
if (auto r = m_Controller->Renderer())
{
hdist = std::abs(r->UpperRightX() - r->LowerLeftX()) * 0.01 * m_Controller->AffineScaleLockedToCurrent();
vdist = std::abs(r->UpperRightY() - r->LowerLeftY()) * 0.01 * m_Controller->AffineScaleLockedToCurrent();
if (shift)
{
hdist *= 0.1;
vdist *= 0.1;
rot *= 0.1;
grow *= 0.1;
}
else if (ctrl)
{
hdist *= 10;
vdist *= 10;
rot *= 10;
grow *= 10;
}
}
if (m_Controller.get() && m_Controller->GLController())
pre = m_Controller->GLController()->AffineType() == eAffineType::AffinePre;
if (ke->key() == Qt::Key_Plus || ke->key() == Qt::Key_Equal)
{
@ -441,6 +484,94 @@ bool Fractorium::eventFilter(QObject* o, QEvent* e)
return true;
}
else if (ke->key() == Qt::Key_W)
{
wcount++;
if (wcount >= 3)
{
wcount = 0;
m_Controller->MoveXforms(0, vdist, pre);
}
return true;
}
else if (ke->key() == Qt::Key_S)
{
scount++;
if (scount >= 3)
{
scount = 0;
m_Controller->MoveXforms(0, -vdist, pre);
}
return true;
}
else if (ke->key() == Qt::Key_A)
{
acount++;
if (acount >= 3)
{
acount = 0;
m_Controller->MoveXforms(-hdist, 0, pre);
}
return true;
}
else if (ke->key() == Qt::Key_D)
{
dcount++;
if (dcount >= 3)
{
dcount = 0;
m_Controller->MoveXforms(hdist, 0, pre);
}
return true;
}
else if (ke->key() == Qt::Key_Q)
{
qcount++;
if (qcount >= 3)
{
qcount = 0;
m_Controller->RotateXformsByAngle(-rot, pre);
}
}
else if (ke->key() == Qt::Key_E)
{
ecount++;
if (ecount >= 3)
{
ecount = 0;
m_Controller->RotateXformsByAngle(rot, pre);
}
}
else if (ke->key() == Qt::Key_G)
{
gcount++;
if (gcount >= 3)
{
gcount = 0;
m_Controller->ScaleXforms(1 - grow, pre);
}
}
else if (ke->key() == Qt::Key_H)
{
hcount++;
if (hcount >= 3)
{
hcount = 0;
m_Controller->ScaleXforms(1 + grow, pre);
}
}
}
}
}
@ -1011,6 +1142,7 @@ void Fractorium::SetTabOrders()
/// The logic is:
/// If any cell in the row is non zero, set all cells to zero, else 1.
/// If shift is held down, reverse the logic.
/// If ctrl is held down, set each cell to a random 0 or 1.
/// Resets the rendering process.
/// </summary>
/// <param name="table">The QTableWidget or QTableView whose row will be toggled</param>
@ -1021,6 +1153,7 @@ void Fractorium::ToggleTableRow(QTableView* table, int logicalIndex)
auto model = table->model();
int cols = model->columnCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
auto tableWidget = qobject_cast<QTableWidget*>(table);
if (tableWidget)
@ -1044,7 +1177,10 @@ void Fractorium::ToggleTableRow(QTableView* table, int logicalIndex)
for (int i = 0; i < cols; i++)
if (auto spinBox = qobject_cast<DoubleSpinBox*>(tableWidget->cellWidget(logicalIndex, i)))
spinBox->setValue(val);
if (ctrl)
spinBox->setValue(double(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRandBit()));
else
spinBox->setValue(val);
}
else
{
@ -1063,7 +1199,10 @@ void Fractorium::ToggleTableRow(QTableView* table, int logicalIndex)
double val = allZero ? 1.0 : 0.0;
for (int i = 0; i < cols; i++)
model->setData(model->index(logicalIndex, i), val, Qt::EditRole);
if (ctrl)
model->setData(model->index(logicalIndex, i), double(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRandBit()), Qt::EditRole);
else
model->setData(model->index(logicalIndex, i), val, Qt::EditRole);
}
}
@ -1072,6 +1211,7 @@ void Fractorium::ToggleTableRow(QTableView* table, int logicalIndex)
/// The logic is:
/// If any cell in the column is non zero, set all cells to zero, else 1.
/// If shift is held down, reverse the logic.
/// If ctrl is held down, set each cell to a random 0 or 1.
/// Resets the rendering process.
/// </summary>
/// <param name="table">The QTableWidget or QTableView whose column will be toggled</param>
@ -1082,6 +1222,7 @@ void Fractorium::ToggleTableCol(QTableView* table, int logicalIndex)
auto model = table->model();
int rows = model->rowCount();
bool shift = QGuiApplication::keyboardModifiers().testFlag(Qt::ShiftModifier);
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
auto tableWidget = qobject_cast<QTableWidget*>(table);
if (tableWidget)
@ -1105,7 +1246,10 @@ void Fractorium::ToggleTableCol(QTableView* table, int logicalIndex)
for (int i = 0; i < rows; i++)
if (auto spinBox = qobject_cast<DoubleSpinBox*>(tableWidget->cellWidget(i, logicalIndex)))
spinBox->setValue(val);
if (ctrl)
spinBox->setValue(double(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRandBit()));
else
spinBox->setValue(val);
}
else
{
@ -1124,7 +1268,10 @@ void Fractorium::ToggleTableCol(QTableView* table, int logicalIndex)
double val = allZero ? 1.0 : 0.0;
for (int i = 0; i < rows; i++)
model->setData(model->index(i, logicalIndex), val, Qt::EditRole);
if (ctrl)
model->setData(model->index(i, logicalIndex), double(QTIsaac<ISAAC_SIZE, ISAAC_INT>::LockedRandBit()), Qt::EditRole);
else
model->setData(model->index(i, logicalIndex), val, Qt::EditRole);
}
}

View File

@ -2784,7 +2784,10 @@
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
@ -4321,7 +4324,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units right</string>
<string>Move xform x units right (D)</string>
</property>
<property name="text">
<string/>
@ -4373,7 +4376,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units up</string>
<string>Move xform x units up (W)</string>
</property>
<property name="text">
<string/>
@ -4457,7 +4460,7 @@
</size>
</property>
<property name="toolTip">
<string>Scale xform x percent up</string>
<string>Scale xform x percent up (H)</string>
</property>
<property name="text">
<string/>
@ -4483,7 +4486,7 @@
</size>
</property>
<property name="toolTip">
<string>Scale xform x percent down</string>
<string>Scale xform x percent down (G)</string>
</property>
<property name="text">
<string/>
@ -4601,7 +4604,7 @@
</size>
</property>
<property name="toolTip">
<string>Rotate xform x degrees clockwise</string>
<string>Rotate xform x degrees clockwise (E)</string>
</property>
<property name="text">
<string/>
@ -4627,7 +4630,7 @@
</size>
</property>
<property name="toolTip">
<string>Rotate xform x degrees counter clockwise</string>
<string>Rotate xform x degrees counter clockwise (Q)</string>
</property>
<property name="text">
<string/>
@ -4732,7 +4735,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units left</string>
<string>Move xform x units left (A)</string>
</property>
<property name="text">
<string/>
@ -4791,7 +4794,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units down</string>
<string>Move xform x units down (S)</string>
</property>
<property name="text">
<string/>
@ -5156,7 +5159,7 @@
</size>
</property>
<property name="toolTip">
<string>Rotate xform x degrees clockwise</string>
<string>Rotate xform x degrees clockwise (E)</string>
</property>
<property name="text">
<string/>
@ -5185,7 +5188,7 @@
</size>
</property>
<property name="toolTip">
<string>Rotate xform x degrees counter clockwise</string>
<string>Rotate xform x degrees counter clockwise (Q)</string>
</property>
<property name="text">
<string/>
@ -5385,7 +5388,7 @@
</size>
</property>
<property name="toolTip">
<string>Scale xform x percent up</string>
<string>Scale xform x percent up (H)</string>
</property>
<property name="text">
<string/>
@ -5414,7 +5417,7 @@
</size>
</property>
<property name="toolTip">
<string>Scale xform x percent down</string>
<string>Scale xform x percent down (G)</string>
</property>
<property name="text">
<string/>
@ -5443,7 +5446,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units left</string>
<string>Move xform x units left (A)</string>
</property>
<property name="text">
<string/>
@ -5508,7 +5511,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units right</string>
<string>Move xform x units right (D)</string>
</property>
<property name="text">
<string/>
@ -5566,7 +5569,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units up</string>
<string>Move xform x units up (W)</string>
</property>
<property name="text">
<string/>
@ -5685,7 +5688,7 @@
</size>
</property>
<property name="toolTip">
<string>Move xform x units down</string>
<string>Move xform x units down (S)</string>
</property>
<property name="text">
<string/>
@ -8258,7 +8261,7 @@
<string>Save the current flame as an xml file</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
<string>Ctrl+T</string>
</property>
</action>
<action name="ActionAbout">
@ -8309,13 +8312,13 @@
<normaloff>:/Fractorium/Icons/068123-3d-transparent-glass-icon-alphanumeric-question-mark3.png</normaloff>:/Fractorium/Icons/068123-3d-transparent-glass-icon-alphanumeric-question-mark3.png</iconset>
</property>
<property name="text">
<string>New &amp;random Flame</string>
<string>New &amp;random flame</string>
</property>
<property name="toolTip">
<string>Add a new random flame to the end of the current file</string>
</property>
<property name="shortcut">
<string>Ctrl+R</string>
<string>Ctrl+M</string>
</property>
</action>
<action name="ActionSaveEntireFileAsXml">
@ -8333,7 +8336,7 @@
<string>Save all flames as a single xml file</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
<string>Ctrl+Shift+T</string>
</property>
</action>
<action name="ActionAddReflectiveSymmetry">
@ -8380,7 +8383,7 @@
<string>Add a new empty flame to the end of the current file</string>
</property>
<property name="shortcut">
<string>Ctrl+E</string>
<string>Ctrl+Y</string>
</property>
</action>
<action name="ActionCopyFlameInCurrentFile">
@ -8708,7 +8711,7 @@
<string>Alternate editor/image</string>
</property>
<property name="shortcut">
<string>Ctrl+W</string>
<string>Ctrl+L</string>
</property>
</action>
<action name="ActionResetScale">

View File

@ -211,6 +211,8 @@ public:
double LockedY() { return m_LockedY; }
void LockedScale(double scale) { m_LockedScale = scale; }
virtual void InitLockedScale() { }
virtual double AffineScaleCurrentToLocked() { return 0; };
virtual double AffineScaleLockedToCurrent() { return 0; };
//Xforms Color.
virtual void XformColorIndexChanged(double d, bool updateRender, bool updateSpinner, bool updateScroll, eXformUpdate update = eXformUpdate::UPDATE_SELECTED, size_t index = 0) { }
@ -496,10 +498,10 @@ public:
virtual void FillBothAffines() override;
virtual void SwapAffines() override;
virtual void InitLockedScale() override;
virtual double AffineScaleCurrentToLocked() override;
virtual double AffineScaleLockedToCurrent() override;
void FillAffineWithXform(Xform<T>* xform, bool pre);
void ChangeLockedScale(T value);
T AffineScaleCurrentToLocked();
T AffineScaleLockedToCurrent();
//Xforms Color.
virtual void XformColorIndexChanged(double d, bool updateRender, bool updateSpinner, bool updateScroll, eXformUpdate update = eXformUpdate::UPDATE_SELECTED, size_t index = 0) override;

View File

@ -225,6 +225,7 @@ void Fractorium::OnClearXaosButtonClicked(bool checked) { m_Controller->ClearXao
template <typename T>
void FractoriumEmberController<T>::RandomXaos()
{
bool ctrl = QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier);
Update([&]
{
size_t i = 0;
@ -233,7 +234,9 @@ void FractoriumEmberController<T>::RandomXaos()
{
for (size_t j = 0; j < m_Ember.XformCount(); j++)
{
if (m_Rand.RandBit())
if (!ctrl)
xform->SetXaos(j, T(m_Rand.RandBit()));
else if (m_Rand.RandBit())
xform->SetXaos(j, T(m_Rand.RandBit()));
else
xform->SetXaos(j, TruncPrecision(m_Rand.Frand<T>(0, 3), 3));

View File

@ -188,7 +188,7 @@ void FractoriumEmberController<T>::ChangeLockedScale(T value)
/// </summary>
/// <returns>The scale value</returns>
template <typename T>
T FractoriumEmberController<T>::AffineScaleCurrentToLocked()
double FractoriumEmberController<T>::AffineScaleCurrentToLocked()
{
return LockedScale() / m_Ember.m_PixelsPerUnit;
}
@ -198,7 +198,7 @@ T FractoriumEmberController<T>::AffineScaleCurrentToLocked()
/// </summary>
/// <returns>The scale value</returns>
template <typename T>
T FractoriumEmberController<T>::AffineScaleLockedToCurrent()
double FractoriumEmberController<T>::AffineScaleLockedToCurrent()
{
return m_Ember.m_PixelsPerUnit / LockedScale();
}

View File

@ -62,6 +62,7 @@ public:
void ClearShift();
void ClearControl();
eDragState DragState() { return m_DragState; }
eAffineType AffineType() { return m_AffineType; }
virtual void DrawImage() { }
virtual void DrawAffines(bool pre, bool post) { }
virtual void ClearWindow() { }

View File

@ -1996,8 +1996,8 @@ bool GLEmberController<T>::CheckXformHover(Xform<T>* xform, v3T& glCoords, T& be
template <typename T>
void GLEmberController<T>::CalcDragXAxis()
{
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
T affineToWorldScale = T(m_FractoriumEmberController->AffineScaleLockedToCurrent());
T worldToAffineScale = T(m_FractoriumEmberController->AffineScaleCurrentToLocked());
bool pre = m_AffineType == eAffineType::AffinePre;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
auto worldRelAxisStartScaled = (v2T(m_HoverHandlePos) * affineToWorldScale) - m_DragSrcTransform.O();//World axis start position, relative, scaled by the zoom.
@ -2161,8 +2161,8 @@ void GLEmberController<T>::CalcDragXAxis()
template <typename T>
void GLEmberController<T>::CalcDragYAxis()
{
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
T affineToWorldScale = T(m_FractoriumEmberController->AffineScaleLockedToCurrent());
T worldToAffineScale = T(m_FractoriumEmberController->AffineScaleCurrentToLocked());
bool pre = m_AffineType == eAffineType::AffinePre;
bool worldPivotShiftAlt = !m_Fractorium->LocalPivot() && GetShift() && GetAlt();
auto worldRelAxisStartScaled = (v2T(m_HoverHandlePos) * affineToWorldScale) - m_DragSrcTransform.O();//World axis start position, relative, scaled by the zoom.
@ -2321,8 +2321,8 @@ void GLEmberController<T>::CalcDragYAxis()
template <typename T>
void GLEmberController<T>::CalcDragTranslation()
{
auto affineToWorldScale = m_FractoriumEmberController->AffineScaleLockedToCurrent();
auto worldToAffineScale = m_FractoriumEmberController->AffineScaleCurrentToLocked();
T affineToWorldScale = T(m_FractoriumEmberController->AffineScaleLockedToCurrent());
T worldToAffineScale = T(m_FractoriumEmberController->AffineScaleCurrentToLocked());
bool worldPivotShift = !m_Fractorium->LocalPivot() && GetShift();
bool pre = m_AffineType == eAffineType::AffinePre;

View File

@ -115,6 +115,11 @@ public:
QPushButton* m_Button;
};
/// <summary>
/// Thin container that is both a widget and a container of one DoubleSpinBox and one QLabel.
/// Used for when a layout expects a single widget, but two need to go in its place.
/// The widgets are public so the caller can easily use them individually.
/// </summary>
class SpinnerLabelWidget : public QWidget
{
Q_OBJECT
@ -150,6 +155,9 @@ protected:
QHBoxLayout* m_L;
};
/// <summary>
/// Thin derivation that adds a button to a SpinnerLabelWidget.
/// </summary>
class SpinnerLabelButtonWidget : public SpinnerLabelWidget
{
Q_OBJECT
@ -184,7 +192,11 @@ public:
QPushButton* m_Button;
};
/// <summary>
/// Thin container that is both a widget and a container of one DoubleSpinBox and one SpinBox.
/// Used for when a layout expects a single widget, but two need to go in its place.
/// The widgets are public so the caller can easily use them individually.
/// </summary>
class DoubleIntSpinnerWidget : public QWidget
{
Q_OBJECT