Created basic layer movement functionality (up, down) (#2108)

* Created basic layer movement functionality (up, down)

* Replaced `and` and `or` with `&&` and `||`, added constructor initialization

* Added move icons. Added that moving layers pushes state to undo stack.

* Cleaned svgs.

* Circle counter doesn't change nubmer when reordered anymore

* Changed move arrow SVGs

* Make down arrow in size with up arrow, fix white colors from #feffff to #fff

* SVGs in unitilypanel for buttons now choose color depending on color theme

* Refactor tool removing code, removed fixme, fixed bug with minimal circleCount

* Set minimal width for buttons

Co-authored-by: Feskow Vega <affirvega@krutt.org>
This commit is contained in:
Affir Vega
2022-01-30 00:32:09 +03:00
committed by GitHub
parent af1b895fe2
commit 1cc5a26292
12 changed files with 158 additions and 17 deletions

View File

@@ -90,5 +90,10 @@
<file>img/material/white/square.svg</file>
<file>img/material/white/text.svg</file>
<file>img/material/white/undo-variant.svg</file>
<file>img/material/black/move_down.svg</file>
<file>img/material/black/move_up.svg</file>
<file>img/material/white/move_down.svg</file>
<file>img/material/white/move_up.svg</file>
<file>img/material/white/delete.svg</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,3 @@
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m 18 11 l -6 6 l -6 -6 M 12 5 L 12 17" fill="none" stroke="#000" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 176 B

View File

@@ -0,0 +1,3 @@
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m 18 11 l -6 -6 l -6 6 M 12 5 L 12 19" fill="none" stroke="#000" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 176 B

View File

@@ -0,0 +1,3 @@
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m 18 11 l -6 6 l -6 -6 M 12 5 L 12 19" fill="none" stroke="#fff" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 176 B

View File

@@ -0,0 +1,3 @@
<svg version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="m 18 11 l -6 -6 l -6 6 M 12 5 L 12 19" fill="none" stroke="#fff" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 176 B

View File

@@ -27,6 +27,8 @@ struct CaptureContext
QPoint mousePos;
// Size of the active tool
int toolSize;
// Current circle count
int circleCount;
// Mode of the capture widget
bool fullscreen;
CaptureRequest request = CaptureRequest::GRAPHICAL_MODE;

View File

@@ -19,6 +19,17 @@ void CaptureToolObjects::append(const QPointer<CaptureTool>& captureTool)
}
}
void CaptureToolObjects::insert(int index,
const QPointer<CaptureTool>& captureTool)
{
if (!captureTool.isNull() && index >= 0 &&
index <= m_captureToolObjects.size()) {
m_captureToolObjects.insert(index,
captureTool->copy(captureTool->parent()));
m_imageCache.clear();
}
}
QPointer<CaptureTool> CaptureToolObjects::at(int index)
{
if (index >= 0 && index < m_captureToolObjects.size()) {

View File

@@ -14,6 +14,7 @@ public:
explicit CaptureToolObjects(QObject* parent = nullptr);
QList<QPointer<CaptureTool>> captureToolObjects();
void append(const QPointer<CaptureTool>& captureTool);
void insert(int index, const QPointer<CaptureTool>& captureTool);
void removeAt(int index);
void clear();
int size();

View File

@@ -73,6 +73,8 @@ CaptureWidget::CaptureWidget(const CaptureRequest& req,
{
m_undoStack.setUndoLimit(ConfigHandler().undoLimit());
m_context.circleCount = 1;
// Base config of the widget
m_eventFilter = new HoverEventFilter(this);
connect(m_eventFilter,
@@ -555,6 +557,8 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos)
// point and shouldn't wait for second point and move event
m_activeTool->drawEnd(m_context.mousePos);
m_activeTool->setCount(m_context.circleCount++);
m_captureToolObjectsBackup = m_captureToolObjects;
m_captureToolObjects.append(m_activeTool);
pushObjectsStateToUndoStack();
@@ -967,6 +971,14 @@ void CaptureWidget::initPanel()
&UtilityPanel::layerChanged,
this,
&CaptureWidget::updateActiveLayer);
connect(m_panel,
&UtilityPanel::moveUpClicked,
this,
&CaptureWidget::onMoveCaptureToolUp);
connect(m_panel,
&UtilityPanel::moveDownClicked,
this,
&CaptureWidget::onMoveCaptureToolDown);
m_sidePanel = new SidePanelWidget(&m_context.screenshot, this);
connect(m_sidePanel,
@@ -1266,6 +1278,26 @@ void CaptureWidget::updateActiveLayer(int layer)
updateSelectionState();
}
void CaptureWidget::onMoveCaptureToolUp(int captureToolIndex)
{
m_captureToolObjectsBackup = m_captureToolObjects;
pushObjectsStateToUndoStack();
auto tool = m_captureToolObjects.at(captureToolIndex);
m_captureToolObjects.removeAt(captureToolIndex);
m_captureToolObjects.insert(captureToolIndex - 1, tool);
updateLayersPanel();
}
void CaptureWidget::onMoveCaptureToolDown(int captureToolIndex)
{
m_captureToolObjectsBackup = m_captureToolObjects;
pushObjectsStateToUndoStack();
auto tool = m_captureToolObjects.at(captureToolIndex);
m_captureToolObjects.removeAt(captureToolIndex);
m_captureToolObjects.insert(captureToolIndex + 1, tool);
updateLayersPanel();
}
void CaptureWidget::selectAll()
{
m_selection->show();
@@ -1279,26 +1311,30 @@ void CaptureWidget::removeToolObject(int index)
{
--index;
if (index >= 0 && index < m_captureToolObjects.size()) {
// in case this tool is circle counter
int removedCircleCount = -1;
const CaptureTool::Type currentToolType =
m_captureToolObjects.at(index)->type();
m_captureToolObjectsBackup = m_captureToolObjects;
update(
paddedUpdateRect(m_captureToolObjects.at(index)->boundingRect()));
m_captureToolObjects.removeAt(index);
if (currentToolType == CaptureTool::TYPE_CIRCLECOUNT) {
// Do circle count reindex
int circleCount = 1;
removedCircleCount = m_captureToolObjects.at(index)->count();
--m_context.circleCount;
// Decrement circle counter numbers starting from deleted circle
for (int cnt = 0; cnt < m_captureToolObjects.size(); cnt++) {
auto toolItem = m_captureToolObjects.at(cnt);
if (toolItem->type() != CaptureTool::TYPE_CIRCLECOUNT) {
continue;
}
if (cnt >= index) {
m_captureToolObjects.at(cnt)->setCount(circleCount);
auto circleTool = m_captureToolObjects.at(cnt);
if (circleTool->count() >= removedCircleCount) {
circleTool->setCount(circleTool->count() - 1);
}
circleCount++;
}
}
m_captureToolObjects.removeAt(index);
pushObjectsStateToUndoStack();
drawToolsData();
updateLayersPanel();
@@ -1481,11 +1517,7 @@ void CaptureWidget::drawToolsData(bool drawSelection)
// TODO refactor this for performance. The objects should not all be updated
// at once every time
QPixmap pixmapItem = m_context.origScreenshot;
int circleCount = 1;
for (auto toolItem : m_captureToolObjects.captureToolObjects()) {
if (toolItem->type() == CaptureTool::TYPE_CIRCLECOUNT) {
toolItem->setCount(circleCount++);
}
processPixmapWithTool(&pixmapItem, toolItem);
update(paddedUpdateRect(toolItem->boundingRect()));
}
@@ -1547,6 +1579,20 @@ void CaptureWidget::makeChild(QWidget* w)
w->installEventFilter(m_eventFilter);
}
void CaptureWidget::restoreCircleCountState()
{
int largest = 0;
for (int cnt = 0; cnt < m_captureToolObjects.size(); cnt++) {
auto toolItem = m_captureToolObjects.at(cnt);
if (toolItem->type() != CaptureTool::TYPE_CIRCLECOUNT) {
continue;
}
if (toolItem->count() > largest)
largest = toolItem->count();
}
m_context.circleCount = largest + 1;
}
/**
* @brief Wrapper around `new QShortcut`, properly handling Enter/Return.
*/
@@ -1609,6 +1655,8 @@ void CaptureWidget::undo()
m_undoStack.undo();
drawToolsData();
updateLayersPanel();
restoreCircleCountState();
}
void CaptureWidget::redo()
@@ -1620,6 +1668,8 @@ void CaptureWidget::redo()
drawToolsData();
update();
updateLayersPanel();
restoreCircleCountState();
}
QRect CaptureWidget::extendedSelection() const

View File

@@ -76,6 +76,8 @@ private slots:
void onToolSizeChanged(int size);
void onToolSizeSettled(int size);
void updateActiveLayer(int layer);
void onMoveCaptureToolUp(int captureToolIndex);
void onMoveCaptureToolDown(int captureToolIndex);
void selectAll();
public:
@@ -115,6 +117,7 @@ private:
void updateLayersPanel();
void pushToolToStack();
void makeChild(QWidget* w);
void restoreCircleCountState();
QList<QShortcut*> newShortcut(const QKeySequence& key,
QWidget* parent,

View File

@@ -22,6 +22,8 @@ UtilityPanel::UtilityPanel(CaptureWidget* captureWidget)
, m_layersLayout(nullptr)
, m_captureTools(nullptr)
, m_buttonDelete(nullptr)
, m_buttonMoveUp(nullptr)
, m_buttonMoveDown(nullptr)
{
initInternalPanel();
setAttribute(Qt::WA_TransparentForMouseEvents);
@@ -141,12 +143,31 @@ void UtilityPanel::initInternalPanel()
QHBoxLayout* layersButtons = new QHBoxLayout();
m_layersLayout->addLayout(layersButtons);
m_layersLayout->addWidget(m_captureTools);
bool isDark = ColorUtils::colorIsDark(bgColor);
QString coloredIconPath =
isDark ? PathInfo::whiteIconPath() : PathInfo::blackIconPath();
m_buttonDelete = new QPushButton(this);
m_buttonDelete->setIcon(QIcon(":/img/material/black/delete.svg"));
m_buttonDelete->setIcon(QIcon(coloredIconPath + "delete.svg"));
m_buttonDelete->setMinimumWidth(m_buttonDelete->height());
m_buttonDelete->setDisabled(true);
m_buttonMoveUp = new QPushButton(this);
m_buttonMoveUp->setIcon(QIcon(coloredIconPath + "move_up.svg"));
m_buttonMoveUp->setMinimumWidth(m_buttonMoveUp->height());
m_buttonMoveUp->setDisabled(true);
m_buttonMoveDown = new QPushButton(this);
m_buttonMoveDown->setIcon(QIcon(coloredIconPath + "move_down.svg"));
m_buttonMoveDown->setMinimumWidth(m_buttonMoveDown->height());
m_buttonMoveDown->setDisabled(true);
layersButtons->addWidget(m_buttonDelete);
layersButtons->addWidget(m_buttonMoveUp);
layersButtons->addWidget(m_buttonMoveDown);
layersButtons->addStretch();
connect(m_buttonDelete,
@@ -154,6 +175,16 @@ void UtilityPanel::initInternalPanel()
this,
SLOT(slotButtonDelete(bool)));
connect(m_buttonMoveUp,
&QPushButton::clicked,
this,
&UtilityPanel::slotUpClicked);
connect(m_buttonMoveDown,
&QPushButton::clicked,
this,
&UtilityPanel::slotDownClicked);
// Bottom
QPushButton* closeButton = new QPushButton(this);
closeButton->setText(tr("Close"));
@@ -192,14 +223,32 @@ int UtilityPanel::activeLayerIndex()
void UtilityPanel::onCurrentRowChanged(int currentRow)
{
if (currentRow > 0) {
m_buttonDelete->setDisabled(false);
} else {
m_buttonDelete->setDisabled(true);
}
m_buttonDelete->setDisabled(currentRow <= 0);
m_buttonMoveDown->setDisabled(currentRow == 0 ||
currentRow + 1 == m_captureTools->count());
m_buttonMoveUp->setDisabled(currentRow <= 1);
emit layerChanged(activeLayerIndex());
}
void UtilityPanel::slotUpClicked(bool clicked)
{
Q_UNUSED(clicked);
// subtract 1 because there's <empty> in m_captureTools as [0] element
int toolRow = m_captureTools->currentRow() - 1;
m_captureTools->setCurrentRow(toolRow);
emit moveUpClicked(toolRow);
}
void UtilityPanel::slotDownClicked(bool clicked)
{
Q_UNUSED(clicked);
// subtract 1 because there's <empty> in m_captureTools as [0] element
int toolRow = m_captureTools->currentRow() - 1;
m_captureTools->setCurrentRow(toolRow + 2);
emit moveDownClicked(toolRow);
}
void UtilityPanel::slotButtonDelete(bool clicked)
{
Q_UNUSED(clicked)
@@ -218,4 +267,4 @@ void UtilityPanel::slotButtonDelete(bool clicked)
bool UtilityPanel::isVisible() const
{
return !m_internalPanel->isHidden();
}
}

View File

@@ -36,12 +36,18 @@ public:
signals:
void layerChanged(int layer);
void moveUpClicked(int currentRow);
void moveDownClicked(int currentRow);
public slots:
void toggle();
void slotButtonDelete(bool clicked);
void onCurrentRowChanged(int currentRow);
private slots:
void slotUpClicked(bool clicked);
void slotDownClicked(bool clicked);
private:
void initInternalPanel();
@@ -55,5 +61,7 @@ private:
QVBoxLayout* m_layersLayout;
QListWidget* m_captureTools;
QPushButton* m_buttonDelete;
QPushButton* m_buttonMoveUp;
QPushButton* m_buttonMoveDown;
CaptureWidget* m_captureWidget;
};