From 96026ed2669603e24f607727c1269421328bcb57 Mon Sep 17 00:00:00 2001 From: Andreas Butti Date: Sat, 29 Dec 2018 13:23:43 +0100 Subject: [PATCH] Stroke tool item fixes #598 --- src/control/Control.cpp | 31 +++--- src/control/Control.h | 13 ++- src/control/ToolHandler.cpp | 6 +- src/control/ToolHandler.h | 2 +- src/control/tools/EditSelection.cpp | 11 ++ src/control/tools/EditSelection.h | 13 ++- src/control/tools/EditSelectionContents.cpp | 61 ++++++++++ src/control/tools/EditSelectionContents.h | 11 +- src/gui/XournalView.cpp | 10 +- src/gui/toolbarMenubar/ColorToolItem.cpp | 1 - src/gui/toolbarMenubar/ColorToolItem.h | 2 +- src/undo/FillUndoAction.cpp | 117 ++++++++++++++++++++ src/undo/FillUndoAction.h | 40 +++++++ src/util/XournalType.cpp | 2 +- src/util/XournalTypeList.h | 2 + 15 files changed, 287 insertions(+), 35 deletions(-) create mode 100644 src/undo/FillUndoAction.cpp create mode 100644 src/undo/FillUndoAction.h diff --git a/src/control/Control.cpp b/src/control/Control.cpp index 193adf85..bf8bd9c0 100644 --- a/src/control/Control.cpp +++ b/src/control/Control.cpp @@ -1815,14 +1815,7 @@ void Control::toolFillChanged() { XOJ_CHECK_TYPE(Control); - if (toolHandler->getFill()) - { - fireActionSelected(GROUP_FILL, ACTION_TOOL_FILL); - } - else - { - fireActionSelected(GROUP_FILL, ACTION_NONE); - } + fireActionSelected(GROUP_FILL, toolHandler->getFill() != -1 ? ACTION_TOOL_FILL : ACTION_NONE); } /** @@ -2914,6 +2907,18 @@ void Control::setFill(bool fill) { XOJ_CHECK_TYPE(Control); + EditSelection* sel = NULL; + if (this->win) + { + sel = this->win->getXournal()->getSelection(); + } + + if (sel) + { + UndoAction* undo = sel->setFill(fill ? toolHandler->getPenFill() : -1, fill ? toolHandler->getHilighterFill() : -1); + undoRedo->addUndoAction(undo); + } + if (toolHandler->getToolType() == TOOL_PEN) { fireActionSelected(GROUP_PEN_FILL, fill ? ACTION_TOOL_PEN_FILL : ACTION_NONE); @@ -2941,10 +2946,7 @@ void Control::setToolSize(ToolSize size) UndoAction* undo = sel->setSize(size, toolHandler->getToolThickness(TOOL_PEN), toolHandler->getToolThickness(TOOL_HILIGHTER), toolHandler->getToolThickness(TOOL_ERASER)); - if (undo) - { - undoRedo->addUndoAction(undo); - } + undoRedo->addUndoAction(undo); } this->toolHandler->setSize(size); } @@ -2964,10 +2966,7 @@ void Control::fontChanged() if (sel) { UndoAction* undo = sel->setFont(font); - if (undo) - { - undoRedo->addUndoAction(undo); - } + undoRedo->addUndoAction(undo); } TextEditor* editor = getTextEditor(); diff --git a/src/control/Control.h b/src/control/Control.h index dca7b35f..a1480a47 100644 --- a/src/control/Control.h +++ b/src/control/Control.h @@ -290,13 +290,20 @@ protected: private: XOJ_TYPE_ATTRIB; - RecentManager* recent; UndoRedoHandler* undoRedo; ZoomControl* zoom; bool fullscreen = false; - bool snapRotation = true; //rotation snapping enabled by default - bool snapGrid = true; //grid snapping enabled by default + + /** + * Rotation snapping enabled by default + */ + bool snapRotation = true; + + /** + * grid snapping enabled by default + */ + bool snapGrid = true; Settings* settings; MainWindow* win; diff --git a/src/control/ToolHandler.cpp b/src/control/ToolHandler.cpp index 00bea8b9..1eb70c14 100644 --- a/src/control/ToolHandler.cpp +++ b/src/control/ToolHandler.cpp @@ -616,17 +616,20 @@ const double* ToolHandler::getToolThickness(ToolType type) /** * Change the selection tools capabilities, depending on the selected elements */ -void ToolHandler::setSelectionEditTools(bool setColor, bool setSize) +void ToolHandler::setSelectionEditTools(bool setColor, bool setSize, bool setFill) { XOJ_CHECK_TYPE(ToolHandler); + // For all selection tools, apply the features for (int i = TOOL_SELECT_RECT - TOOL_PEN; i <= TOOL_SELECT_OBJECT - TOOL_PEN; i++) { Tool* t = tools[i]; t->setCapability(TOOL_CAP_COLOR, setColor); t->setCapability(TOOL_CAP_SIZE, setSize); + t->setCapability(TOOL_CAP_FILL, setFill); t->size = TOOL_SIZE_NONE; t->color = -1; + t->fill = false; } if (this->current->type == TOOL_SELECT_RECT || @@ -636,6 +639,7 @@ void ToolHandler::setSelectionEditTools(bool setColor, bool setSize) { this->listener->toolColorChanged(false); this->listener->toolSizeChanged(); + this->listener->toolFillChanged(); this->fireToolChanged(); } } diff --git a/src/control/ToolHandler.h b/src/control/ToolHandler.h index 6f7a19f8..410c22c5 100644 --- a/src/control/ToolHandler.h +++ b/src/control/ToolHandler.h @@ -105,7 +105,7 @@ public: /** * Change the selection tools capabilities, depending on the selected elements */ - void setSelectionEditTools(bool setColor, bool setSize); + void setSelectionEditTools(bool setColor, bool setSize, bool setFill); const double* getToolThickness(ToolType type); diff --git a/src/control/tools/EditSelection.cpp b/src/control/tools/EditSelection.cpp index 303bfd5a..b1f21373 100644 --- a/src/control/tools/EditSelection.cpp +++ b/src/control/tools/EditSelection.cpp @@ -253,6 +253,17 @@ UndoAction* EditSelection::setSize(ToolSize size, return this->contents->setSize(size, thicknessPen, thicknessHilighter, thicknessEraser); } +/** + * Fills the stroke, return an undo action + * (Or NULL if nothing done, e.g. because there is only an image) + */ +UndoAction* EditSelection::setFill(int alphaPen, int alphaHighligther) +{ + XOJ_CHECK_TYPE(EditSelection); + + return this->contents->setFill(alphaPen, alphaHighligther); +} + /** * Set the color of all elements, return an undo action * (Or NULL if nothing done, e.g. because there is only an image) diff --git a/src/control/tools/EditSelection.h b/src/control/tools/EditSelection.h index c26e01eb..b2e8114f 100644 --- a/src/control/tools/EditSelection.h +++ b/src/control/tools/EditSelection.h @@ -96,11 +96,10 @@ public: public: /** - * Sets the tool size for pen or eraser, returs an undo action + * Sets the tool size for pen or eraser, returns an undo action * (or NULL if nothing is done) */ - UndoAction* setSize(ToolSize size, - const double* thicknessPen, const double* thicknessHilighter, const double* thicknessEraser); + UndoAction* setSize(ToolSize size, const double* thicknessPen, const double* thicknessHilighter, const double* thicknessEraser); /** * Set the color of all elements, return an undo action @@ -115,11 +114,17 @@ public: UndoAction* setFont(XojFont& font); /** - * Fills de undo item if the selection is deleted + * Fills the undo item if the selection is deleted * the selection is cleared after */ void fillUndoItem(DeleteUndoAction* undo); + /** + * Fills the stroke, return an undo action + * (Or NULL if nothing done, e.g. because there is only an image) + */ + UndoAction* setFill(int alphaPen, int alphaHighligther); + public: /** * Add an element to the this selection diff --git a/src/control/tools/EditSelectionContents.cpp b/src/control/tools/EditSelectionContents.cpp index 90f2e70d..8e7f2ec8 100644 --- a/src/control/tools/EditSelectionContents.cpp +++ b/src/control/tools/EditSelectionContents.cpp @@ -14,6 +14,7 @@ #include "undo/ColorUndoAction.h" #include "undo/DeleteUndoAction.h" #include "undo/FontUndoAction.h" +#include "undo/FillUndoAction.h" #include "undo/InsertUndoAction.h" #include "undo/MoveUndoAction.h" #include "undo/UndoRedoHandler.h" @@ -151,6 +152,66 @@ UndoAction* EditSelectionContents::setSize(ToolSize size, } } +/** + * Fills the stroke, return an undo action + * (Or NULL if nothing done, e.g. because there is only an image) + */ +UndoAction* EditSelectionContents::setFill(int alphaPen, int alphaHighligther) +{ + XOJ_CHECK_TYPE(EditSelectionContents); + + FillUndoAction* undo = new FillUndoAction(this->sourcePage, this->sourceLayer); + + bool found = false; + + for (Element* e : this->selected) + { + if (e->getType() == ELEMENT_STROKE) + { + Stroke* s = (Stroke*) e; + StrokeTool tool = s->getToolType(); + int newFill = 128; + + if (tool == STROKE_TOOL_PEN) + { + newFill = alphaPen; + } + else if (tool == STROKE_TOOL_HIGHLIGHTER) + { + newFill = alphaHighligther; + } + else + { + continue; + } + + if (newFill == s->getFill()) + { + continue; + } + + bool originalFill = s->getFill(); + s->setFill(newFill); + + undo->addStroke(s, originalFill, newFill); + found = true; + } + } + + if (found) + { + this->deleteViewBuffer(); + this->sourceView->getXournal()->repaintSelection(); + + return undo; + } + else + { + delete undo; + return NULL; + } +} + /** * Sets the font of all containing text elements, return an undo action * (or NULL if there are no Text elements) diff --git a/src/control/tools/EditSelectionContents.h b/src/control/tools/EditSelectionContents.h index a9d0ee7b..bee294e5 100644 --- a/src/control/tools/EditSelectionContents.h +++ b/src/control/tools/EditSelectionContents.h @@ -42,8 +42,7 @@ public: * Sets the tool size for pen or eraser, returs an undo action * (or NULL if nothing is done) */ - UndoAction* setSize(ToolSize size, const double* thicknessPen, - const double* thicknessHilighter, const double* thicknessEraser); + UndoAction* setSize(ToolSize size, const double* thicknessPen, const double* thicknessHilighter, const double* thicknessEraser); /** * Set the color of all elements, return an undo action @@ -58,11 +57,17 @@ public: UndoAction* setFont(XojFont& font); /** - * Fills de undo item if the selection is deleted + * Fills the undo item if the selection is deleted * the selection is cleared after */ void fillUndoItem(DeleteUndoAction* undo); + /** + * Fills the stroke, return an undo action + * (Or NULL if nothing done, e.g. because there is only an image) + */ + UndoAction* setFill(int alphaPen, int alphaHighligther); + public: /** * Add an element to the this selection diff --git a/src/gui/XournalView.cpp b/src/gui/XournalView.cpp index 0b42ed75..1e675e5d 100644 --- a/src/gui/XournalView.cpp +++ b/src/gui/XournalView.cpp @@ -775,7 +775,7 @@ void XournalView::clearSelection() control->setClipboardHandlerSelection(getSelection()); getCursor()->setMouseSelectionType(CURSOR_SELECTION_NONE); - control->getToolHandler()->setSelectionEditTools(false, false); + control->getToolHandler()->setSelectionEditTools(false, false, false); } void XournalView::deleteSelection(EditSelection* sel) @@ -812,6 +812,7 @@ void XournalView::setSelection(EditSelection* selection) bool canChangeSize = false; bool canChangeColor = false; + bool canChangeFill = false; for (Element* e : *selection->getElements()) { @@ -825,17 +826,18 @@ void XournalView::setSelection(EditSelection* selection) if (s->getToolType() != STROKE_TOOL_ERASER) { canChangeColor = true; + canChangeFill = true; } canChangeSize = true; } - if (canChangeColor && canChangeSize) + if (canChangeColor && canChangeSize && canChangeFill) { break; } } - control->getToolHandler()->setSelectionEditTools(canChangeColor, canChangeSize); + control->getToolHandler()->setSelectionEditTools(canChangeColor, canChangeSize, canChangeFill); repaintSelection(); } @@ -865,7 +867,7 @@ void XournalView::setEventCompression(gboolean enable) // Enable this when gdk is new enough for the compression feature. if (gtk_widget_get_realized(getWidget())) { - gdk_window_set_event_compression(gtk_widget_get_window(getWidget()), FALSE); + gdk_window_set_event_compression(gtk_widget_get_window(getWidget()), enable); } } diff --git a/src/gui/toolbarMenubar/ColorToolItem.cpp b/src/gui/toolbarMenubar/ColorToolItem.cpp index f31fa432..62f4704b 100644 --- a/src/gui/toolbarMenubar/ColorToolItem.cpp +++ b/src/gui/toolbarMenubar/ColorToolItem.cpp @@ -18,7 +18,6 @@ ColorToolItem::ColorToolItem(ActionHandler* handler, ToolHandler* toolHandler, G this->color = color; this->toolHandler = toolHandler; this->group = GROUP_COLOR; - this->iconWidget = NULL; this->parent = parent; updateName(); diff --git a/src/gui/toolbarMenubar/ColorToolItem.h b/src/gui/toolbarMenubar/ColorToolItem.h index f435bf96..25469f26 100644 --- a/src/gui/toolbarMenubar/ColorToolItem.h +++ b/src/gui/toolbarMenubar/ColorToolItem.h @@ -50,7 +50,7 @@ private: int color; string name; - GtkWidget* iconWidget; + GtkWidget* iconWidget = NULL; GtkWindow* parent; ToolHandler* toolHandler; diff --git a/src/undo/FillUndoAction.cpp b/src/undo/FillUndoAction.cpp new file mode 100644 index 00000000..00d51d84 --- /dev/null +++ b/src/undo/FillUndoAction.cpp @@ -0,0 +1,117 @@ +#include "FillUndoAction.h" + +#include "gui/Redrawable.h" +#include "model/Stroke.h" + +#include +#include + +class FillUndoActionEntry +{ +public: + FillUndoActionEntry(Stroke* s, int originalFill, int newFill) + { + XOJ_INIT_TYPE(FillUndoActionEntry); + + this->s = s; + this->originalFill = originalFill; + this->newFill = newFill; + } + + ~FillUndoActionEntry() + { + XOJ_CHECK_TYPE(FillUndoActionEntry); + XOJ_RELEASE_TYPE(FillUndoActionEntry); + } + + XOJ_TYPE_ATTRIB; + + Stroke* s; + int originalFill; + int newFill; +}; + +FillUndoAction::FillUndoAction(PageRef page, Layer* layer) : UndoAction("FillUndoAction") +{ + XOJ_INIT_TYPE(FillUndoAction); + + this->page = page; + this->layer = layer; +} + +FillUndoAction::~FillUndoAction() +{ + XOJ_CHECK_TYPE(FillUndoAction); + + for (FillUndoActionEntry* e : this->data) + { + delete e; + } + this->data.clear(); + + XOJ_RELEASE_TYPE(FillUndoAction); +} + +void FillUndoAction::addStroke(Stroke* s, int originalFill, int newFill) +{ + XOJ_CHECK_TYPE(FillUndoAction); + + this->data.push_back(new FillUndoActionEntry(s, originalFill, newFill)); +} + +bool FillUndoAction::undo(Control* control) +{ + XOJ_CHECK_TYPE(FillUndoAction); + + if (this->data.empty()) + { + return true; + } + + FillUndoActionEntry* e = this->data.front(); + Range range(e->s->getX(), e->s->getY()); + + for (FillUndoActionEntry* e : this->data) + { + e->s->setFill(e->originalFill); + + range.addPoint(e->s->getX(), e->s->getY()); + range.addPoint(e->s->getX() + e->s->getElementWidth(), e->s->getY() + e->s->getElementHeight()); + } + + this->page->fireRangeChanged(range); + + return true; +} + +bool FillUndoAction::redo(Control* control) +{ + XOJ_CHECK_TYPE(FillUndoAction); + + if (this->data.empty()) + { + return true; + } + + FillUndoActionEntry* e = this->data.front(); + Range range(e->s->getX(), e->s->getY()); + + for (FillUndoActionEntry* e : this->data) + { + e->s->setFill(e->newFill); + + range.addPoint(e->s->getX(), e->s->getY()); + range.addPoint(e->s->getX() + e->s->getElementWidth(), e->s->getY() + e->s->getElementHeight()); + } + + this->page->fireRangeChanged(range); + + return true; +} + +string FillUndoAction::getText() +{ + XOJ_CHECK_TYPE(FillUndoAction); + + return _("Change stroke fill"); +} diff --git a/src/undo/FillUndoAction.h b/src/undo/FillUndoAction.h new file mode 100644 index 00000000..7be5130b --- /dev/null +++ b/src/undo/FillUndoAction.h @@ -0,0 +1,40 @@ +/* + * Xournal++ + * + * Undo action resize + * + * @author Xournal++ Team + * https://github.com/xournalpp/xournalpp + * + * @license GNU GPLv2 or later + */ + +#pragma once + +#include "UndoAction.h" + +class Layer; +class Redrawable; +class FillUndoActionEntry; +class Stroke; + +class FillUndoAction : public UndoAction +{ +public: + FillUndoAction(PageRef page, Layer* layer); + virtual ~FillUndoAction(); + +public: + virtual bool undo(Control* control); + virtual bool redo(Control* control); + virtual string getText(); + + void addStroke(Stroke* s, int originalFill, int newFill); + +private: + XOJ_TYPE_ATTRIB; + + std::vector data; + + Layer* layer; +}; diff --git a/src/util/XournalType.cpp b/src/util/XournalType.cpp index 8b6f9cc4..03eb7c68 100644 --- a/src/util/XournalType.cpp +++ b/src/util/XournalType.cpp @@ -10,7 +10,7 @@ using std::endl; #ifdef DEV_MEMORY_CHECKING -#define XOURNAL_TYPE_LIST_LENGTH 256 +#define XOURNAL_TYPE_LIST_LENGTH 512 #undef XOJ_DECLARE_TYPE #define XOJ_DECLARE_TYPE(name, id) \ diff --git a/src/util/XournalTypeList.h b/src/util/XournalTypeList.h index 9089b70e..4a867443 100644 --- a/src/util/XournalTypeList.h +++ b/src/util/XournalTypeList.h @@ -259,6 +259,8 @@ XOJ_DECLARE_TYPE(TouchDisableInterface, 248); XOJ_DECLARE_TYPE(TouchDisableCustom, 249); XOJ_DECLARE_TYPE(TouchDisableX11, 250); XOJ_DECLARE_TYPE(Path, 251); +XOJ_DECLARE_TYPE(FillUndoAction, 252); +XOJ_DECLARE_TYPE(FillUndoActionEntry, 253);