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.
This commit is contained in:
David Capello 2015-04-28 12:38:15 -03:00
parent 274b903aad
commit f09db4d9aa
7 changed files with 133 additions and 49 deletions

View File

@ -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

View File

@ -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<SkinTheme*>(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

36
src/app/ui/brush_popup.h Normal file
View File

@ -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<void, doc::Brush*> BrushChange;
private:
void onBrushTypeChange();
ButtonSet* m_brushTypeButton;
};
} // namespace app
#endif

View File

@ -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> 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> brush(
new Brush(
m_brushType = brushSettings->getType(),
std::min(10, brushSettings->getSize()),
brushSettings->getAngle()));
base::SharedPtr<doc::Brush> 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<SkinTheme*>(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<doc::Brush> 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<void>(&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

View File

@ -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;

View File

@ -79,7 +79,7 @@ Image* get_tool_loop_brush_image()
return nullptr;
}
base::SharedPtr<Brush> get_tool_loop_brush(IBrushSettings* brushSettings)
base::SharedPtr<Brush> get_tool_loop_brush(IBrushSettings* brushSettings, int sizeLimit)
{
base::SharedPtr<Brush> brush;
@ -92,7 +92,7 @@ base::SharedPtr<Brush> get_tool_loop_brush(IBrushSettings* brushSettings)
brush.reset(
new Brush(
brushSettings->getType(),
brushSettings->getSize(),
std::min(sizeLimit, brushSettings->getSize()),
brushSettings->getAngle()));
}
return brush;

View File

@ -35,7 +35,7 @@ namespace app {
doc::Image* get_tool_loop_brush_image();
base::SharedPtr<doc::Brush> get_tool_loop_brush(
IBrushSettings* brushSettings);
IBrushSettings* brushSettings, int sizeLimit = 0xffff);
tools::ToolLoop* create_tool_loop(
Editor* editor, Context* context);