mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
Merge branch 'master' into beta
This commit is contained in:
parent
a9f3702ba4
commit
a104afc670
@ -18,7 +18,7 @@
|
||||
<key command="ImportSpriteSheet" shortcut="Ctrl+I" mac="Cmd+I" />
|
||||
<key command="ExportSpriteSheet" shortcut="Ctrl+E" mac="Cmd+E" />
|
||||
<key command="RepeatLastExport" shortcut="Ctrl+Shift+X" mac="Cmd+Shift+X" />
|
||||
<key command="AdvancedMode" shortcut="F11" />
|
||||
<key command="AdvancedMode" shortcut="F" />
|
||||
<key command="DeveloperConsole" shortcut="F12" />
|
||||
<key command="Exit" win="Ctrl+Q" linux="Ctrl+Q" mac="Cmd+Q" />
|
||||
<key command="Exit" win="Alt+F4" />
|
||||
@ -777,7 +777,8 @@
|
||||
<param name="switch" value="true" />
|
||||
</item>
|
||||
<item command="TogglePreview" text="Previe&w" />
|
||||
<item command="FullscreenPreview" text="&Fullscreen Preview" />
|
||||
<item command="AdvancedMode" text="&Full Screen Mode" />
|
||||
<item command="FullscreenPreview" text="F&ull Screen Preview" />
|
||||
<item command="Home" text="&Home" />
|
||||
<separator />
|
||||
<item command="Refresh" text="&Refresh && Reload Skin" />
|
||||
|
21
data/palettes/edg16.gpl
Normal file
21
data/palettes/edg16.gpl
Normal file
@ -0,0 +1,21 @@
|
||||
GIMP Palette
|
||||
#
|
||||
# By ENDESGA Studios
|
||||
# https://twitter.com/ENDESGA
|
||||
#
|
||||
228 166 114 Birch
|
||||
184 111 80 Oak
|
||||
116 63 57 Pine
|
||||
63 40 50 Darkbark
|
||||
158 40 53 Blood
|
||||
229 59 68 Fabric
|
||||
251 146 43 Candle
|
||||
255 231 98 Glow
|
||||
99 198 77 Flora
|
||||
50 115 69 Moss
|
||||
25 61 63 Mold
|
||||
79 103 129 Iron
|
||||
175 191 210 Aluminium
|
||||
255 255 255 White
|
||||
44 232 244 Ion
|
||||
4 132 209 Archaeon
|
37
data/palettes/edg32.gpl
Normal file
37
data/palettes/edg32.gpl
Normal file
@ -0,0 +1,37 @@
|
||||
GIMP Palette
|
||||
#
|
||||
# By ENDESGA Studios
|
||||
# https://twitter.com/ENDESGA
|
||||
#
|
||||
190 74 47 Tetanus
|
||||
216 118 68 Rust
|
||||
234 212 170 Birch
|
||||
228 166 114 Sap
|
||||
184 111 80 Oak
|
||||
116 63 57 Pine
|
||||
63 40 50 Darkbark
|
||||
158 40 53 Blood
|
||||
228 59 68 Fabric
|
||||
247 118 34 Amber
|
||||
254 174 52 Glow
|
||||
254 231 97 Light
|
||||
99 199 77 Glade
|
||||
62 137 72 Flora
|
||||
38 92 66 Moss
|
||||
25 60 62 Mold
|
||||
18 78 137 Deep
|
||||
0 149 233 Archaeon
|
||||
44 232 245 Ion
|
||||
255 255 255 White
|
||||
192 203 220 Aluminium
|
||||
139 155 180 Zinc
|
||||
90 105 136 Iron
|
||||
58 68 102 Steel
|
||||
38 43 68 Shade
|
||||
255 0 68 Iiem
|
||||
24 20 37 Ink
|
||||
104 56 108 Lilac
|
||||
181 80 136 Petal
|
||||
246 117 122 Peach
|
||||
232 183 150 Skin
|
||||
194 133 105 Shadeskin
|
@ -86,6 +86,7 @@
|
||||
<global>
|
||||
<section id="general">
|
||||
<option id="screen_scale" type="int" default="0" />
|
||||
<option id="ui_scale" type="int" default="1" migrate="experimental.ui_scale" />
|
||||
<option id="gpu_acceleration" type="bool" default="false" />
|
||||
<option id="visible_timeline" type="bool" default="false" />
|
||||
<option id="autoshow_timeline" type="bool" default="true" migrate="Options.AutoShowTimeline" />
|
||||
@ -126,7 +127,6 @@
|
||||
<option id="mini_font" type="std::string" migrate="Options.UserMiniFont" />
|
||||
</section>
|
||||
<section id="experimental" text="Experimental">
|
||||
<option id="ui_scale" type="int" default="1" />
|
||||
<option id="use_native_file_dialog" type="bool" default="false" />
|
||||
<option id="flash_layer" type="bool" default="false" migrate="Options.FlashLayer" />
|
||||
</section>
|
||||
@ -280,6 +280,7 @@
|
||||
<option id="resize_scale" type="double" default="1" />
|
||||
</section>
|
||||
<section id="sprite_sheet">
|
||||
<option id="defined" type="bool" default="false" />
|
||||
<option id="type" type="app::SpriteSheetType" default="app::SpriteSheetType::None" />
|
||||
<option id="columns" type="int" default="0" />
|
||||
<option id="rows" type="int" default="0" />
|
||||
|
@ -192,8 +192,8 @@
|
||||
<part id="sunken_focused" x="0" y="48" w1="4" w2="4" w3="4" h1="4" h2="4" h3="4" />
|
||||
<part id="sunken2_normal" x="0" y="64" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
||||
<part id="sunken2_focused" x="0" y="80" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
||||
<part id="sunken_mini_normal" x="16" y="64" w1="4" w2="4" w3="4" h1="4" h2="4" h3="4" />
|
||||
<part id="sunken_mini_focused" x="16" y="80" w1="4" w2="4" w3="4" h1="4" h2="4" h3="4" />
|
||||
<part id="sunken_mini_normal" x="16" y="64" w1="4" w2="4" w3="4" h1="3" h2="6" h3="3" />
|
||||
<part id="sunken_mini_focused" x="16" y="80" w1="4" w2="4" w3="4" h1="3" h2="6" h3="3" />
|
||||
<part id="window" x="0" y="0" w1="3" w2="7" w3="3" h1="15" h2="4" h3="5" />
|
||||
<part id="menu" x="0" y="96" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
|
||||
<part id="window_close_button_normal" x="16" y="0" w="9" h="11" />
|
||||
@ -212,10 +212,10 @@
|
||||
<part id="slider_empty" x="16" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="slider_full_focused" x="0" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="slider_empty_focused" x="16" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="mini_slider_full" x="32" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="mini_slider_empty" x="48" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="mini_slider_full_focused" x="32" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="mini_slider_empty_focused" x="48" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||
<part id="mini_slider_full" x="32" y="144" w1="2" w2="12" w3="2" h1="2" h2="11" h3="3" />
|
||||
<part id="mini_slider_empty" x="48" y="144" w1="2" w2="12" w3="2" h1="2" h2="11" h3="3" />
|
||||
<part id="mini_slider_full_focused" x="32" y="160" w1="2" w2="12" w3="2" h1="2" h2="11" h3="3" />
|
||||
<part id="mini_slider_empty_focused" x="48" y="160" w1="2" w2="12" w3="2" h1="2" h2="11" h3="3" />
|
||||
<part id="mini_slider_thumb" x="32" y="176" w="5" h="4" />
|
||||
<part id="mini_slider_thumb_focused" x="48" y="176" w="5" h="4" />
|
||||
<part id="separator_horz" x="32" y="80" w="9" h="5" />
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/tools/active_tool.h"
|
||||
#include "app/tools/tool.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "base/convert_to.h"
|
||||
@ -71,7 +72,9 @@ void ChangeBrushCommand::onLoadParams(const Params& params)
|
||||
|
||||
void ChangeBrushCommand::onExecute(Context* context)
|
||||
{
|
||||
tools::Tool* tool = App::instance()->activeTool();
|
||||
// Change the brush of the selected tool in the toolbar (not the
|
||||
// active tool which might be different, e.g. the quick tool)
|
||||
tools::Tool* tool = App::instance()->activeToolManager()->selectedTool();
|
||||
ToolPreferences::Brush& brush =
|
||||
Preferences::instance().tool(tool).brush;
|
||||
|
||||
@ -97,7 +100,7 @@ void ChangeBrushCommand::onExecute(Context* context)
|
||||
break;
|
||||
case CustomBrush:
|
||||
App::instance()->contextBar()
|
||||
->setActiveBrushBySlot(m_slot);
|
||||
->setActiveBrushBySlot(tool, m_slot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -769,6 +769,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
if (!window.ok())
|
||||
return;
|
||||
|
||||
docPref.spriteSheet.defined(true);
|
||||
docPref.spriteSheet.type(window.spriteSheetTypeValue());
|
||||
docPref.spriteSheet.columns(window.columnsValue());
|
||||
docPref.spriteSheet.rows(window.rowsValue());
|
||||
@ -790,6 +791,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context)
|
||||
// Default preferences for future sprites
|
||||
DocumentPreferences& defPref(Preferences::instance().document(nullptr));
|
||||
defPref.spriteSheet = docPref.spriteSheet;
|
||||
defPref.spriteSheet.defined(false);
|
||||
if (!defPref.spriteSheet.textureFilename().empty())
|
||||
defPref.spriteSheet.textureFilename.setValueAndDefault(kSpecifiedFilename);
|
||||
if (!defPref.spriteSheet.dataFilename().empty())
|
||||
|
@ -168,6 +168,10 @@ private:
|
||||
}
|
||||
|
||||
void onCommitChange() {
|
||||
// Nothing to do here, as there is no layer selected.
|
||||
if (!m_layer)
|
||||
return;
|
||||
|
||||
base::ScopedValue<bool> switchSelf(m_selfUpdate, true, false);
|
||||
|
||||
m_timer.stop();
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -103,7 +103,8 @@ void MaskByColorCommand::onExecute(Context* context)
|
||||
m_buttonColor = new ColorButton
|
||||
(get_config_color("MaskColor", "Color",
|
||||
ColorBar::instance()->getFgColor()),
|
||||
sprite->pixelFormat());
|
||||
sprite->pixelFormat(),
|
||||
false);
|
||||
label_tolerance = new Label("Tolerance:");
|
||||
m_sliderTolerance = new Slider(0, 255, get_config_int("MaskColor", "Tolerance", 0));
|
||||
m_checkPreview = new CheckBox("&Preview");
|
||||
|
@ -68,11 +68,11 @@ public:
|
||||
, m_globPref(m_pref.document(nullptr))
|
||||
, m_docPref(m_pref.document(context->activeDocument()))
|
||||
, m_curPref(&m_docPref)
|
||||
, m_checked_bg_color1(new ColorButton(app::Color::fromMask(), IMAGE_RGB))
|
||||
, m_checked_bg_color2(new ColorButton(app::Color::fromMask(), IMAGE_RGB))
|
||||
, m_pixelGridColor(new ColorButton(app::Color::fromMask(), IMAGE_RGB))
|
||||
, m_gridColor(new ColorButton(app::Color::fromMask(), IMAGE_RGB))
|
||||
, m_cursorColor(new ColorButton(m_pref.cursor.cursorColor(), IMAGE_RGB))
|
||||
, m_checked_bg_color1(new ColorButton(app::Color::fromMask(), IMAGE_RGB, false))
|
||||
, m_checked_bg_color2(new ColorButton(app::Color::fromMask(), IMAGE_RGB, false))
|
||||
, m_pixelGridColor(new ColorButton(app::Color::fromMask(), IMAGE_RGB, false))
|
||||
, m_gridColor(new ColorButton(app::Color::fromMask(), IMAGE_RGB, false))
|
||||
, m_cursorColor(new ColorButton(m_pref.cursor.cursorColor(), IMAGE_RGB, false))
|
||||
, m_curSection(curSection)
|
||||
{
|
||||
sectionListbox()->Change.connect(base::Bind<void>(&OptionsWindow::onChangeSection, this));
|
||||
@ -173,7 +173,7 @@ public:
|
||||
|
||||
uiScale()->setSelectedItemIndex(
|
||||
uiScale()->findItemIndexByValue(
|
||||
base::convert_to<std::string>(m_pref.experimental.uiScale())));
|
||||
base::convert_to<std::string>(m_pref.general.uiScale())));
|
||||
|
||||
if ((int(she::instance()->capabilities()) &
|
||||
int(she::Capabilities::GpuAccelerationSwitch)) == int(she::Capabilities::GpuAccelerationSwitch)) {
|
||||
@ -312,8 +312,8 @@ public:
|
||||
}
|
||||
|
||||
int newUIScale = base::convert_to<int>(uiScale()->getValue());
|
||||
if (newUIScale != m_pref.experimental.uiScale()) {
|
||||
m_pref.experimental.uiScale(newUIScale);
|
||||
if (newUIScale != m_pref.general.uiScale()) {
|
||||
m_pref.general.uiScale(newUIScale);
|
||||
warnings += "<<- UI Elements Scale";
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -51,8 +51,7 @@ void RepeatLastExportCommand::onExecute(Context* context)
|
||||
DocumentPreferences& docPref =
|
||||
Preferences::instance().document(document);
|
||||
|
||||
params.set("ui",
|
||||
(docPref.spriteSheet.type() == app::SpriteSheetType::None ? "1": "0"));
|
||||
params.set("ui", (docPref.spriteSheet.defined() ? "0": "1"));
|
||||
}
|
||||
|
||||
context->executeCommand(cmd, params);
|
||||
|
@ -106,7 +106,8 @@ void SpritePropertiesCommand::onExecute(Context* context)
|
||||
|
||||
if (sprite->pixelFormat() == IMAGE_INDEXED) {
|
||||
color_button = new ColorButton(app::Color::fromIndex(sprite->transparentColor()),
|
||||
IMAGE_INDEXED);
|
||||
IMAGE_INDEXED,
|
||||
false);
|
||||
|
||||
window.transparentColorPlaceholder()->addChild(color_button);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "doc/cel.h"
|
||||
#include "doc/file/col_file.h"
|
||||
#include "doc/file/gpl_file.h"
|
||||
#include "doc/file/hex_file.h"
|
||||
#include "doc/file/pal_file.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
@ -33,14 +34,14 @@ using namespace doc;
|
||||
std::string get_readable_palette_extensions()
|
||||
{
|
||||
std::string buf = get_readable_extensions();
|
||||
buf += ",col,gpl,pal";
|
||||
buf += ",col,gpl,hex,pal";
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string get_writable_palette_extensions()
|
||||
{
|
||||
std::string buf = get_writable_extensions();
|
||||
buf += ",col,gpl,pal";
|
||||
buf += ",col,gpl,hex,pal";
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -55,6 +56,9 @@ Palette* load_palette(const char *filename)
|
||||
else if (ext == "gpl") {
|
||||
pal = doc::file::load_gpl_file(filename);
|
||||
}
|
||||
else if (ext == "hex") {
|
||||
pal = doc::file::load_hex_file(filename);
|
||||
}
|
||||
else if (ext == "pal") {
|
||||
pal = doc::file::load_pal_file(filename);
|
||||
}
|
||||
@ -101,13 +105,16 @@ bool save_palette(const char *filename, const Palette* pal, int columns)
|
||||
else if (ext == "gpl") {
|
||||
success = doc::file::save_gpl_file(pal, filename);
|
||||
}
|
||||
else if (ext == "hex") {
|
||||
success = doc::file::save_hex_file(pal, filename);
|
||||
}
|
||||
else if (ext == "pal") {
|
||||
success = doc::file::save_pal_file(pal, filename);
|
||||
}
|
||||
else {
|
||||
FileFormat* ff = FileFormatsManager::instance()->getFileFormatByExtension(ext.c_str());
|
||||
if (ff && ff->support(FILE_SUPPORT_SAVE)) {
|
||||
int w = (columns > 0 ? columns: pal->size());
|
||||
int w = (columns > 0 ? MID(0, columns, pal->size()): pal->size());
|
||||
int h = (pal->size() / w) + (pal->size() % w > 0 ? 1: 0);
|
||||
|
||||
app::Context tmpContext;
|
||||
@ -118,18 +125,25 @@ bool save_palette(const char *filename, const Palette* pal, int columns)
|
||||
Sprite* sprite = doc->sprite();
|
||||
doc->sprite()->setPalette(pal, false);
|
||||
|
||||
Layer* layer = sprite->root()->firstLayer();
|
||||
LayerImage* layer = static_cast<LayerImage*>(sprite->root()->firstLayer());
|
||||
layer->configureAsBackground();
|
||||
|
||||
Image* image = layer->cel(frame_t(0))->image();
|
||||
image->clear(0);
|
||||
|
||||
int x, y, c;
|
||||
for (y=c=0; y<h; ++y) {
|
||||
for (x=0; x<w; ++x, ++c) {
|
||||
for (x=0; x<w; ++x) {
|
||||
if (doc->colorMode() == doc::ColorMode::INDEXED)
|
||||
image->putPixel(x, y, c);
|
||||
else
|
||||
image->putPixel(x, y, pal->entry(c));
|
||||
|
||||
if (++c == pal->size())
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:;
|
||||
|
||||
doc->setFilename(filename);
|
||||
success = (save_document(&tmpContext, doc) == 0);
|
||||
|
@ -179,7 +179,7 @@ int init_module_gui()
|
||||
|
||||
// Setup the GUI theme for all widgets
|
||||
gui_theme = new SkinTheme();
|
||||
gui_theme->setScale(Preferences::instance().experimental.uiScale());
|
||||
gui_theme->setScale(Preferences::instance().general.uiScale());
|
||||
CurrentTheme::set(gui_theme);
|
||||
|
||||
if (maximized)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2015 David Capello
|
||||
// Copyright (C) 2015-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "app/tools/symmetries.h"
|
||||
|
||||
#include "app/tools/point_shape.h"
|
||||
#include "app/tools/stroke.h"
|
||||
#include "app/tools/tool_loop.h"
|
||||
#include "doc/brush.h"
|
||||
@ -20,7 +21,11 @@ namespace tools {
|
||||
void HorizontalSymmetry::generateStrokes(const Stroke& mainStroke, Strokes& strokes,
|
||||
ToolLoop* loop)
|
||||
{
|
||||
int adjust = (loop->getBrush()->bounds().w % 2);
|
||||
int adjust;
|
||||
if (loop->getPointShape()->isFloodFill())
|
||||
adjust = 1;
|
||||
else
|
||||
adjust = (loop->getBrush()->bounds().w % 2);
|
||||
|
||||
strokes.push_back(mainStroke);
|
||||
|
||||
@ -33,7 +38,11 @@ void HorizontalSymmetry::generateStrokes(const Stroke& mainStroke, Strokes& stro
|
||||
void VerticalSymmetry::generateStrokes(const Stroke& mainStroke, Strokes& strokes,
|
||||
ToolLoop* loop)
|
||||
{
|
||||
int adjust = (loop->getBrush()->bounds().h % 2);
|
||||
int adjust;
|
||||
if (loop->getPointShape()->isFloodFill())
|
||||
adjust = 1;
|
||||
else
|
||||
adjust = (loop->getBrush()->bounds().h % 2);
|
||||
|
||||
strokes.push_back(mainStroke);
|
||||
|
||||
|
@ -91,11 +91,11 @@ public:
|
||||
private:
|
||||
void onClick() override {
|
||||
ContextBar* contextBar = App::instance()->contextBar();
|
||||
tools::Tool* tool = App::instance()->activeTool();
|
||||
|
||||
if (m_slot >= 0)
|
||||
contextBar->setActiveBrushBySlot(m_slot);
|
||||
contextBar->setActiveBrushBySlot(tool, m_slot);
|
||||
else if (m_brush.hasBrush()) {
|
||||
tools::Tool* tool = App::instance()->activeTool();
|
||||
auto& brushPref = Preferences::instance().tool(tool).brush;
|
||||
BrushRef brush;
|
||||
|
||||
|
@ -139,8 +139,8 @@ ColorBar::ColorBar(int align)
|
||||
, m_tintShadeTone(nullptr)
|
||||
, m_spectrum(nullptr)
|
||||
, m_wheel(nullptr)
|
||||
, m_fgColor(app::Color::fromRgb(255, 255, 255), IMAGE_RGB)
|
||||
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB)
|
||||
, m_fgColor(app::Color::fromRgb(255, 255, 255), IMAGE_RGB, true)
|
||||
, m_bgColor(app::Color::fromRgb(0, 0, 0), IMAGE_RGB, true)
|
||||
, m_fgWarningIcon(new WarningIcon)
|
||||
, m_bgWarningIcon(new WarningIcon)
|
||||
, m_lock(false)
|
||||
@ -183,12 +183,7 @@ ColorBar::ColorBar(int align)
|
||||
setColorSelector(
|
||||
Preferences::instance().colorBar.selector());
|
||||
|
||||
Box* buttonsBox = new HBox();
|
||||
buttonsBox->addChild(&m_buttons);
|
||||
m_buttons.setMaxSize(gfx::Size(m_buttons.maxSize().w,
|
||||
16*ui::guiscale()));
|
||||
|
||||
addChild(buttonsBox);
|
||||
addChild(&m_buttons);
|
||||
addChild(&m_splitter);
|
||||
|
||||
HBox* fgBox = new HBox;
|
||||
@ -202,6 +197,8 @@ ColorBar::ColorBar(int align)
|
||||
addChild(fgBox);
|
||||
addChild(bgBox);
|
||||
|
||||
m_fgColor.setId("fg_color");
|
||||
m_bgColor.setId("bg_color");
|
||||
m_fgColor.setExpansive(true);
|
||||
m_bgColor.setExpansive(true);
|
||||
|
||||
@ -236,6 +233,8 @@ ColorBar::ColorBar(int align)
|
||||
m_buttons.addItem(theme->parts.palSort());
|
||||
m_buttons.addItem(theme->parts.palPresets());
|
||||
m_buttons.addItem(theme->parts.palOptions());
|
||||
m_buttons.setMaxSize(gfx::Size(m_buttons.sizeHint().w,
|
||||
16*ui::guiscale()));
|
||||
|
||||
// Tooltips
|
||||
TooltipManager* tooltipManager = new TooltipManager();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "doc/layer.h"
|
||||
#include "doc/site.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "gfx/rect_io.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
@ -41,12 +42,15 @@ static WidgetType colorbutton_type()
|
||||
return type;
|
||||
}
|
||||
|
||||
ColorButton::ColorButton(const app::Color& color, PixelFormat pixelFormat)
|
||||
ColorButton::ColorButton(const app::Color& color,
|
||||
PixelFormat pixelFormat,
|
||||
bool canPinSelector)
|
||||
: ButtonBase("", colorbutton_type(), kButtonWidget, kButtonWidget)
|
||||
, m_color(color)
|
||||
, m_pixelFormat(pixelFormat)
|
||||
, m_window(NULL)
|
||||
, m_dependOnLayer(false)
|
||||
, m_canPinSelector(canPinSelector)
|
||||
{
|
||||
this->setFocusStop(true);
|
||||
|
||||
@ -102,6 +106,13 @@ bool ColorButton::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
|
||||
case kOpenMessage:
|
||||
if (!m_windowDefaultBounds.isEmpty() &&
|
||||
this->isVisible()) {
|
||||
openSelectorDialog();
|
||||
}
|
||||
break;
|
||||
|
||||
case kCloseMessage:
|
||||
if (m_window && m_window->isVisible())
|
||||
m_window->closeWindow(NULL);
|
||||
@ -233,34 +244,65 @@ void ColorButton::onClick(Event& ev)
|
||||
}
|
||||
}
|
||||
|
||||
void ColorButton::onLoadLayout(ui::LoadLayoutEvent& ev)
|
||||
{
|
||||
if (m_canPinSelector) {
|
||||
bool pinned = false;
|
||||
ev.stream() >> pinned;
|
||||
if (ev.stream() && pinned)
|
||||
ev.stream() >> m_windowDefaultBounds;
|
||||
}
|
||||
}
|
||||
|
||||
void ColorButton::onSaveLayout(ui::SaveLayoutEvent& ev)
|
||||
{
|
||||
if (m_canPinSelector && m_window && m_window->isPinned())
|
||||
ev.stream() << 1 << ' ' << m_window->bounds();
|
||||
else
|
||||
ev.stream() << 0;
|
||||
}
|
||||
|
||||
void ColorButton::openSelectorDialog()
|
||||
{
|
||||
int x, y;
|
||||
bool pinned = (!m_windowDefaultBounds.isEmpty());
|
||||
|
||||
if (m_window == NULL) {
|
||||
m_window = new ColorPopup();
|
||||
m_window = new ColorPopup(m_canPinSelector);
|
||||
m_window->ColorChange.connect(&ColorButton::onWindowColorChange, this);
|
||||
}
|
||||
|
||||
if (pinned)
|
||||
m_window->setPinned(true);
|
||||
|
||||
m_window->setColor(m_color, ColorPopup::ChangeType);
|
||||
m_window->openWindow();
|
||||
|
||||
x = MID(0, bounds().x, ui::display_w()-m_window->bounds().w);
|
||||
if (bounds().y2() <= ui::display_h()-m_window->bounds().h)
|
||||
y = MAX(0, bounds().y2());
|
||||
else
|
||||
y = MAX(0, bounds().y-m_window->bounds().h);
|
||||
|
||||
m_window->positionWindow(x, y);
|
||||
gfx::Rect winBounds = m_windowDefaultBounds;
|
||||
if (!pinned) {
|
||||
winBounds = gfx::Rect(m_window->bounds().origin(),
|
||||
m_window->sizeHint());
|
||||
winBounds.x = MID(0, bounds().x, ui::display_w()-winBounds.w);
|
||||
if (bounds().y2() <= ui::display_h()-winBounds.h)
|
||||
winBounds.y = MAX(0, bounds().y2());
|
||||
else
|
||||
winBounds.y = MAX(0, bounds().y-winBounds.h);
|
||||
}
|
||||
winBounds.x = MID(0, winBounds.x, ui::display_w()-winBounds.w);
|
||||
winBounds.y = MID(0, winBounds.y, ui::display_h()-winBounds.h);
|
||||
m_window->setBounds(winBounds);
|
||||
|
||||
m_window->manager()->dispatchMessages();
|
||||
m_window->layout();
|
||||
|
||||
// Setup the hot-region
|
||||
gfx::Rect rc = bounds().createUnion(m_window->bounds());
|
||||
rc.enlarge(8);
|
||||
gfx::Region rgn(rc);
|
||||
static_cast<PopupWindow*>(m_window)->setHotRegion(rgn);
|
||||
if (!pinned) {
|
||||
gfx::Rect rc = bounds().createUnion(m_window->bounds());
|
||||
rc.enlarge(8);
|
||||
gfx::Region rgn(rc);
|
||||
static_cast<PopupWindow*>(m_window)->setHotRegion(rgn);
|
||||
}
|
||||
|
||||
m_windowDefaultBounds = gfx::Rect();
|
||||
}
|
||||
|
||||
void ColorButton::closeSelectorDialog()
|
||||
@ -278,6 +320,24 @@ void ColorButton::onActiveSiteChange(const Site& site)
|
||||
{
|
||||
if (m_dependOnLayer)
|
||||
invalidate();
|
||||
|
||||
if (m_canPinSelector) {
|
||||
// Hide window
|
||||
if (!site.document()) {
|
||||
if (m_window)
|
||||
m_window->setVisible(false);
|
||||
}
|
||||
// Show window if it's pinned
|
||||
else {
|
||||
// Check if it's pinned from the preferences (m_windowDefaultBounds)
|
||||
if (!m_window && !m_windowDefaultBounds.isEmpty())
|
||||
openSelectorDialog();
|
||||
// Or check if the window was hidden but it's pinned, so we've
|
||||
// to show it again.
|
||||
else if (m_window && m_window->isPinned())
|
||||
m_window->setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -22,7 +22,9 @@ namespace app {
|
||||
, public doc::ContextObserver
|
||||
, public IColorSource {
|
||||
public:
|
||||
ColorButton(const app::Color& color, PixelFormat pixelFormat);
|
||||
ColorButton(const app::Color& color,
|
||||
PixelFormat pixelFormat,
|
||||
bool canPinSelector);
|
||||
~ColorButton();
|
||||
|
||||
PixelFormat pixelFormat() const;
|
||||
@ -43,6 +45,8 @@ namespace app {
|
||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
void onClick(ui::Event& ev) override;
|
||||
void onLoadLayout(ui::LoadLayoutEvent& ev) override;
|
||||
void onSaveLayout(ui::SaveLayoutEvent& ev) override;
|
||||
|
||||
private:
|
||||
void openSelectorDialog();
|
||||
@ -53,7 +57,9 @@ namespace app {
|
||||
app::Color m_color;
|
||||
PixelFormat m_pixelFormat;
|
||||
ColorPopup* m_window;
|
||||
gfx::Rect m_windowDefaultBounds;
|
||||
bool m_dependOnLayer;
|
||||
bool m_canPinSelector;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -47,7 +47,7 @@ enum {
|
||||
MASK_MODE
|
||||
};
|
||||
|
||||
ColorPopup::ColorPopup()
|
||||
ColorPopup::ColorPopup(bool canPin)
|
||||
: PopupWindowPin("Color Selector", ClickBehavior::CloseOnClickInOtherWindow)
|
||||
, m_vbox(VERTICAL)
|
||||
, m_topBox(HORIZONTAL)
|
||||
@ -55,6 +55,7 @@ ColorPopup::ColorPopup()
|
||||
, m_colorPalette(false, PaletteView::SelectOneColor, this, 7*guiscale())
|
||||
, m_colorType(5)
|
||||
, m_maskLabel("Transparent Color Selected")
|
||||
, m_canPin(canPin)
|
||||
, m_disableHexUpdate(false)
|
||||
{
|
||||
m_colorType.addItem("Index");
|
||||
@ -69,6 +70,9 @@ ColorPopup::ColorPopup()
|
||||
m_colorPaletteContainer.attachToView(&m_colorPalette);
|
||||
|
||||
m_colorPaletteContainer.setExpansive(true);
|
||||
m_rgbSliders.setExpansive(true);
|
||||
m_hsvSliders.setExpansive(true);
|
||||
m_graySlider.setExpansive(true);
|
||||
|
||||
m_topBox.addChild(&m_colorType);
|
||||
m_topBox.addChild(new Separator("", VERTICAL));
|
||||
@ -94,6 +98,9 @@ ColorPopup::ColorPopup()
|
||||
m_graySlider.ColorChange.connect(&ColorPopup::onColorSlidersChange, this);
|
||||
m_hexColorEntry.ColorChange.connect(&ColorPopup::onColorHexEntryChange, this);
|
||||
|
||||
if (!m_canPin)
|
||||
showPin(false);
|
||||
|
||||
selectColorType(app::Color::RgbType);
|
||||
setSizeHint(gfx::Size(300*guiscale(), sizeHint().h));
|
||||
|
||||
@ -132,6 +139,26 @@ app::Color ColorPopup::getColor() const
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void ColorPopup::onMakeFloating()
|
||||
{
|
||||
PopupWindowPin::onMakeFloating();
|
||||
|
||||
if (m_canPin) {
|
||||
setSizeable(true);
|
||||
setMoveable(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPopup::onMakeFixed()
|
||||
{
|
||||
PopupWindowPin::onMakeFixed();
|
||||
|
||||
if (m_canPin) {
|
||||
setSizeable(false);
|
||||
setMoveable(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPopup::onPaletteViewIndexChange(int index, ui::MouseButtons buttons)
|
||||
{
|
||||
setColorWithSignal(app::Color::fromIndex(index));
|
||||
|
@ -31,7 +31,7 @@ namespace app {
|
||||
DoNotChangeType
|
||||
};
|
||||
|
||||
ColorPopup();
|
||||
ColorPopup(bool canPin);
|
||||
~ColorPopup();
|
||||
|
||||
void setColor(const app::Color& color, SetColorOptions options);
|
||||
@ -41,6 +41,8 @@ namespace app {
|
||||
base::Signal1<void, const app::Color&> ColorChange;
|
||||
|
||||
protected:
|
||||
void onMakeFloating() override;
|
||||
void onMakeFixed() override;
|
||||
void onColorSlidersChange(ColorSlidersChangeEvent& ev);
|
||||
void onColorHexEntryChange(const app::Color& color);
|
||||
void onColorTypeClick();
|
||||
@ -66,6 +68,7 @@ namespace app {
|
||||
GraySlider m_graySlider;
|
||||
ui::Label m_maskLabel;
|
||||
base::ScopedConnection m_onPaletteChangeConn;
|
||||
bool m_canPin;
|
||||
|
||||
// This variable is used to avoid updating the m_hexColorEntry text
|
||||
// when the color change is generated from a
|
||||
|
@ -68,6 +68,7 @@ namespace {
|
||||
color = color_utils::color_for_ui(app::Color::fromHsv(m_color.getHue(), m_color.getSaturation(), 100 * x / w));
|
||||
break;
|
||||
case ColorSliders::Gray:
|
||||
case ColorSliders::Alpha:
|
||||
color = color_utils::color_for_ui(app::Color::fromGray(255 * x / w));
|
||||
break;
|
||||
}
|
||||
@ -163,9 +164,9 @@ void ColorSliders::addSlider(Channel channel, const char* labelText, int min, in
|
||||
box->setMaxSize(sz);
|
||||
entry->setMaxSize(sz);
|
||||
|
||||
m_grid.addChildInCell(label, 1, 1, LEFT | MIDDLE);
|
||||
m_grid.addChildInCell(box, 1, 1, HORIZONTAL | VERTICAL | EXPANSIVE);
|
||||
m_grid.addChildInCell(entry, 1, 1, LEFT | MIDDLE);
|
||||
m_grid.addChildInCell(label, 1, 1, LEFT | MIDDLE);
|
||||
m_grid.addChildInCell(box, 1, 1, HORIZONTAL | VERTICAL);
|
||||
m_grid.addChildInCell(entry, 1, 1, LEFT | MIDDLE);
|
||||
}
|
||||
|
||||
void ColorSliders::setAbsSliderValue(int sliderIndex, int value)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -45,7 +45,7 @@ namespace app {
|
||||
base::Signal1<void, ColorSlidersChangeEvent&> ColorChange;
|
||||
|
||||
protected:
|
||||
void onSizeHint(ui::SizeHintEvent& ev);
|
||||
void onSizeHint(ui::SizeHintEvent& ev) override;
|
||||
|
||||
// For derived classes
|
||||
void addSlider(Channel channel, const char* labelText, int min, int max);
|
||||
|
@ -886,7 +886,7 @@ class ContextBar::TransparentColorField : public HBox {
|
||||
public:
|
||||
TransparentColorField(ContextBar* owner)
|
||||
: m_icon(1)
|
||||
, m_maskColor(app::Color::fromMask(), IMAGE_RGB)
|
||||
, m_maskColor(app::Color::fromMask(), IMAGE_RGB, false)
|
||||
, m_owner(owner) {
|
||||
SkinTheme* theme = SkinTheme::instance();
|
||||
|
||||
@ -1700,14 +1700,17 @@ void ContextBar::updateAutoSelectLayer(bool state)
|
||||
m_autoSelectLayer->setSelected(state);
|
||||
}
|
||||
|
||||
void ContextBar::setActiveBrushBySlot(int slot)
|
||||
void ContextBar::setActiveBrushBySlot(tools::Tool* tool, int slot)
|
||||
{
|
||||
ASSERT(tool);
|
||||
if (!tool)
|
||||
return;
|
||||
|
||||
AppBrushes& brushes = App::instance()->brushes();
|
||||
BrushSlot brush = brushes.getBrushSlot(slot);
|
||||
if (!brush.isEmpty()) {
|
||||
brushes.lockBrushSlot(slot);
|
||||
|
||||
Tool* tool = App::instance()->activeTool();
|
||||
Preferences& pref = Preferences::instance();
|
||||
ToolPreferences& toolPref = pref.tool(tool);
|
||||
ToolPreferences::Brush& brushPref = toolPref.brush;
|
||||
@ -1752,7 +1755,7 @@ void ContextBar::setActiveBrushBySlot(int slot)
|
||||
tools::FreehandAlgorithm::REGULAR));
|
||||
}
|
||||
else {
|
||||
updateForTool(App::instance()->activeTool());
|
||||
updateForTool(tool);
|
||||
m_brushType->showPopupAndHighlightSlot(slot);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ namespace app {
|
||||
void updateAutoSelectLayer(bool state);
|
||||
|
||||
void setActiveBrush(const doc::BrushRef& brush);
|
||||
void setActiveBrushBySlot(int slot);
|
||||
void setActiveBrushBySlot(tools::Tool* tool, int slot);
|
||||
doc::BrushRef activeBrush(tools::Tool* tool = nullptr) const;
|
||||
void discardActiveBrush();
|
||||
|
||||
|
@ -198,11 +198,28 @@ void MovingPixelsState::onActiveToolChange(Editor* editor, tools::Tool* tool)
|
||||
|
||||
// If the user changed the tool when he/she is moving pixels,
|
||||
// we have to drop the pixels only if the new tool is not selection...
|
||||
if (m_pixelsMovement &&
|
||||
(!tool->getInk(0)->isSelection() ||
|
||||
!tool->getInk(1)->isSelection())) {
|
||||
// We have to drop pixels
|
||||
dropPixels();
|
||||
if (m_pixelsMovement) {
|
||||
// We don't want to drop pixels in case the user change the tool
|
||||
// for scrolling/zooming/picking colors.
|
||||
if ((!tool->getInk(0)->isSelection() ||
|
||||
!tool->getInk(1)->isSelection()) &&
|
||||
(!tool->getInk(0)->isScrollMovement() ||
|
||||
!tool->getInk(1)->isScrollMovement()) &&
|
||||
(!tool->getInk(0)->isZoom() ||
|
||||
!tool->getInk(1)->isZoom()) &&
|
||||
(!tool->getInk(0)->isEyedropper() ||
|
||||
!tool->getInk(1)->isEyedropper())) {
|
||||
// We have to drop pixels
|
||||
dropPixels();
|
||||
}
|
||||
// If we've temporarily gone to a non-selection tool and now we're
|
||||
// back, we've just to update the context bar to show the "moving
|
||||
// pixels" controls (e.g. OK/Cancel movement buttons).
|
||||
else if (tool->getInk(0)->isSelection() ||
|
||||
tool->getInk(1)->isSelection()) {
|
||||
ContextBar* contextBar = App::instance()->contextBar();
|
||||
contextBar->updateForMovingPixels();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,8 +494,13 @@ void MovingPixelsState::onBeforeCommandExecution(CommandExecutionEvent& ev)
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't drop pixels if the user zooms/scrolls/picks a color
|
||||
// using commands.
|
||||
else if ((command->id() == CommandId::Zoom) ||
|
||||
(command->id() == CommandId::Scroll)) {
|
||||
(command->id() == CommandId::Scroll) ||
|
||||
(command->id() == CommandId::Eyedropper) ||
|
||||
// DiscardBrush is used by Eyedropper command
|
||||
(command->id() == CommandId::DiscardBrush)) {
|
||||
// Do not drop pixels
|
||||
return;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -88,8 +88,8 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void onSelect() override {
|
||||
if (m_image)
|
||||
void onSelect(bool selected) override {
|
||||
if (!selected || m_image)
|
||||
return;
|
||||
|
||||
ListBox* listbox = static_cast<ListBox*>(parent());
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -12,6 +12,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "app/ui/hex_color_entry.h"
|
||||
#include "base/hex.h"
|
||||
#include "gfx/border.h"
|
||||
#include "ui/theme.h"
|
||||
|
||||
@ -19,13 +20,6 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
static inline bool is_hex_digit(char digit)
|
||||
{
|
||||
return ((digit >= '0' && digit <= '9') ||
|
||||
(digit >= 'a' && digit <= 'f') ||
|
||||
(digit >= 'A' && digit <= 'F'));
|
||||
}
|
||||
|
||||
HexColorEntry::HexColorEntry()
|
||||
: Box(HORIZONTAL)
|
||||
, m_label("#")
|
||||
@ -56,7 +50,7 @@ void HexColorEntry::onEntryChange()
|
||||
int r, g, b;
|
||||
|
||||
// Remove non hex digits
|
||||
while (text.size() > 0 && !is_hex_digit(text[0]))
|
||||
while (text.size() > 0 && !base::is_hex_digit(text[0]))
|
||||
text.erase(0, 1);
|
||||
|
||||
// Fill with zeros at the end of the text
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/notification_delegate.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
@ -35,6 +36,7 @@
|
||||
#include "app/ui/workspace_tabs.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/path.h"
|
||||
#include "she/display.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/splitter.h"
|
||||
#include "ui/system.h"
|
||||
@ -44,10 +46,51 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
class ScreenScalePanic : public INotificationDelegate {
|
||||
public:
|
||||
std::string notificationText() override {
|
||||
return "Reset Scale!";
|
||||
}
|
||||
|
||||
void notificationClick() override {
|
||||
auto& pref = Preferences::instance();
|
||||
|
||||
const int newScreenScale = 2;
|
||||
const int newUIScale = 1;
|
||||
bool needsRestart = false;
|
||||
|
||||
if (pref.general.screenScale() != newScreenScale)
|
||||
pref.general.screenScale(newScreenScale);
|
||||
|
||||
if (pref.general.uiScale() != newUIScale) {
|
||||
pref.general.uiScale(newUIScale);
|
||||
needsRestart = true;
|
||||
}
|
||||
|
||||
pref.save();
|
||||
|
||||
// If the UI scale is greater than 100%, we would like to avoid
|
||||
// setting the Screen Scale to 200% right now to avoid a worse
|
||||
// effect to the user. E.g. If the UI Scale is 400% and Screen
|
||||
// Scale is 100%, and the user choose to reset the scale, we
|
||||
// cannot change the Screen Scale to 200% (we're going to
|
||||
// increase the problem), so we change the Screen Scale to 100%
|
||||
// just to show the "restart" message.
|
||||
Manager* manager = Manager::getDefault();
|
||||
she::Display* display = manager->getDisplay();
|
||||
display->setScale(ui::guiscale() > newUIScale ? 1: newScreenScale);
|
||||
manager->setDisplay(display);
|
||||
|
||||
if (needsRestart)
|
||||
Alert::show("Aseprite<<Restart the program.||&OK");
|
||||
}
|
||||
};
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: m_mode(NormalMode)
|
||||
, m_homeView(nullptr)
|
||||
, m_devConsoleView(nullptr)
|
||||
, m_scalePanic(nullptr)
|
||||
{
|
||||
// Load all menus by first time.
|
||||
AppMenus::instance()->reload();
|
||||
@ -104,6 +147,8 @@ MainWindow::MainWindow()
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete m_scalePanic;
|
||||
|
||||
if (m_devConsoleView) {
|
||||
if (m_devConsoleView->parent())
|
||||
m_workspace->removeView(m_devConsoleView);
|
||||
@ -251,6 +296,20 @@ void MainWindow::onSaveLayout(SaveLayoutEvent& ev)
|
||||
Window::onSaveLayout(ev);
|
||||
}
|
||||
|
||||
void MainWindow::onResize(ui::ResizeEvent& ev)
|
||||
{
|
||||
app::gen::MainWindow::onResize(ev);
|
||||
|
||||
she::Display* display = manager()->getDisplay();
|
||||
if ((display) &&
|
||||
(display->scale()*ui::guiscale() > 2) &&
|
||||
(!m_scalePanic) &&
|
||||
(ui::display_w()/ui::guiscale() < 320 ||
|
||||
ui::display_h()/ui::guiscale() < 260)) {
|
||||
showNotification(m_scalePanic = new ScreenScalePanic);
|
||||
}
|
||||
}
|
||||
|
||||
// When the active view is changed from methods like
|
||||
// Workspace::splitView(), this function is called, and we have to
|
||||
// inform to the UIContext that the current view has changed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -95,6 +95,7 @@ namespace app {
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onSaveLayout(ui::SaveLayoutEvent& ev) override;
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onActiveViewChange();
|
||||
|
||||
private:
|
||||
@ -115,6 +116,7 @@ namespace app {
|
||||
HomeView* m_homeView;
|
||||
DevConsoleView* m_devConsoleView;
|
||||
Notifications* m_notifications;
|
||||
INotificationDelegate* m_scalePanic;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -40,6 +40,19 @@ PopupWindowPin::PopupWindowPin(const std::string& text, ClickBehavior clickBehav
|
||||
CENTER | MIDDLE));
|
||||
}
|
||||
|
||||
void PopupWindowPin::showPin(bool state)
|
||||
{
|
||||
m_pin.setVisible(state);
|
||||
}
|
||||
|
||||
void PopupWindowPin::setPinned(bool pinned)
|
||||
{
|
||||
m_pin.setSelected(pinned);
|
||||
|
||||
Event ev(this);
|
||||
onPinClick(ev);
|
||||
}
|
||||
|
||||
void PopupWindowPin::onPinClick(Event& ev)
|
||||
{
|
||||
if (m_pin.isSelected()) {
|
||||
@ -57,33 +70,25 @@ bool PopupWindowPin::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
|
||||
case kOpenMessage:
|
||||
m_pin.setSelected(false);
|
||||
makeFixed();
|
||||
break;
|
||||
|
||||
case kCloseMessage:
|
||||
m_pin.setSelected(false);
|
||||
case kOpenMessage: {
|
||||
if (!isPinned())
|
||||
makeFixed();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return PopupWindow::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
void PopupWindowPin::onHitTest(HitTestEvent& ev)
|
||||
void PopupWindowPin::onWindowMovement()
|
||||
{
|
||||
PopupWindow::onHitTest(ev);
|
||||
PopupWindow::onWindowMovement();
|
||||
|
||||
if ((m_pin.isSelected()) &&
|
||||
(ev.hit() == HitTestClient)) {
|
||||
if (ev.point().x <= bounds().x+2)
|
||||
ev.setHit(HitTestBorderW);
|
||||
else if (ev.point().x >= bounds().x2()-3)
|
||||
ev.setHit(HitTestBorderE);
|
||||
else
|
||||
ev.setHit(HitTestCaption);
|
||||
}
|
||||
// If the window isn't pinned and we move it, we can automatically
|
||||
// pin it.
|
||||
if (!m_pin.isSelected())
|
||||
setPinned(true);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -17,9 +17,13 @@ namespace app {
|
||||
public:
|
||||
PopupWindowPin(const std::string& text, ClickBehavior clickBehavior);
|
||||
|
||||
void showPin(bool state);
|
||||
bool isPinned() const { return m_pin.isSelected(); }
|
||||
void setPinned(bool pinned);
|
||||
|
||||
protected:
|
||||
virtual bool onProcessMessage(ui::Message* msg) override;
|
||||
virtual void onHitTest(ui::HitTestEvent& ev) override;
|
||||
virtual void onWindowMovement() override;
|
||||
|
||||
// The pin. Your derived class must add this pin in some place of
|
||||
// the frame as a children, and you must to remove the pin from the
|
||||
|
@ -1315,21 +1315,22 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
||||
g->fillRect(BGCOLOR, rc);
|
||||
|
||||
// Draw thumb
|
||||
g->drawRgbaSurface(thumb, x-thumb->width()/2, rc.y);
|
||||
int thumb_y = rc.y;
|
||||
if (rc.h > thumb->height()*3)
|
||||
rc.shrink(Border(0, thumb->height(), 0, 0));
|
||||
|
||||
// Draw borders
|
||||
rc.shrink(Border(
|
||||
3 * guiscale(),
|
||||
thumb->height(),
|
||||
3 * guiscale(),
|
||||
1 * guiscale()));
|
||||
|
||||
drawRect(g, rc, nw.get(), gfx::ColorNone);
|
||||
if (rc.h > 4*guiscale()) {
|
||||
rc.shrink(Border(3, 0, 3, 1) * guiscale());
|
||||
drawRect(g, rc, nw.get(), gfx::ColorNone);
|
||||
}
|
||||
|
||||
// Draw background (using the customized ISliderBgPainter implementation)
|
||||
rc.shrink(Border(1, 1, 1, 2) * guiscale());
|
||||
if (!rc.isEmpty())
|
||||
bgPainter->paint(widget, g, rc);
|
||||
|
||||
g->drawRgbaSurface(thumb, x-thumb->width()/2, thumb_y);
|
||||
}
|
||||
else {
|
||||
// Draw borders
|
||||
|
@ -420,7 +420,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
|
||||
}
|
||||
else if (elem_name == "colorpicker") {
|
||||
if (!widget)
|
||||
widget = new ColorButton(Color::fromMask(), app_get_current_pixel_format());
|
||||
widget = new ColorButton(Color::fromMask(), app_get_current_pixel_format(), false);
|
||||
}
|
||||
else if (elem_name == "dropdownbutton") {
|
||||
if (!widget) {
|
||||
|
21
src/base/hex.h
Normal file
21
src/base/hex.h
Normal file
@ -0,0 +1,21 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef BASE_HEX_H_INCLUDED
|
||||
#define BASE_HEX_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
namespace base {
|
||||
|
||||
inline bool is_hex_digit(int digit) {
|
||||
return ((digit >= '0' && digit <= '9') ||
|
||||
(digit >= 'a' && digit <= 'f') ||
|
||||
(digit >= 'A' && digit <= 'F'));
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif
|
@ -32,6 +32,7 @@ add_library(doc-lib
|
||||
documents.cpp
|
||||
file/col_file.cpp
|
||||
file/gpl_file.cpp
|
||||
file/hex_file.cpp
|
||||
file/pal_file.cpp
|
||||
frame_tag.cpp
|
||||
frame_tag_io.cpp
|
||||
|
87
src/doc/file/hex_file.cpp
Normal file
87
src/doc/file/hex_file.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base/fstream_path.h"
|
||||
#include "base/hex.h"
|
||||
#include "base/trim_string.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/palette.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace doc {
|
||||
namespace file {
|
||||
|
||||
Palette* load_hex_file(const char *filename)
|
||||
{
|
||||
std::ifstream f(FSTREAM_PATH(filename));
|
||||
if (f.bad())
|
||||
return nullptr;
|
||||
|
||||
base::UniquePtr<Palette> pal(new Palette(frame_t(0), 0));
|
||||
|
||||
// Read line by line, each line one color, ignore everything that
|
||||
// doesn't look like a hex color.
|
||||
std::string line;
|
||||
while (std::getline(f, line)) {
|
||||
// Trim line
|
||||
base::trim_string(line, line);
|
||||
|
||||
// Remove comments
|
||||
if (line.empty())
|
||||
continue;
|
||||
|
||||
// Find 6 consecutive hex digits
|
||||
for (int i=0; i<line.size(); ++i) {
|
||||
int j = i;
|
||||
for (; j<i+6; ++j) {
|
||||
if (!base::is_hex_digit(line[j]))
|
||||
break;
|
||||
}
|
||||
if (j-i != 6)
|
||||
continue;
|
||||
|
||||
// Convert text (Base 16) to integer
|
||||
int hex = std::strtol(line.substr(i, 6).c_str(), nullptr, 16);
|
||||
int r = (hex & 0xff0000) >> 16;
|
||||
int g = (hex & 0xff00) >> 8;
|
||||
int b = (hex & 0xff);
|
||||
pal->addEntry(rgba(r, g, b, 255));
|
||||
|
||||
// Done, one color per line
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pal.release();
|
||||
}
|
||||
|
||||
bool save_hex_file(const Palette *pal, const char *filename)
|
||||
{
|
||||
std::ofstream f(FSTREAM_PATH(filename));
|
||||
if (f.bad()) return false;
|
||||
|
||||
f << std::hex << std::setfill('0');
|
||||
for (int i=0; i<pal->size(); ++i) {
|
||||
uint32_t col = pal->getEntry(i);
|
||||
f << std::setw(2) << ((int)rgba_getr(col))
|
||||
<< std::setw(2) << ((int)rgba_getg(col))
|
||||
<< std::setw(2) << ((int)rgba_getb(col)) << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace file
|
||||
} // namespace doc
|
23
src/doc/file/hex_file.h
Normal file
23
src/doc/file/hex_file.h
Normal file
@ -0,0 +1,23 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef DOC_FILE_HEX_FILE_H_INCLUDED
|
||||
#define DOC_FILE_HEX_FILE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
namespace doc {
|
||||
|
||||
class Palette;
|
||||
|
||||
namespace file {
|
||||
|
||||
Palette* load_hex_file(const char* filename);
|
||||
bool save_hex_file(const Palette* pal, const char* filename);
|
||||
|
||||
} // namespace file
|
||||
} // namespace doc
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2001-2014 David Capello
|
||||
Copyright (c) 2001-2016 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Gfx Library
|
||||
// Copyright (C) 2001-2014 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -13,8 +13,7 @@
|
||||
|
||||
namespace gfx {
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Rect& rect)
|
||||
{
|
||||
inline std::ostream& operator<<(std::ostream& os, const Rect& rect) {
|
||||
return os << "("
|
||||
<< rect.x << ", "
|
||||
<< rect.y << ", "
|
||||
@ -22,6 +21,22 @@ namespace gfx {
|
||||
<< rect.h << ")";
|
||||
}
|
||||
|
||||
inline std::istream& operator>>(std::istream& in, Rect& rect) {
|
||||
while (in && in.get() != '(')
|
||||
;
|
||||
|
||||
if (!in)
|
||||
return in;
|
||||
|
||||
char chr;
|
||||
in >> rect.x >> chr
|
||||
>> rect.y >> chr
|
||||
>> rect.w >> chr
|
||||
>> rect.h >> chr;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Gfx Library
|
||||
// Copyright (C) 2001-2013 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -10,24 +10,13 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "gfx/region.h"
|
||||
#include "gfx/point.h"
|
||||
#include "gfx/rect_io.h"
|
||||
#include "gfx/region.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gfx;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
ostream& operator<<(ostream& os, const Rect& rect) {
|
||||
return os << "("
|
||||
<< rect.x << ", "
|
||||
<< rect.y << ", "
|
||||
<< rect.w << ", "
|
||||
<< rect.h << ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& os, const Region& rgn)
|
||||
{
|
||||
os << "{";
|
||||
|
@ -406,9 +406,19 @@ bool is_key_pressed(KeyScancode scancode)
|
||||
ev.setPreciseWheel(true);
|
||||
}
|
||||
else {
|
||||
// Ignore the acceleration factor, just use the wheel sign.
|
||||
gfx::Point pt(0, 0);
|
||||
if (event.scrollingDeltaX >= 0.1)
|
||||
pt.x = -1;
|
||||
else if (event.scrollingDeltaX <= -0.1)
|
||||
pt.x = 1;
|
||||
if (event.scrollingDeltaY >= 0.1)
|
||||
pt.y = -1;
|
||||
else if (event.scrollingDeltaY <= -0.1)
|
||||
pt.y = 1;
|
||||
|
||||
ev.setPointerType(she::PointerType::Mouse);
|
||||
ev.setWheelDelta(gfx::Point(-event.scrollingDeltaX,
|
||||
-event.scrollingDeltaY));
|
||||
ev.setWheelDelta(pt);
|
||||
}
|
||||
|
||||
queue_event(ev);
|
||||
|
@ -300,7 +300,8 @@ private:
|
||||
{
|
||||
NSGraphicsContext* gc = [NSGraphicsContext currentContext];
|
||||
CGContextRef cg = (CGContextRef)[gc graphicsPort];
|
||||
CGImageRef img = SkCreateCGImageRef(bitmap);
|
||||
CGColorSpaceRef colorSpace = CGDisplayCopyColorSpace(CGMainDisplayID());
|
||||
CGImageRef img = SkCreateCGImageRefWithColorspace(bitmap, colorSpace);
|
||||
if (img) {
|
||||
CGRect r = CGRectMake(viewBounds.origin.x+rect.x,
|
||||
viewBounds.origin.y+rect.y,
|
||||
@ -312,6 +313,7 @@ private:
|
||||
CGContextRestoreGState(cg);
|
||||
CGImageRelease(img);
|
||||
}
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
}
|
||||
bitmap.unlockPixels();
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2001-2015 David Capello
|
||||
Copyright (c) 2001-2016 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Aseprite UI Library
|
||||
*Copyright (C) 2001-2014 David Capello*
|
||||
*Copyright (C) 2001-2016 David Capello*
|
||||
|
||||
> Distributed under [MIT license](LICENSE.txt)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -79,13 +79,13 @@ void Box::onSizeHint(SizeHintEvent& ev)
|
||||
|
||||
void Box::onResize(ResizeEvent& ev)
|
||||
{
|
||||
#define LAYOUT_CHILDREN(x, w) { \
|
||||
#define LAYOUT_CHILDREN(x, y, w, h) { \
|
||||
availExtraSize = availSize.w - prefSize.w; \
|
||||
availSize.w -= childSpacing() * (visibleChildren-1); \
|
||||
if (align() & HOMOGENEOUS) \
|
||||
homogeneousSize = availSize.w / visibleChildren; \
|
||||
\
|
||||
Rect childPos(childrenBounds()); \
|
||||
Rect defChildPos(childrenBounds()); \
|
||||
int i = 0, j = 0; \
|
||||
for (auto child : children()) { \
|
||||
if (child->hasFlags(HIDDEN)) \
|
||||
@ -111,9 +111,12 @@ void Box::onResize(ResizeEvent& ev)
|
||||
} \
|
||||
} \
|
||||
\
|
||||
childPos.w = MAX(1, size); \
|
||||
Rect childPos = defChildPos; \
|
||||
childPos.w = size = MID(child->minSize().w, size, child->maxSize().w); \
|
||||
childPos.h = MID(child->minSize().h, childPos.h, child->maxSize().h); \
|
||||
child->setBounds(childPos); \
|
||||
childPos.x += size + childSpacing(); \
|
||||
\
|
||||
defChildPos.x += size + childSpacing(); \
|
||||
availSize.w -= size; \
|
||||
++i; \
|
||||
} \
|
||||
@ -141,10 +144,10 @@ void Box::onResize(ResizeEvent& ev)
|
||||
prefSize.h -= border().height();
|
||||
|
||||
if (align() & HORIZONTAL) {
|
||||
LAYOUT_CHILDREN(x, w);
|
||||
LAYOUT_CHILDREN(x, y, w, h);
|
||||
}
|
||||
else {
|
||||
LAYOUT_CHILDREN(y, h);
|
||||
LAYOUT_CHILDREN(y, x, h, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -370,9 +370,11 @@ void RadioButton::deselectRadioGroup()
|
||||
}
|
||||
}
|
||||
|
||||
void RadioButton::onSelect()
|
||||
void RadioButton::onSelect(bool selected)
|
||||
{
|
||||
ButtonBase::onSelect();
|
||||
ButtonBase::onSelect(selected);
|
||||
if (!selected)
|
||||
return;
|
||||
|
||||
if (!m_handleSelect)
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -98,7 +98,7 @@ namespace ui {
|
||||
void deselectRadioGroup();
|
||||
|
||||
protected:
|
||||
void onSelect() override;
|
||||
void onSelect(bool selected) override;
|
||||
|
||||
private:
|
||||
int m_radioGroup;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -191,20 +191,17 @@ void Grid::onResize(ResizeEvent& ev)
|
||||
|
||||
void Grid::onSizeHint(SizeHintEvent& ev)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
w = h = 0;
|
||||
|
||||
calculateSize();
|
||||
|
||||
// Calculate the total
|
||||
sumStripSize(m_colstrip, w);
|
||||
sumStripSize(m_rowstrip, h);
|
||||
gfx::Size sz(0, 0);
|
||||
sumStripSize(m_colstrip, sz.w);
|
||||
sumStripSize(m_rowstrip, sz.h);
|
||||
|
||||
w += border().width();
|
||||
h += border().height();
|
||||
sz.w += border().width();
|
||||
sz.h += border().height();
|
||||
|
||||
ev.setSizeHint(Size(w, h));
|
||||
ev.setSizeHint(sz);
|
||||
}
|
||||
|
||||
void Grid::onPaint(PaintEvent& ev)
|
||||
@ -374,7 +371,6 @@ void Grid::expandStrip(std::vector<Strip>& colstrip,
|
||||
else
|
||||
size = cell->h; // Transposed
|
||||
}
|
||||
|
||||
(this->*incCol)(i, size);
|
||||
}
|
||||
}
|
||||
@ -423,38 +419,40 @@ void Grid::distributeStripSize(std::vector<Strip>& colstrip,
|
||||
}
|
||||
total_req += border_size;
|
||||
|
||||
if (wantmore_count > 0) {
|
||||
int extra_total = rect_size - total_req;
|
||||
if (extra_total > 0) {
|
||||
// If a expandable column-strip was empty (size=0) then we have
|
||||
// to reduce the extra_total size because a new child-spacing is
|
||||
// added by this column
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if ((colstrip[i].size == 0) &&
|
||||
(colstrip[i].expand_count == max_expand_count || same_width)) {
|
||||
extra_total -= this->childSpacing();
|
||||
}
|
||||
int extra_total = (rect_size - total_req);
|
||||
|
||||
// Expand or reduce "expandable" strip
|
||||
if ((wantmore_count > 0) &&
|
||||
((extra_total > 0 && (max_expand_count > 0 || same_width)) ||
|
||||
(extra_total < 0))) {
|
||||
// If a expandable column-strip was empty (size=0) then we have
|
||||
// to reduce the extra_total size because a new child-spacing is
|
||||
// added by this column
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if ((colstrip[i].size == 0) &&
|
||||
(colstrip[i].expand_count == max_expand_count || same_width)) {
|
||||
extra_total -= SGN(extra_total)*this->childSpacing();
|
||||
}
|
||||
|
||||
int extra_foreach = extra_total / wantmore_count;
|
||||
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if (colstrip[i].expand_count == max_expand_count || same_width) {
|
||||
ASSERT(wantmore_count > 0);
|
||||
|
||||
colstrip[i].size += extra_foreach;
|
||||
extra_total -= extra_foreach;
|
||||
|
||||
if (--wantmore_count == 0) {
|
||||
colstrip[i].size += extra_total;
|
||||
extra_total = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(wantmore_count == 0);
|
||||
ASSERT(extra_total == 0);
|
||||
}
|
||||
|
||||
int extra_foreach = extra_total / wantmore_count;
|
||||
|
||||
for (i=0; i<(int)colstrip.size(); ++i) {
|
||||
if (colstrip[i].expand_count == max_expand_count || same_width) {
|
||||
ASSERT(wantmore_count > 0);
|
||||
|
||||
colstrip[i].size += extra_foreach;
|
||||
extra_total -= extra_foreach;
|
||||
|
||||
if (--wantmore_count == 0) {
|
||||
colstrip[i].size += extra_total;
|
||||
extra_total = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(wantmore_count == 0);
|
||||
ASSERT(extra_total == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#define TEST_GUI
|
||||
#include "tests/test.h"
|
||||
#include "gfx/rect_io.h"
|
||||
#include "gfx/size.h"
|
||||
|
||||
using namespace gfx;
|
||||
@ -144,7 +145,7 @@ TEST(Grid, SameWidth2x1Grid)
|
||||
// | | |
|
||||
// +----------------------------+---+
|
||||
//
|
||||
TEST(Grid, Intrincate3x3Grid)
|
||||
TEST(Grid, Intrincate2x2Grid)
|
||||
{
|
||||
Grid* grid = new Grid(3, false);
|
||||
Widget* w1 = new Widget;
|
||||
@ -226,3 +227,82 @@ TEST(Grid, FourColumns)
|
||||
EXPECT_EQ(gfx::Rect(30, 0, 10, 10), d.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 10, 40, 10), e.bounds());
|
||||
}
|
||||
|
||||
TEST(Grid, OneFixedReduceThree)
|
||||
{
|
||||
Grid grid(1, false);
|
||||
grid.noBorderNoChildSpacing();
|
||||
|
||||
Widget a;
|
||||
Widget b;
|
||||
Widget c;
|
||||
Widget d;
|
||||
a.setMinSize(gfx::Size(10, 10));
|
||||
b.setMinSize(gfx::Size(10, 10));
|
||||
c.setMinSize(gfx::Size(10, 10));
|
||||
d.setMinSize(gfx::Size(10, 10));
|
||||
|
||||
grid.addChildInCell(&a, 1, 1, HORIZONTAL);
|
||||
grid.addChildInCell(&b, 1, 1, HORIZONTAL | VERTICAL);
|
||||
grid.addChildInCell(&c, 1, 1, HORIZONTAL | VERTICAL);
|
||||
grid.addChildInCell(&d, 1, 1, HORIZONTAL | VERTICAL);
|
||||
|
||||
// Test request size
|
||||
grid.setChildSpacing(0);
|
||||
EXPECT_EQ(gfx::Size(10, 40), grid.sizeHint());
|
||||
|
||||
// Test bigger layout
|
||||
grid.setBounds(gfx::Rect(0, 0, 10, 100));
|
||||
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), a.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 10, 10, 30), b.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 40, 10, 30), c.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 70, 10, 30), d.bounds());
|
||||
|
||||
// Test perfect layout
|
||||
grid.setBounds(gfx::Rect(0, 0, 10, 40));
|
||||
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), a.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 10, 10, 10), b.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 20, 10, 10), c.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 30, 10, 10), d.bounds());
|
||||
|
||||
// Test reduced layout
|
||||
grid.setBounds(gfx::Rect(0, 0, 10, 16));
|
||||
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), a.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 10, 10, 2), b.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 12, 10, 2), c.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 14, 10, 2), d.bounds());
|
||||
}
|
||||
|
||||
TEST(Grid, ReduceThree)
|
||||
{
|
||||
Grid grid(1, false);
|
||||
grid.noBorderNoChildSpacing();
|
||||
|
||||
Widget a;
|
||||
Widget b;
|
||||
Widget c;
|
||||
a.setMinSize(gfx::Size(10, 10));
|
||||
b.setMinSize(gfx::Size(10, 10));
|
||||
c.setMinSize(gfx::Size(10, 10));
|
||||
|
||||
grid.addChildInCell(&a, 1, 1, HORIZONTAL);
|
||||
grid.addChildInCell(&b, 1, 1, HORIZONTAL);
|
||||
grid.addChildInCell(&c, 1, 1, HORIZONTAL);
|
||||
|
||||
// Test request size
|
||||
grid.setChildSpacing(0);
|
||||
EXPECT_EQ(gfx::Size(10, 30), grid.sizeHint());
|
||||
|
||||
// Test bigger layout (as these widgets aren't expandible, they
|
||||
// should have height=10)
|
||||
grid.setBounds(gfx::Rect(0, 0, 10, 90));
|
||||
EXPECT_EQ(gfx::Rect(0, 0, 10, 10), a.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 10, 10, 10), b.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 20, 10, 10), c.bounds());
|
||||
|
||||
// Test reduced layout
|
||||
grid.setBounds(gfx::Rect(0, 0, 10, 12));
|
||||
EXPECT_EQ(gfx::Rect(0, 0, 10, 4), a.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 4, 10, 4), b.bounds());
|
||||
EXPECT_EQ(gfx::Rect(0, 8, 10, 4), c.bounds());
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -26,6 +26,7 @@ PopupWindow::PopupWindow(const std::string& text,
|
||||
, m_clickBehavior(clickBehavior)
|
||||
, m_enterBehavior(enterBehavior)
|
||||
, m_filtering(false)
|
||||
, m_fixed(false)
|
||||
{
|
||||
setSizeable(false);
|
||||
setMoveable(false);
|
||||
@ -64,12 +65,18 @@ void PopupWindow::makeFloating()
|
||||
{
|
||||
stopFilteringMessages();
|
||||
setMoveable(true);
|
||||
m_fixed = false;
|
||||
|
||||
onMakeFloating();
|
||||
}
|
||||
|
||||
void PopupWindow::makeFixed()
|
||||
{
|
||||
startFilteringMessages();
|
||||
setMoveable(false);
|
||||
m_fixed = true;
|
||||
|
||||
onMakeFixed();
|
||||
}
|
||||
|
||||
bool PopupWindow::onProcessMessage(Message* msg)
|
||||
@ -91,7 +98,7 @@ bool PopupWindow::onProcessMessage(Message* msg)
|
||||
break;
|
||||
|
||||
case kMouseLeaveMessage:
|
||||
if (m_hotRegion.isEmpty() && !isMoveable())
|
||||
if (m_hotRegion.isEmpty() && m_fixed)
|
||||
closeWindow(nullptr);
|
||||
break;
|
||||
|
||||
@ -139,7 +146,7 @@ bool PopupWindow::onProcessMessage(Message* msg)
|
||||
break;
|
||||
|
||||
case kMouseMoveMessage:
|
||||
if (!isMoveable() &&
|
||||
if (m_fixed &&
|
||||
!m_hotRegion.isEmpty() &&
|
||||
manager()->getCapture() == NULL) {
|
||||
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
||||
@ -202,19 +209,34 @@ void PopupWindow::onInitTheme(InitThemeEvent& ev)
|
||||
|
||||
void PopupWindow::onHitTest(HitTestEvent& ev)
|
||||
{
|
||||
Window::onHitTest(ev);
|
||||
|
||||
Widget* picked = manager()->pick(ev.point());
|
||||
if (picked) {
|
||||
WidgetType type = picked->type();
|
||||
if ((type == kWindowWidget && picked == this) ||
|
||||
type == kBoxWidget ||
|
||||
type == kLabelWidget ||
|
||||
type == kGridWidget ||
|
||||
type == kSeparatorWidget) {
|
||||
ev.setHit(HitTestCaption);
|
||||
return;
|
||||
if (type == kWindowWidget && picked == this) {
|
||||
if (isSizeable() && (ev.hit() == HitTestBorderNW ||
|
||||
ev.hit() == HitTestBorderN ||
|
||||
ev.hit() == HitTestBorderNE ||
|
||||
ev.hit() == HitTestBorderE ||
|
||||
ev.hit() == HitTestBorderSE ||
|
||||
ev.hit() == HitTestBorderS ||
|
||||
ev.hit() == HitTestBorderSW ||
|
||||
ev.hit() == HitTestBorderW)) {
|
||||
// Use the hit value from Window::onHitTest()
|
||||
return;
|
||||
}
|
||||
else {
|
||||
ev.setHit(isMoveable() ? HitTestCaption: HitTestClient);
|
||||
}
|
||||
}
|
||||
else if (type == kBoxWidget ||
|
||||
type == kLabelWidget ||
|
||||
type == kGridWidget ||
|
||||
type == kSeparatorWidget) {
|
||||
ev.setHit(isMoveable() ? HitTestCaption: HitTestClient);
|
||||
}
|
||||
}
|
||||
Window::onHitTest(ev);
|
||||
}
|
||||
|
||||
void PopupWindow::startFilteringMessages()
|
||||
@ -241,4 +263,14 @@ void PopupWindow::stopFilteringMessages()
|
||||
}
|
||||
}
|
||||
|
||||
void PopupWindow::onMakeFloating()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void PopupWindow::onMakeFixed()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -46,6 +46,9 @@ namespace ui {
|
||||
void onInitTheme(InitThemeEvent& ev) override;
|
||||
void onHitTest(HitTestEvent& ev) override;
|
||||
|
||||
virtual void onMakeFloating();
|
||||
virtual void onMakeFixed();
|
||||
|
||||
private:
|
||||
void startFilteringMessages();
|
||||
void stopFilteringMessages();
|
||||
@ -54,6 +57,7 @@ namespace ui {
|
||||
EnterBehavior m_enterBehavior;
|
||||
gfx::Region m_hotRegion;
|
||||
bool m_filtering;
|
||||
bool m_fixed;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
@ -211,7 +211,7 @@ void Widget::setEnabled(bool state)
|
||||
disableFlags(DISABLED);
|
||||
invalidate();
|
||||
|
||||
onEnable();
|
||||
onEnable(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -221,7 +221,7 @@ void Widget::setEnabled(bool state)
|
||||
enableFlags(DISABLED);
|
||||
invalidate();
|
||||
|
||||
onDisable();
|
||||
onEnable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -233,7 +233,7 @@ void Widget::setSelected(bool state)
|
||||
enableFlags(SELECTED);
|
||||
invalidate();
|
||||
|
||||
onSelect();
|
||||
onSelect(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -241,7 +241,7 @@ void Widget::setSelected(bool state)
|
||||
disableFlags(SELECTED);
|
||||
invalidate();
|
||||
|
||||
onDeselect();
|
||||
onSelect(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1436,22 +1436,12 @@ void Widget::onSetDecorativeWidgetBounds()
|
||||
}
|
||||
}
|
||||
|
||||
void Widget::onEnable()
|
||||
void Widget::onEnable(bool enabled)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Widget::onDisable()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Widget::onSelect()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Widget::onDeselect()
|
||||
void Widget::onSelect(bool selected)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
@ -368,10 +368,8 @@ namespace ui {
|
||||
virtual void onBroadcastMouseMessage(WidgetsList& targets);
|
||||
virtual void onInitTheme(InitThemeEvent& ev);
|
||||
virtual void onSetDecorativeWidgetBounds();
|
||||
virtual void onEnable();
|
||||
virtual void onDisable();
|
||||
virtual void onSelect();
|
||||
virtual void onDeselect();
|
||||
virtual void onEnable(bool enabled);
|
||||
virtual void onSelect(bool selected);
|
||||
virtual void onSetText();
|
||||
virtual void onSetBgColor();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -182,6 +182,11 @@ void Window::onWindowResize()
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Window::onWindowMovement()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Window::remapWindow()
|
||||
{
|
||||
if (m_isAutoRemap) {
|
||||
@ -579,6 +584,8 @@ void Window::moveWindow(const gfx::Rect& rect, bool use_blit)
|
||||
}
|
||||
|
||||
manager->invalidateDisplayRegion(invalidManagerRegion);
|
||||
|
||||
onWindowMovement();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2001-2013, 2015 David Capello
|
||||
// Copyright (C) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -46,6 +46,7 @@ namespace ui {
|
||||
bool isDesktop() const { return m_isDesktop; }
|
||||
bool isOnTop() const { return m_isOnTop; }
|
||||
bool isWantFocus() const { return m_isWantFocus; }
|
||||
bool isSizeable() const { return m_isSizeable; }
|
||||
bool isMoveable() const { return m_isMoveable; }
|
||||
|
||||
HitTest hitTest(const gfx::Point& point);
|
||||
@ -67,6 +68,7 @@ namespace ui {
|
||||
virtual void onClose(CloseEvent& ev);
|
||||
virtual void onHitTest(HitTestEvent& ev);
|
||||
virtual void onWindowResize();
|
||||
virtual void onWindowMovement();
|
||||
|
||||
private:
|
||||
void windowSetPosition(const gfx::Rect& rect);
|
||||
|
Loading…
x
Reference in New Issue
Block a user