From f09db4d9aa9e10045ee46402c90cdbe7b9b32360 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 28 Apr 2015 12:38:15 -0300 Subject: [PATCH] Add new BrushPopup (now the image brush is previewed) This is the first step to create a bigger BrushPopup to select brushes from an history of brushes. The general idea is to use Alt+1, Alt+2, etc. to select different brushes from a stock. Also the "discard brush" was removed. As the brush can be discarded changing the brush type. --- src/app/CMakeLists.txt | 1 + src/app/ui/brush_popup.cpp | 56 +++++++++++++++++++ src/app/ui/brush_popup.h | 36 +++++++++++++ src/app/ui/context_bar.cpp | 81 +++++++++++++--------------- src/app/ui/context_bar.h | 2 - src/app/ui/editor/tool_loop_impl.cpp | 4 +- src/app/ui/editor/tool_loop_impl.h | 2 +- 7 files changed, 133 insertions(+), 49 deletions(-) create mode 100644 src/app/ui/brush_popup.cpp create mode 100644 src/app/ui/brush_popup.h diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index bb75567da..355b12631 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -291,6 +291,7 @@ add_library(app-lib transaction.cpp ui/ani_controls.cpp ui/app_menuitem.cpp + ui/brush_popup.cpp ui/button_set.cpp ui/color_bar.cpp ui/color_button.cpp diff --git a/src/app/ui/brush_popup.cpp b/src/app/ui/brush_popup.cpp new file mode 100644 index 000000000..9a43be5dc --- /dev/null +++ b/src/app/ui/brush_popup.cpp @@ -0,0 +1,56 @@ +// Aseprite +// Copyright (C) 2001-2015 David Capello +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "app/ui/brush_popup.h" + +#include "gfx/region.h" +#include "gfx/border.h" +#include "app/ui/skin/skin_theme.h" +#include "app/ui/button_set.h" +#include "doc/brush.h" + +namespace app { + +using namespace app::skin; +using namespace ui; + +BrushPopup::BrushPopup(const gfx::Rect& rc, doc::Brush* brush) + : PopupWindow("", kCloseOnClickInOtherWindow) +{ + SkinTheme* theme = static_cast(getTheme()); + + setAutoRemap(false); + setBorder(gfx::Border(0)); + setBounds(rc); + child_spacing = 0; + + m_brushTypeButton = new ButtonSet(3); + m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_CIRCLE)); + m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_SQUARE)); + m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_LINE)); + m_brushTypeButton->ItemChange.connect(&BrushPopup::onBrushTypeChange, this); + m_brushTypeButton->setTransparent(true); + m_brushTypeButton->setBgColor(gfx::ColorNone); + addChild(m_brushTypeButton); + + m_brushTypeButton->setSelectedItem(brush->type()); +} + +void BrushPopup::onBrushTypeChange() +{ + doc::BrushType brushType = (doc::BrushType)m_brushTypeButton->selectedItem(); + doc::Brush brush; + brush.setType(brushType); + + BrushChange(&brush); +} + +} // namespace app diff --git a/src/app/ui/brush_popup.h b/src/app/ui/brush_popup.h new file mode 100644 index 000000000..33ca51487 --- /dev/null +++ b/src/app/ui/brush_popup.h @@ -0,0 +1,36 @@ +// Aseprite +// Copyright (C) 2001-2015 David Capello +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. + +#ifndef APP_UI_BRUSH_POPUP_H_INCLUDED +#define APP_UI_BRUSH_POPUP_H_INCLUDED +#pragma once + +#include "base/signal.h" +#include "ui/popup_window.h" + +namespace doc { + class Brush; +} + +namespace app { + class ButtonSet; + + class BrushPopup : public ui::PopupWindow { + public: + BrushPopup(const gfx::Rect& rc, doc::Brush* brush); + + Signal1 BrushChange; + + private: + void onBrushTypeChange(); + + ButtonSet* m_brushTypeButton; + }; + +} // namespace app + +#endif diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index d1180cdc8..ee255eebd 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -14,6 +14,7 @@ #include "app/app.h" #include "app/commands/commands.h" #include "app/modules/gui.h" +#include "app/modules/palettes.h" #include "app/pref/preferences.h" #include "app/settings/ink_type.h" #include "app/settings/selection_mode.h" @@ -24,6 +25,7 @@ #include "app/tools/point_shape.h" #include "app/tools/tool.h" #include "app/tools/tool_box.h" +#include "app/ui/brush_popup.h" #include "app/ui/button_set.h" #include "app/ui/color_button.h" #include "app/ui/editor/tool_loop_impl.h" @@ -62,8 +64,7 @@ class ContextBar::BrushTypeField : public ButtonSet { public: BrushTypeField() : ButtonSet(1) - , m_popupWindow(NULL) - , m_brushTypeButton(NULL) { + , m_popupWindow(NULL) { m_bitmap = she::instance()->createRgbaSurface(8, 8); she::ScopedSurfaceLock lock(m_bitmap); lock->clear(); @@ -78,25 +79,31 @@ public: } void setBrushSettings(IBrushSettings* brushSettings) { - base::UniquePtr palette(new Palette(frame_t(0), 2)); - palette->setEntry(0, doc::rgba(0, 0, 0, 0)); - palette->setEntry(1, doc::rgba(0, 0, 0, 255)); - - base::UniquePtr brush( - new Brush( - m_brushType = brushSettings->getType(), - std::min(10, brushSettings->getSize()), - brushSettings->getAngle())); + base::SharedPtr brush = get_tool_loop_brush( + brushSettings, 10); Image* image = brush->image(); if (m_bitmap) m_bitmap->dispose(); - m_bitmap = she::instance()->createRgbaSurface(image->width(), image->height()); + m_bitmap = she::instance()->createRgbaSurface( + std::min(10, image->width()), + std::min(10, image->height())); + + Palette* palette = get_current_palette(); + if (image->pixelFormat() == IMAGE_BITMAP) { + palette = new Palette(frame_t(0), 2); + palette->setEntry(0, doc::rgba(0, 0, 0, 0)); + palette->setEntry(1, doc::rgba(0, 0, 0, 255)); + } + convert_image_to_surface(image, palette, m_bitmap, 0, 0, 0, 0, image->width(), image->height()); + if (image->pixelFormat() == IMAGE_BITMAP) + delete palette; + getItem(0)->setIcon(m_bitmap); } @@ -116,44 +123,35 @@ protected: private: void openPopup() { - SkinTheme* theme = static_cast(getTheme()); - Rect rc = getBounds(); rc.y += rc.h - 2*guiscale(); rc.setSize(getPreferredSize()); rc.w *= 3; - m_popupWindow = new PopupWindow("", PopupWindow::kCloseOnClickInOtherWindow); - m_popupWindow->setAutoRemap(false); - m_popupWindow->setBorder(Border(0)); - m_popupWindow->setBounds(rc); - m_popupWindow->child_spacing = 0; + + ISettings* settings = UIContext::instance()->settings(); + Tool* currentTool = settings->getCurrentTool(); + IBrushSettings* brushSettings = settings->getToolSettings(currentTool)->getBrush(); + base::SharedPtr brush = get_tool_loop_brush(brushSettings); + + m_popupWindow = new BrushPopup(rc, brush.get()); Region rgn(m_popupWindow->getBounds().createUnion(getBounds())); m_popupWindow->setHotRegion(rgn); - m_brushTypeButton = new ButtonSet(3); - m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_CIRCLE)); - m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_SQUARE)); - m_brushTypeButton->addItem(theme->get_part(PART_BRUSH_LINE)); - m_brushTypeButton->setSelectedItem(m_brushType); - m_brushTypeButton->ItemChange.connect(&BrushTypeField::onBrushTypeChange, this); - m_brushTypeButton->setTransparent(true); - m_brushTypeButton->setBgColor(gfx::ColorNone); - m_popupWindow->addChild(m_brushTypeButton); m_popupWindow->openWindow(); + m_popupWindow->BrushChange.connect(&BrushTypeField::onBrushTypeChange, this); } void closePopup() { if (m_popupWindow) { m_popupWindow->closeWindow(NULL); delete m_popupWindow; - m_popupWindow = NULL; - m_brushTypeButton = NULL; + m_popupWindow = nullptr; } } - void onBrushTypeChange() { - m_brushType = (BrushType)m_brushTypeButton->selectedItem(); + void onBrushTypeChange(Brush* brush) { + m_brushType = brush->type(); ISettings* settings = UIContext::instance()->settings(); Tool* currentTool = settings->getCurrentTool(); @@ -161,12 +159,16 @@ private: brushSettings->setType(m_brushType); setBrushSettings(brushSettings); + + { + Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DiscardBrush); + UIContext::instance()->executeCommand(cmd); + } } she::Surface* m_bitmap; BrushType m_brushType; - PopupWindow* m_popupWindow; - ButtonSet* m_brushTypeButton; + BrushPopup* m_popupWindow; }; class ContextBar::BrushSizeField : public IntEntry @@ -794,7 +796,6 @@ ContextBar::ContextBar() addChild(m_brushType = new BrushTypeField()); addChild(m_brushSize = new BrushSizeField()); addChild(m_brushAngle = new BrushAngleField(m_brushType)); - addChild(m_discardBrush = new Button("Discard Brush")); addChild(m_brushPatternField = new BrushPatternField()); addChild(m_toleranceLabel = new Label("Tolerance:")); @@ -855,7 +856,6 @@ ContextBar::ContextBar() App::instance()->BrushAngleAfterChange.connect(&ContextBar::onBrushAngleChange, this); App::instance()->CurrentToolChange.connect(&ContextBar::onCurrentToolChange, this); m_dropPixels->DropPixels.connect(&ContextBar::onDropPixels, this); - m_discardBrush->Click.connect(Bind(&ContextBar::onDiscardBrush, this)); onCurrentToolChange(); } @@ -985,10 +985,9 @@ void ContextBar::updateFromTool(tools::Tool* tool) tool->getController(1)->isFreehand()); // Show/Hide fields - m_brushType->setVisible(hasOpacity && !hasImageBrush); + m_brushType->setVisible(hasOpacity); m_brushSize->setVisible(hasOpacity && !hasImageBrush); m_brushAngle->setVisible(hasOpacity && !hasImageBrush); - m_discardBrush->setVisible(hasOpacity && hasImageBrush); m_brushPatternField->setVisible(hasOpacity && hasImageBrush); m_opacityLabel->setVisible(hasOpacity); m_inkType->setVisible(hasInk && !hasImageBrush); @@ -1036,10 +1035,4 @@ void ContextBar::updateAutoSelectLayer(bool state) m_autoSelectLayer->setSelected(state); } -void ContextBar::onDiscardBrush() -{ - Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DiscardBrush); - UIContext::instance()->executeCommand(cmd); -} - } // namespace app diff --git a/src/app/ui/context_bar.h b/src/app/ui/context_bar.h index 17cd6d7a7..fe2b43c25 100644 --- a/src/app/ui/context_bar.h +++ b/src/app/ui/context_bar.h @@ -52,7 +52,6 @@ namespace app { void onBrushAngleChange(); void onCurrentToolChange(); void onDropPixels(ContextBarObserver::DropAction action); - void onDiscardBrush(); class BrushTypeField; class BrushAngleField; @@ -86,7 +85,6 @@ namespace app { AutoSelectLayerField* m_autoSelectLayer; ui::Box* m_freehandBox; FreehandAlgorithmField* m_freehandAlgo; - ui::Button* m_discardBrush; BrushPatternField* m_brushPatternField; ui::Box* m_sprayBox; SprayWidthField* m_sprayWidth; diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index 8947fee96..0822adf40 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -79,7 +79,7 @@ Image* get_tool_loop_brush_image() return nullptr; } -base::SharedPtr get_tool_loop_brush(IBrushSettings* brushSettings) +base::SharedPtr get_tool_loop_brush(IBrushSettings* brushSettings, int sizeLimit) { base::SharedPtr brush; @@ -92,7 +92,7 @@ base::SharedPtr get_tool_loop_brush(IBrushSettings* brushSettings) brush.reset( new Brush( brushSettings->getType(), - brushSettings->getSize(), + std::min(sizeLimit, brushSettings->getSize()), brushSettings->getAngle())); } return brush; diff --git a/src/app/ui/editor/tool_loop_impl.h b/src/app/ui/editor/tool_loop_impl.h index 224574760..2310382fd 100644 --- a/src/app/ui/editor/tool_loop_impl.h +++ b/src/app/ui/editor/tool_loop_impl.h @@ -35,7 +35,7 @@ namespace app { doc::Image* get_tool_loop_brush_image(); base::SharedPtr get_tool_loop_brush( - IBrushSettings* brushSettings); + IBrushSettings* brushSettings, int sizeLimit = 0xffff); tools::ToolLoop* create_tool_loop( Editor* editor, Context* context);