Merge branch 'next' into dev

This commit is contained in:
David Capello 2014-07-11 01:15:30 -03:00
commit 958d8f922f
169 changed files with 3750 additions and 3435 deletions

View File

@ -80,7 +80,6 @@ Aseprite uses libraries or parts of the original source code
of the following projects created by third-parties:
* [Allegro 4](http://alleg.sourceforge.net/) - [allegro4 license](https://github.com/dacap/aseprite/tree/master/docs/licenses/allegro4-LICENSE.txt)
* [AllegroFont](http://chernsha.sitesled.com/) - [FTL license](https://github.com/dacap/aseprite/tree/master/docs/licenses/FTL.txt)
* [curl](http://curl.haxx.se/) - [curl license](https://github.com/dacap/aseprite/tree/master/docs/licenses/curl-LICENSE.txt)
* [FreeType](http://www.freetype.org/) - [FTL license](https://github.com/dacap/aseprite/tree/master/docs/licenses/FTL.txt)
* [giflib](http://sourceforge.net/projects/giflib/) - [giflib license](https://github.com/dacap/aseprite/tree/master/docs/licenses/giflib-LICENSE.txt)

View File

@ -166,6 +166,7 @@
<key tool="hand" shortcut="H" />
<key tool="move" shortcut="V" />
<key tool="zoom" shortcut="Z" />
<!-- key tool="slice" shortcut="K" /-->
<key tool="paint_bucket" shortcut="G" />
@ -600,6 +601,15 @@
ink="move"
controller="freehand"
/>
<!-- tool id="slice"
text="Slice Tool"
fill="always"
ink="slice"
controller="two_points"
pointshape="pixel"
intertwine="as_rectangles"
tracepolicy="last"
/-->
</group>
<group id="paint_bucket" text="Paint Bucket Tool">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -125,6 +125,7 @@
<tool id="hand" x="176" y="32" w="16" h="16" />
<tool id="move" x="192" y="32" w="16" h="16" />
<tool id="zoom" x="208" y="32" w="16" h="16" />
<tool id="slice" x="224" y="32" w="16" h="16" />
<tool id="paint_bucket" x="144" y="48" w="16" h="16" />
@ -201,6 +202,8 @@
<part id="combobox_arrow_right" x="99" y="196" w="9" h="9" />
<part id="combobox_arrow_right_selected" x="115" y="196" w="9" h="9" />
<part id="combobox_arrow_right_disabled" x="131" y="196" w="9" h="9" />
<part id="newfolder" x="99" y="211" w="9" h="9" />
<part id="newfolder_selected" x="115" y="211" w="9" h="9" />
<part id="toolbutton_normal" x="96" y="0" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
<part id="toolbutton_hot" x="112" y="0" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
<part id="toolbutton_last" x="96" y="16" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
@ -328,6 +331,12 @@
<part id="drop_pixels_cancel" x="192" y="176" w="7" h="8" />
<part id="drop_pixels_cancel_selected" x="192" y="184" w="7" h="8" />
<part id="warning_box" x="112" y="80" w="9" h="10" />
<part id="freehand_algo_default" x="144" y="208" w="8" h="8" />
<part id="freehand_algo_default_selected" x="152" y="208" w="8" h="8" />
<part id="freehand_algo_pixel_perfect" x="160" y="208" w="8" h="8" />
<part id="freehand_algo_pixel_perfect_selected" x="168" y="208" w="8" h="8" />
<part id="freehand_algo_dots" x="176" y="208" w="8" h="8" />
<part id="freehand_algo_dots_selected" x="184" y="208" w="8" h="8" />
</parts>
<stylesheet>

View File

@ -8,6 +8,7 @@
<button text="" id="goforward" bevel="0 2 0 2" tooltip="Go forward one folder" />
</box>
<button text="" id="goup" tooltip="Up to parent folder&#10;(Backspace)" />
<button text="" id="newfolder" tooltip="New folder" />
<combobox id="location" expansive="true" />
</box>
<view id="fileview_container" expansive="true"></view>
@ -24,4 +25,20 @@
</box>
</box>
</box>
<window text="New Folder" id="newfolder_dialog">
<vbox>
<hbox>
<label text="Folder Name:" />
<entry text="New Folder" id="name" maxsize="256" magnet="true" expansive="true" />
</hbox>
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" id="cancel" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,82 +1,88 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2014 by David Capello -->
<gui>
<window text="Options" id="options">
<box vertical="true">
<box horizontal="true">
<box vertical="true">
<vbox id="main_box">
<hbox>
<view maxsize="true">
<listbox id="section_listbox">
<listitem text="General" value="section_general" />
<listitem text="Editor" value="section_editor" />
<listitem text="Grid &amp;&amp; Background" value="section_grid" />
<listitem text="Undo" value="section_undo" />
</listbox>
</view>
<!-- Screen -->
<panel id="panel">
<vbox id="section_general">
<separator text="General" horizontal="true" />
<grid columns="2">
<label text="Screen Scale:" />
<combobox id="screen_scale" expansive="true" />
</grid>
<check text="Zoom with Scroll Wheel" id="wheel_zoom" />
<check text="Show timeline automatically" id="autotimeline" tooltip="Show the timeline automatically&#10;when a new frame or layer is added." />
</vbox>
<separator text="Screen:" horizontal="true" />
<grid columns="2">
<label text="Screen Scale:" />
<combobox id="screen_scale" expansive="true" />
</grid>
<!-- Editor -->
<vbox id="section_editor">
<separator text="Editor" horizontal="true" />
<check text="Smooth auto-scroll" id="smooth" />
<check text="Show scroll-bars in sprite editor" id="show_scrollbars" tooltip="Show scroll-bars in all sprite editors." />
<grid columns="2">
<label text="Cursor:" />
<box id="cursor_color_box" /><!-- custom widget -->
</grid>
</vbox>
<!-- Editor -->
<!-- Grid & background -->
<vbox id="section_grid">
<separator text="Grid" horizontal="true" />
<grid columns="2">
<label text="Grid Color:" />
<box id="grid_color_box" /><!-- custom widget -->
<separator text="Editor:" horizontal="true" />
<check text="Smooth auto-scroll" id="smooth" />
<check text="Show timeline automatically" id="autotimeline" tooltip="Show the timeline automatically&#10;when a new frame or layer is added." />
<check text="Show scroll-bars in sprite editor" id="show_scrollbars" tooltip="Show scroll-bars in all sprite editors." />
<grid columns="2">
<label text="Cursor:" />
<box id="cursor_color_box" /><!-- custom widget -->
<label text="Pixel Grid:" />
<box id="pixel_grid_color_box" /><!-- custom widget -->
</grid>
<label text="Grid Color:" />
<box id="grid_color_box" /><!-- custom widget -->
<separator text="Checked Background" horizontal="true" />
<box horizontal="true">
<label text="Size:" />
<combobox id="checked_bg_size" expansive="true" />
</box>
<check text="Apply Zoom" id="checked_bg_zoom" />
<grid columns="2">
<label text="Color 1" />
<box horizontal="true" id="checked_bg_color1_box" />
<label text="Color 2" />
<box horizontal="true" id="checked_bg_color2_box" />
</grid>
<button id="checked_bg_reset" text="Reset" />
</vbox>
<label text="Pixel Grid:" />
<box id="pixel_grid_color_box" /><!-- custom widget -->
</grid>
<!-- Undo -->
<separator text="Undo:" horizontal="true" />
<box horizontal="true">
<label text="Undo Limit:" />
<entry id="undo_size_limit" maxsize="4" tooltip="Limit of memory to be used&#10;for undo information per sprite.&#10;Specified in megabytes." />
<label text="MB" />
</box>
<box horizontal="true">
<check id="undo_goto_modified" text="Go to modified frame/layer" tooltip="When it's enabled each time you undo/redo&#10;the current frame &amp; layer will be modified&#10;to focus the undid/redid change." />
</box>
</box>
<separator vertical="true" />
<box vertical="true">
<!-- Checked Background -->
<separator text="Checked Background:" horizontal="true" />
<box horizontal="true">
<label text="Size:" />
<combobox id="checked_bg_size" expansive="true" />
</box>
<check text="Apply Zoom" id="checked_bg_zoom" />
<grid columns="2">
<label text="Color 1" />
<box horizontal="true" id="checked_bg_color1_box" />
<label text="Color 2" />
<box horizontal="true" id="checked_bg_color2_box" />
</grid>
<button id="checked_bg_reset" text="Reset" />
</box>
</box>
<!-- Undo -->
<vbox id="section_undo">
<separator text="Undo" horizontal="true" />
<box horizontal="true">
<label text="Undo Limit:" />
<entry id="undo_size_limit" maxsize="4" tooltip="Limit of memory to be used&#10;for undo information per sprite.&#10;Specified in megabytes." />
<label text="MB" />
</box>
<box horizontal="true">
<check id="undo_goto_modified" text="Go to modified frame/layer" tooltip="When it's enabled each time you undo/redo&#10;the current frame &amp; layer will be modified&#10;to focus the undid/redid change." />
</box>
</vbox>
</panel>
</hbox>
<separator horizontal="true" />
<box horizontal="true">
<hbox>
<link id="locate_file" text="Locate File" />
<boxfiller />
<box horizontal="true" homogeneous="true">
<hbox homogeneous="true">
<button text="&amp;OK" closewindow="true" id="button_ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</hbox>
</hbox>
</vbox>
</gui>

View File

@ -210,10 +210,10 @@ if(EXISTS ../docs/quickref.pdf)
endif()
######################################################################
# Unit tests
# Tests
function(find_unittests dir dependencies)
file(GLOB tests ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*_unittest.cpp)
function(find_tests dir dependencies)
file(GLOB tests ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*_tests.cpp)
list(REMOVE_AT ARGV 0)
if(NOT USE_SHARED_GTEST)
@ -247,8 +247,8 @@ function(find_unittests dir dependencies)
set(local_runs ${local_runs} run_${testname})
string(REGEX MATCH "_ui_unittest" test_requires_ui ${testname})
if (NOT test_requires_ui STREQUAL "_ui_unittest")
string(REGEX MATCH "_ui_tests" test_requires_ui ${testname})
if (NOT test_requires_ui STREQUAL "_ui_tests")
set(local_non_ui_runs ${local_non_ui_runs} run_${testname})
endif()
endforeach()
@ -256,15 +256,15 @@ function(find_unittests dir dependencies)
set(non_ui_runs ${non_ui_runs} ${local_non_ui_runs} PARENT_SCOPE)
endfunction()
find_unittests(base base-lib ${sys_libs})
find_unittests(gfx gfx-lib base-lib ${sys_libs})
find_unittests(raster raster-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(css css-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(ui ui-lib she gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(file ${all_libs})
find_unittests(app ${all_libs})
find_unittests(. ${all_libs})
find_tests(base base-lib ${sys_libs})
find_tests(gfx gfx-lib base-lib ${sys_libs})
find_tests(raster raster-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(css css-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(ui ui-lib she gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_tests(app/file ${all_libs})
find_tests(app ${all_libs})
find_tests(. ${all_libs})
# To run tests
add_custom_target(run_all_unittests DEPENDS ${all_runs})
add_custom_target(run_non_ui_unittests DEPENDS ${non_ui_runs})
add_custom_target(run_all_tests DEPENDS ${all_runs})
add_custom_target(run_non_ui_tests DEPENDS ${non_ui_runs})

View File

@ -26,7 +26,7 @@ because they don't depend on any other component.
* [doc](doc/) (base, gfx): Document model library (business layer, replacement of `raster` library).
* [net](net/) (base): Networking library to send HTTP requests.
* [raster](raster/) (base, gfx): Library to handle graphics entities like sprites, images, frames.
* [she](she/) (allegro): A (Work In Progress) wrapper for Allegro library.
* [she](she/) (base, gfx, allegro): A wrapper for the Allegro library.
* [webserver](webserver/) (base): HTTP web server (based on [mongoose](https://github.com/valenok/mongoose))
## Level 2

View File

@ -178,6 +178,9 @@ static int osx_mouse_init(void)
osx_emulate_mouse_buttons = (max_buttons == 1) ? TRUE : FALSE;
_unix_unlock_mutex(osx_event_mutex);
_mouse_on = TRUE;
[NSCursor performSelectorOnMainThread: @selector(hide) withObject: nil waitUntilDone: NO];
return max_buttons;
}
@ -344,7 +347,6 @@ int osx_mouse_show(BITMAP *bmp, int x, int y)
return -1;
osx_change_cursor(requested_cursor);
return 0;
}

View File

@ -223,7 +223,10 @@ void osx_event_handler()
mx = point.x;
my = frame.size.height - point.y;
buttons = 0;
_mouse_on = TRUE;
if (!_mouse_on) {
_mouse_on = TRUE;
[NSCursor performSelectorOnMainThread: @selector(hide) withObject: nil waitUntilDone: NO];
}
}
}
if (osx_window)
@ -292,8 +295,11 @@ void osx_event_handler()
mx = point.x;
my = frame.size.height - point.y;
buttons = 0;
_mouse_on = TRUE;
gotmouseevent = YES;
if (!_mouse_on) {
_mouse_on = TRUE;
[NSCursor performSelectorOnMainThread: @selector(hide) withObject: nil waitUntilDone: NO];
}
}
}
[NSApp sendEvent: event];
@ -302,8 +308,11 @@ void osx_event_handler()
case NSMouseExited:
if ([event trackingNumber] == osx_mouse_tracking_rect) {
if (_mouse_installed) {
_mouse_on = FALSE;
gotmouseevent = YES;
if (_mouse_on) {
_mouse_on = FALSE;
[NSCursor performSelectorOnMainThread: @selector(unhide) withObject: nil waitUntilDone: NO];
}
}
}
[NSApp sendEvent: event];

View File

@ -56,7 +56,7 @@ int _mouse_y = 0;
int _mouse_z = 0;
int _mouse_w = 0;
int _mouse_b = 0;
int _mouse_on = TRUE;
int _mouse_on = FALSE;
static int mon = TRUE;

View File

@ -137,9 +137,10 @@ add_library(app-lib
modules/gui.cpp
modules/palettes.cpp
objects_container_impl.cpp
palettes_loader.cpp
project.cpp
recent_files.cpp
res/palettes_loader_delegate.cpp
res/resources_loader.cpp
resource_finder.cpp
settings/ui_settings_impl.cpp
shell.cpp
@ -184,10 +185,11 @@ add_library(app-lib
ui/main_window.cpp
ui/mini_editor.cpp
ui/notifications.cpp
ui/palette_listbox.cpp
ui/palettes_listbox.cpp
ui/palette_popup.cpp
ui/palette_view.cpp
ui/popup_window_pin.cpp
ui/resources_listbox.cpp
ui/skin/button_icon_impl.cpp
ui/skin/skin_part.cpp
ui/skin/skin_property.cpp

View File

@ -66,6 +66,7 @@
#include "raster/palette.h"
#include "raster/sprite.h"
#include "scripting/engine.h"
#include "she/error.h"
#include "ui/intern.h"
#include "ui/ui.h"
@ -78,7 +79,6 @@
#include <string.h>
#include <time.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
@ -313,7 +313,7 @@ App::~App()
m_instance = NULL;
}
catch (...) {
allegro_message("Error closing ASE.\n(uncaught exception)");
she::error_message("Error closing ASE.\n(uncaught exception)");
// no re-throw
}

View File

@ -32,8 +32,6 @@
#include "raster/palette.h"
#include "raster/sprite.h"
using namespace gfx;
// Internal functions
namespace {
@ -56,43 +54,45 @@ int get_mask_for_bitmap(int depth)
namespace app {
ui::Color color_utils::blackandwhite(ui::Color color)
gfx::Color color_utils::blackandwhite(gfx::Color color)
{
if ((ui::getr(color)*30+ui::getg(color)*59+ui::getb(color)*11)/100 < 128)
return ui::rgba(0, 0, 0);
if ((gfx::getr(color)*30+gfx::getg(color)*59+gfx::getb(color)*11)/100 < 128)
return gfx::rgba(0, 0, 0);
else
return ui::rgba(255, 255, 255);
return gfx::rgba(255, 255, 255);
}
ui::Color color_utils::blackandwhite_neg(ui::Color color)
gfx::Color color_utils::blackandwhite_neg(gfx::Color color)
{
if ((ui::getr(color)*30+ui::getg(color)*59+ui::getb(color)*11)/100 < 128)
return ui::rgba(255, 255, 255);
if ((gfx::getr(color)*30+gfx::getg(color)*59+gfx::getb(color)*11)/100 < 128)
return gfx::rgba(255, 255, 255);
else
return ui::rgba(0, 0, 0);
return gfx::rgba(0, 0, 0);
}
ui::Color color_utils::color_for_ui(const app::Color& color)
gfx::Color color_utils::color_for_ui(const app::Color& color)
{
ui::Color c = ui::ColorNone;
gfx::Color c = gfx::ColorNone;
switch (color.getType()) {
case app::Color::MaskType:
c = ui::ColorNone;
c = gfx::ColorNone;
break;
case app::Color::RgbType:
case app::Color::HsvType:
c = ui::rgba(color.getRed(),
color.getGreen(),
color.getBlue(), 255);
c = gfx::rgba(
color.getRed(),
color.getGreen(),
color.getBlue(), 255);
break;
case app::Color::GrayType:
c = ui::rgba(color.getGray(),
color.getGray(),
color.getGray(), 255);
c = gfx::rgba(
color.getGray(),
color.getGray(),
color.getGray(), 255);
break;
case app::Color::IndexType: {
@ -100,9 +100,10 @@ ui::Color color_utils::color_for_ui(const app::Color& color)
ASSERT(i >= 0 && i < (int)get_current_palette()->size());
uint32_t _c = get_current_palette()->getEntry(i);
c = ui::rgba(rgba_getr(_c),
rgba_getg(_c),
rgba_getb(_c), 255);
c = gfx::rgba(
rgba_getr(_c),
rgba_getg(_c),
rgba_getb(_c), 255);
break;
}
@ -111,48 +112,6 @@ ui::Color color_utils::color_for_ui(const app::Color& color)
return c;
}
int color_utils::color_for_allegro(const app::Color& color, int depth)
{
int c = -1;
switch (color.getType()) {
case app::Color::MaskType:
c = get_mask_for_bitmap(depth);
break;
case app::Color::RgbType:
case app::Color::HsvType:
c = makeacol_depth(depth,
color.getRed(),
color.getGreen(),
color.getBlue(), 255);
break;
case app::Color::GrayType:
c = color.getGray();
if (depth != 8)
c = makeacol_depth(depth, c, c, c, 255);
break;
case app::Color::IndexType:
c = color.getIndex();
if (depth != 8) {
ASSERT(c >= 0 && c < (int)get_current_palette()->size());
uint32_t _c = get_current_palette()->getEntry(c);
c = makeacol_depth(depth,
rgba_getr(_c),
rgba_getg(_c),
rgba_getb(_c), 255);
}
break;
}
return c;
}
raster::color_t color_utils::color_for_image(const app::Color& color, PixelFormat format)
{
if (color.getType() == app::Color::MaskType)
@ -162,10 +121,10 @@ raster::color_t color_utils::color_for_image(const app::Color& color, PixelForma
switch (format) {
case IMAGE_RGB:
c = rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
c = raster::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
break;
case IMAGE_GRAYSCALE:
c = graya(color.getGray(), 255);
c = raster::graya(color.getGray(), 255);
break;
case IMAGE_INDEXED:
c = color.getIndex();
@ -189,10 +148,10 @@ raster::color_t color_utils::color_for_target(const app::Color& color, const Col
switch (colorTarget.pixelFormat()) {
case IMAGE_RGB:
c = rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
c = raster::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
break;
case IMAGE_GRAYSCALE:
c = graya(color.getGray(), 255);
c = raster::graya(color.getGray(), 255);
break;
case IMAGE_INDEXED:
if (color.getType() == app::Color::IndexType) {

View File

@ -22,9 +22,9 @@
#include "app/color.h"
#include "app/color_target.h"
#include "gfx/color.h"
#include "raster/color.h"
#include "raster/pixel_format.h"
#include "ui/color.h"
namespace raster {
class Layer;
@ -33,11 +33,10 @@ namespace raster {
namespace app {
namespace color_utils {
ui::Color blackandwhite(ui::Color color);
ui::Color blackandwhite_neg(ui::Color color);
gfx::Color blackandwhite(gfx::Color color);
gfx::Color blackandwhite_neg(gfx::Color color);
ui::Color color_for_ui(const app::Color& color);
int color_for_allegro(const app::Color& color, int depth);
gfx::Color color_for_ui(const app::Color& color);
raster::color_t color_for_image(const app::Color& color, raster::PixelFormat format);
raster::color_t color_for_layer(const app::Color& color, raster::Layer* layer);
raster::color_t color_for_target(const app::Color& color, const ColorTarget& colorTarget);

View File

@ -54,10 +54,7 @@ protected:
virtual FrameNumber onGetFrame(Editor* editor) = 0;
};
class GotoFirstFrameCommand : public GotoCommand
{
class GotoFirstFrameCommand : public GotoCommand {
public:
GotoFirstFrameCommand()
: GotoCommand("GotoFirstFrame",
@ -70,11 +67,7 @@ protected:
}
};
class GotoPreviousFrameCommand : public GotoCommand
{
class GotoPreviousFrameCommand : public GotoCommand {
public:
GotoPreviousFrameCommand()
: GotoCommand("GotoPreviousFrame",
@ -92,11 +85,7 @@ protected:
}
};
class GotoNextFrameCommand : public GotoCommand
{
class GotoNextFrameCommand : public GotoCommand {
public:
GotoNextFrameCommand() : GotoCommand("GotoNextFrame",
"Goto Next Frame") { }
@ -112,10 +101,7 @@ protected:
}
};
class GotoLastFrameCommand : public GotoCommand
{
class GotoLastFrameCommand : public GotoCommand {
public:
GotoLastFrameCommand() : GotoCommand("GotoLastFrame",
"Goto Last Frame") { }
@ -127,11 +113,7 @@ protected:
}
};
class GotoFrameCommand : public GotoCommand
{
class GotoFrameCommand : public GotoCommand {
public:
GotoFrameCommand() : GotoCommand("GotoFrame",
"Goto Frame")

View File

@ -42,145 +42,131 @@ namespace app {
using namespace ui;
class OptionsCommand : public Command {
class OptionsWindow : public Window {
public:
OptionsCommand();
Command* clone() const OVERRIDE { return new OptionsCommand(*this); }
OptionsWindow(Context* context)
: Window(Window::WithTitleBar, "Options")
, m_settings(context->settings())
, m_docSettings(m_settings->getDocumentSettings(NULL))
, m_checked_bg_color1(new ColorButton(RenderEngine::getCheckedBgColor1(), IMAGE_RGB))
, m_checked_bg_color2(new ColorButton(RenderEngine::getCheckedBgColor2(), IMAGE_RGB))
, m_pixelGridColor(new ColorButton(m_docSettings->getPixelGridColor(), IMAGE_RGB))
, m_gridColor(new ColorButton(m_docSettings->getGridColor(), IMAGE_RGB))
, m_cursorColor(new ColorButton(Editor::get_cursor_color(), IMAGE_RGB))
{
addChild(app::load_widget<Box>("options.xml", "main_box"));
protected:
void onExecute(Context* context);
// Load the this widget
app::finder(this)
>> "section_listbox" >> m_section_listbox
>> "panel" >> m_panel
>> "smooth" >> m_check_smooth
>> "autotimeline" >> m_check_autotimeline
>> "show_scrollbars" >> m_show_scrollbars
>> "cursor_color_box" >> m_cursor_color_box
>> "grid_color_box" >> m_grid_color_box
>> "pixel_grid_color_box" >> m_pixel_grid_color_box
>> "checked_bg_size" >> m_checked_bg
>> "checked_bg_zoom" >> m_checked_bg_zoom
>> "checked_bg_color1_box" >> m_checked_bg_color1_box
>> "checked_bg_color2_box" >> m_checked_bg_color2_box
>> "checked_bg_reset" >> m_checked_bg_reset
>> "undo_size_limit" >> m_undo_size_limit
>> "undo_goto_modified" >> m_undo_goto_modified
>> "screen_scale" >> m_screen_scale
>> "wheel_zoom" >> m_wheel_zoom
>> "locate_file" >> m_locate_file
>> "button_ok" >> m_button_ok;
private:
void onResetCheckedBg();
void onLocateConfigFile();
m_section_listbox->ChangeSelectedItem.connect(Bind<void>(&OptionsWindow::onChangeSection, this));
m_cursor_color_box->addChild(m_cursorColor);
ComboBox* m_checked_bg;
Widget* m_checked_bg_zoom;
ColorButton* m_checked_bg_color1;
ColorButton* m_checked_bg_color2;
};
// Grid color
m_gridColor->setId("grid_color");
m_grid_color_box->addChild(m_gridColor);
OptionsCommand::OptionsCommand()
: Command("Options",
"Options",
CmdUIOnlyFlag)
{
}
// Pixel grid color
m_pixelGridColor->setId("pixel_grid_color");
m_pixel_grid_color_box->addChild(m_pixelGridColor);
void OptionsCommand::onExecute(Context* context)
{
// Load the window widget
base::UniquePtr<Window> window(app::load_widget<Window>("options.xml", "options"));
Widget* check_smooth = app::find_widget<Widget>(window, "smooth");
Widget* check_autotimeline = app::find_widget<Widget>(window, "autotimeline");
Widget* show_scrollbars = app::find_widget<Widget>(window, "show_scrollbars");
Widget* cursor_color_box = app::find_widget<Widget>(window, "cursor_color_box");
Widget* grid_color_box = app::find_widget<Widget>(window, "grid_color_box");
Widget* pixel_grid_color_box = app::find_widget<Widget>(window, "pixel_grid_color_box");
m_checked_bg = app::find_widget<ComboBox>(window, "checked_bg_size");
m_checked_bg_zoom = app::find_widget<Widget>(window, "checked_bg_zoom");
Widget* checked_bg_color1_box = app::find_widget<Widget>(window, "checked_bg_color1_box");
Widget* checked_bg_color2_box = app::find_widget<Widget>(window, "checked_bg_color2_box");
Button* checked_bg_reset = app::find_widget<Button>(window, "checked_bg_reset");
Widget* undo_size_limit = app::find_widget<Widget>(window, "undo_size_limit");
Widget* undo_goto_modified = app::find_widget<Widget>(window, "undo_goto_modified");
ComboBox* screen_scale = app::find_widget<ComboBox>(window, "screen_scale");
LinkLabel* locate_file = app::find_widget<LinkLabel>(window, "locate_file");
Widget* button_ok = app::find_widget<Widget>(window, "button_ok");
// Others
if (get_config_bool("Options", "MoveSmooth", true))
m_check_smooth->setSelected(true);
// Cursor color
ColorButton* cursor_color = new ColorButton(Editor::get_cursor_color(), IMAGE_RGB);
cursor_color->setId("cursor_color");
cursor_color_box->addChild(cursor_color);
if (get_config_bool("Options", "AutoShowTimeline", true))
m_check_autotimeline->setSelected(true);
// Get global settings for documents
ISettings* settings = context->settings();
IDocumentSettings* docSettings = settings->getDocumentSettings(NULL);
if (m_settings->getShowSpriteEditorScrollbars())
m_show_scrollbars->setSelected(true);
// Grid color
ColorButton* grid_color = new ColorButton(docSettings->getGridColor(), IMAGE_RGB);
grid_color->setId("grid_color");
grid_color_box->addChild(grid_color);
// Checked background size
m_screen_scale->addItem("1:1");
m_screen_scale->addItem("2:1");
m_screen_scale->addItem("3:1");
m_screen_scale->addItem("4:1");
m_screen_scale->setSelectedItemIndex(get_screen_scaling()-1);
// Pixel grid color
ColorButton* pixel_grid_color = new ColorButton(docSettings->getPixelGridColor(), IMAGE_RGB);
pixel_grid_color->setId("pixel_grid_color");
pixel_grid_color_box->addChild(pixel_grid_color);
// Zoom with Scroll Wheel
m_wheel_zoom->setSelected(m_settings->getZoomWithScrollWheel());
// Others
if (get_config_bool("Options", "MoveSmooth", true))
check_smooth->setSelected(true);
// Checked background size
m_checked_bg->addItem("16x16");
m_checked_bg->addItem("8x8");
m_checked_bg->addItem("4x4");
m_checked_bg->addItem("2x2");
m_checked_bg->setSelectedItemIndex((int)RenderEngine::getCheckedBgType());
if (get_config_bool("Options", "AutoShowTimeline", true))
check_autotimeline->setSelected(true);
// Zoom checked background
if (RenderEngine::getCheckedBgZoom())
m_checked_bg_zoom->setSelected(true);
if (settings->getShowSpriteEditorScrollbars())
show_scrollbars->setSelected(true);
// Checked background colors
m_checked_bg_color1_box->addChild(m_checked_bg_color1);
m_checked_bg_color2_box->addChild(m_checked_bg_color2);
// Checked background size
screen_scale->addItem("1:1");
screen_scale->addItem("2:1");
screen_scale->addItem("3:1");
screen_scale->addItem("4:1");
screen_scale->setSelectedItemIndex(get_screen_scaling()-1);
// Reset button
m_checked_bg_reset->Click.connect(Bind<void>(&OptionsWindow::onResetCheckedBg, this));
// Checked background size
m_checked_bg->addItem("16x16");
m_checked_bg->addItem("8x8");
m_checked_bg->addItem("4x4");
m_checked_bg->addItem("2x2");
m_checked_bg->setSelectedItemIndex((int)RenderEngine::getCheckedBgType());
// Locate config file
m_locate_file->Click.connect(Bind<void>(&OptionsWindow::onLocateConfigFile, this));
// Zoom checked background
if (RenderEngine::getCheckedBgZoom())
m_checked_bg_zoom->setSelected(true);
// Undo limit
m_undo_size_limit->setTextf("%d", get_config_int("Options", "UndoSizeLimit", 8));
// Checked background colors
m_checked_bg_color1 = new ColorButton(RenderEngine::getCheckedBgColor1(), IMAGE_RGB);
m_checked_bg_color2 = new ColorButton(RenderEngine::getCheckedBgColor2(), IMAGE_RGB);
// Goto modified frame/layer on undo/redo
if (get_config_bool("Options", "UndoGotoModified", true))
m_undo_goto_modified->setSelected(true);
checked_bg_color1_box->addChild(m_checked_bg_color1);
checked_bg_color2_box->addChild(m_checked_bg_color2);
m_section_listbox->selectIndex(0);
}
// Reset button
checked_bg_reset->Click.connect(Bind<void>(&OptionsCommand::onResetCheckedBg, this));
bool ok() {
return (getKiller() == m_button_ok);
}
// Locate config file
locate_file->Click.connect(Bind<void>(&OptionsCommand::onLocateConfigFile, this));
void saveConfig() {
Editor::set_cursor_color(m_cursorColor->getColor());
m_docSettings->setGridColor(m_gridColor->getColor());
m_docSettings->setPixelGridColor(m_pixelGridColor->getColor());
// Undo limit
undo_size_limit->setTextf("%d", get_config_int("Options", "UndoSizeLimit", 8));
set_config_bool("Options", "MoveSmooth", m_check_smooth->isSelected());
set_config_bool("Options", "AutoShowTimeline", m_check_autotimeline->isSelected());
// Goto modified frame/layer on undo/redo
if (get_config_bool("Options", "UndoGotoModified", true))
undo_goto_modified->setSelected(true);
// Show the window and wait the user to close it
window->openWindowInForeground();
if (window->getKiller() == button_ok) {
int undo_size_limit_value;
Editor::set_cursor_color(cursor_color->getColor());
docSettings->setGridColor(grid_color->getColor());
docSettings->setPixelGridColor(pixel_grid_color->getColor());
set_config_bool("Options", "MoveSmooth", check_smooth->isSelected());
set_config_bool("Options", "AutoShowTimeline", check_autotimeline->isSelected());
settings->setShowSpriteEditorScrollbars(show_scrollbars->isSelected());
m_settings->setShowSpriteEditorScrollbars(m_show_scrollbars->isSelected());
m_settings->setZoomWithScrollWheel(m_wheel_zoom->isSelected());
RenderEngine::setCheckedBgType((RenderEngine::CheckedBgType)m_checked_bg->getSelectedItemIndex());
RenderEngine::setCheckedBgZoom(m_checked_bg_zoom->isSelected());
RenderEngine::setCheckedBgColor1(m_checked_bg_color1->getColor());
RenderEngine::setCheckedBgColor2(m_checked_bg_color2->getColor());
undo_size_limit_value = undo_size_limit->getTextInt();
int undo_size_limit_value;
undo_size_limit_value = m_undo_size_limit->getTextInt();
undo_size_limit_value = MID(1, undo_size_limit_value, 9999);
set_config_int("Options", "UndoSizeLimit", undo_size_limit_value);
set_config_bool("Options", "UndoGotoModified", undo_goto_modified->isSelected());
set_config_bool("Options", "UndoGotoModified", m_undo_goto_modified->isSelected());
int new_screen_scaling = screen_scale->getSelectedItemIndex()+1;
int new_screen_scaling = m_screen_scale->getSelectedItemIndex()+1;
if (new_screen_scaling != get_screen_scaling()) {
set_screen_scaling(new_screen_scaling);
@ -192,20 +178,78 @@ void OptionsCommand::onExecute(Context* context)
// Save configuration
flush_config_file();
}
private:
void onChangeSection() {
ListItem* item = m_section_listbox->getSelectedChild();
if (!item)
return;
m_panel->showChild(findChild(item->getValue().c_str()));
}
void onResetCheckedBg() {
// Default values
m_checked_bg->setSelectedItemIndex((int)RenderEngine::CHECKED_BG_16X16);
m_checked_bg_zoom->setSelected(true);
m_checked_bg_color1->setColor(app::Color::fromRgb(128, 128, 128));
m_checked_bg_color2->setColor(app::Color::fromRgb(192, 192, 192));
}
void onLocateConfigFile() {
app::launcher::open_folder(app::get_config_file());
}
ISettings* m_settings;
IDocumentSettings* m_docSettings;
ListBox* m_section_listbox;
Panel* m_panel;
Widget* m_check_smooth;
Widget* m_check_autotimeline;
Widget* m_show_scrollbars;
Widget* m_cursor_color_box;
Widget* m_grid_color_box;
Widget* m_pixel_grid_color_box;
ComboBox* m_checked_bg;
Widget* m_checked_bg_zoom;
Widget* m_checked_bg_color1_box;
Widget* m_checked_bg_color2_box;
Button* m_checked_bg_reset;
Widget* m_undo_size_limit;
Widget* m_undo_goto_modified;
ComboBox* m_screen_scale;
CheckBox* m_wheel_zoom;
LinkLabel* m_locate_file;
ColorButton* m_checked_bg_color1;
ColorButton* m_checked_bg_color2;
ColorButton* m_pixelGridColor;
ColorButton* m_gridColor;
ColorButton* m_cursorColor;
Button* m_button_ok;
};
class OptionsCommand : public Command {
public:
OptionsCommand();
Command* clone() const OVERRIDE { return new OptionsCommand(*this); }
protected:
void onExecute(Context* context);
};
OptionsCommand::OptionsCommand()
: Command("Options",
"Options",
CmdUIOnlyFlag)
{
}
void OptionsCommand::onResetCheckedBg()
void OptionsCommand::onExecute(Context* context)
{
// Default values
m_checked_bg->setSelectedItemIndex((int)RenderEngine::CHECKED_BG_16X16);
m_checked_bg_zoom->setSelected(true);
m_checked_bg_color1->setColor(app::Color::fromRgb(128, 128, 128));
m_checked_bg_color2->setColor(app::Color::fromRgb(192, 192, 192));
}
void OptionsCommand::onLocateConfigFile()
{
app::launcher::open_folder(app::get_config_file());
OptionsWindow window(context);
window.openWindowInForeground();
if (window.ok())
window.saveConfig();
}
Command* CommandFactory::createOptionsCommand()

View File

@ -185,6 +185,7 @@ protected:
{
ContextWriter writer(reader);
Document* documentWriter = writer.document();
std::string oldFilename = documentWriter->getFilename();
// Change the document file name
documentWriter->setFilename(filename.c_str());
@ -193,6 +194,9 @@ protected:
// Save the document
save_document_in_background(documentWriter, markAsSaved);
if (documentWriter->isModified())
documentWriter->setFilename(oldFilename);
update_screen_for_document(documentWriter);
}
}

View File

@ -1018,12 +1018,12 @@ static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, FrameNumber frame,
layer = sprite->indexToLayer(layer_index);
if (!layer) {
fop_error(fop, "Frame %d didn't found layer with index %d\n",
(int)frame, layer_index);
(int)frame, (int)layer_index);
return NULL;
}
if (!layer->isImage()) {
fop_error(fop, "Invalid .ase file (frame %d in layer %d which does not contain images\n",
(int)frame, layer_index);
(int)frame, (int)layer_index);
return NULL;
}

View File

@ -29,11 +29,11 @@
#include <cstdlib>
#include <vector>
using namespace app::file;
using namespace app;
TEST(File, SeveralSizes)
{
she::ScopedHandle<she::System> system(she::CreateSystem());
she::ScopedHandle<she::System> system(she::create_system());
// Register all possible image formats.
FileFormatsManager::instance().registerAllFormats();
std::vector<char> fn(256);

View File

@ -27,8 +27,10 @@
#include "app/file_system.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/string.h"
#include "she/surface.h"
#include <algorithm>
#include <cstdio>
@ -54,6 +56,7 @@
#endif
#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX || defined ALLEGRO_MINGW32
#include <sys/unistd.h>
#endif
#if defined USE_PIDLS
@ -144,16 +147,17 @@ public:
IFileItem* getParent() const;
const FileItemList& getChildren();
void createDirectory(const std::string& dirname);
bool hasExtension(const std::string& csv_extensions);
BITMAP* getThumbnail();
void setThumbnail(BITMAP* thumbnail);
she::Surface* getThumbnail();
void setThumbnail(she::Surface* thumbnail);
};
typedef std::map<std::string, FileItem*> FileItemMap;
typedef std::map<std::string, BITMAP*> ThumbnailMap;
typedef std::map<std::string, she::Surface*> ThumbnailMap;
// the root of the file-system
static FileItem* rootitem = NULL;
@ -237,7 +241,7 @@ FileSystemModule::~FileSystemModule()
for (ThumbnailMap::iterator
it=thumbnail_map->begin(); it!=thumbnail_map->end(); ++it) {
destroy_bitmap(it->second);
it->second->dispose();
}
thumbnail_map->clear();
@ -560,6 +564,14 @@ const FileItemList& FileItem::getChildren()
return this->children;
}
void FileItem::createDirectory(const std::string& dirname)
{
base::make_directory(base::join_path(filename, dirname));
// Invalidate the children list.
this->version = 0;
}
bool FileItem::hasExtension(const std::string& csv_extensions)
{
ASSERT(this->filename != NOTINITIALIZED);
@ -567,7 +579,7 @@ bool FileItem::hasExtension(const std::string& csv_extensions)
return base::has_file_extension(this->filename, csv_extensions);
}
BITMAP* FileItem::getThumbnail()
she::Surface* FileItem::getThumbnail()
{
ThumbnailMap::iterator it = thumbnail_map->find(this->filename);
if (it != thumbnail_map->end())
@ -576,12 +588,12 @@ BITMAP* FileItem::getThumbnail()
return NULL;
}
void FileItem::setThumbnail(BITMAP* thumbnail)
void FileItem::setThumbnail(she::Surface* thumbnail)
{
// destroy the current thumbnail of the file (if exists)
ThumbnailMap::iterator it = thumbnail_map->find(this->filename);
if (it != thumbnail_map->end()) {
destroy_bitmap(it->second);
it->second->dispose();
thumbnail_map->erase(it);
}

View File

@ -25,7 +25,9 @@
#include <string>
#include <vector>
struct BITMAP;
namespace she {
class Surface;
}
namespace app {
@ -86,11 +88,12 @@ namespace app {
virtual IFileItem* getParent() const = 0;
virtual const FileItemList& getChildren() = 0;
virtual void createDirectory(const std::string& dirname) = 0;
virtual bool hasExtension(const std::string& csv_extensions) = 0;
virtual BITMAP* getThumbnail() = 0;
virtual void setThumbnail(BITMAP* thumbnail) = 0;
virtual she::Surface* getThumbnail() = 0;
virtual void setThumbnail(she::Surface* thumbnail) = 0;
};
} // namespace app

View File

@ -27,6 +27,7 @@
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/main_window.h"
#include "she/error.h"
#include "ui/manager.h"
#include "ui/window.h"
@ -107,7 +108,7 @@ bool CurrentGfxModeGuard::tryGfxMode(const GfxMode& newMode)
if (!m_oldMode.setGfxMode()) {
// Oh no! more errors!, we can't restore the old graphics mode!
set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
allegro_message("FATAL ERROR: Unable to restore the old graphics mode!\n");
she::error_message("FATAL ERROR: Unable to restore the old graphics mode!\n");
exit(1);
}
// Only print a message of the old error

View File

@ -23,25 +23,25 @@
#include <allegro.h>
#include <allegro/internal/aintern.h>
#include "ui/color.h"
#include "gfx/color.h"
#include "ui/intern.h"
#include "ui/system.h"
#include "ui/theme.h"
#include "app/app.h"
#include "app/color_utils.h"
#include "app/ui/editor/editor.h"
#include "app/console.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "app/ini_file.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "raster/blend.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "app/ui/skin/skin_theme.h"
namespace app {
@ -171,8 +171,8 @@ static void rectgrid(ui::Graphics* g, const gfx::Rect& rc, const gfx::Size& tile
return;
int x, y, u, v;
ui::Color c1 = ui::rgba(128, 128, 128);
ui::Color c2 = ui::rgba(192, 192, 192);
gfx::Color c1 = gfx::rgba(128, 128, 128);
gfx::Color c2 = gfx::rgba(192, 192, 192);
u = 0;
v = 0;
@ -213,8 +213,8 @@ static void draw_color(ui::Graphics* g, const Rect& rc, const app::Color& color)
g->fillRect(color_utils::color_for_ui(color), rc);
}
else {
g->fillRect(ui::rgba(0, 0, 0), rc);
g->drawLine(ui::rgba(255, 255, 255),
g->fillRect(gfx::rgba(0, 0, 0), rc);
g->drawLine(gfx::rgba(255, 255, 255),
gfx::Point(rc.x+rc.w-2, rc.y+1),
gfx::Point(rc.x+1, rc.y+rc.h-2));
}

View File

@ -21,14 +21,11 @@
#pragma once
#include "app/color.h"
#include "gfx/color.h"
#include "gfx/rect.h"
#include "ui/base.h"
#include "ui/color.h"
#include "ui/graphics.h"
struct FONT;
struct BITMAP;
namespace app {
using namespace raster;

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -49,6 +49,7 @@
#include "raster/sprite.h"
#include "she/clipboard.h"
#include "she/display.h"
#include "she/error.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/intern.h"
@ -168,13 +169,13 @@ int init_module_gui()
load_gui_config(w, h, maximized);
try {
main_display = she::Instance()->createDisplay(w, h, screen_scaling);
main_display = she::instance()->createDisplay(w, h, screen_scaling);
}
catch (const she::DisplayCreationException&) {
for (c=min_possible_dsk_res; try_resolutions[c].width; ++c) {
try {
main_display =
she::Instance()->createDisplay(try_resolutions[c].width,
she::instance()->createDisplay(try_resolutions[c].width,
try_resolutions[c].height,
try_resolutions[c].scale);
@ -188,11 +189,11 @@ int init_module_gui()
}
if (!main_display) {
allegro_message("Unable to create a user-interface display.\n");
she::error_message("Unable to create a user-interface display.\n");
return -1;
}
main_clipboard = she::Instance()->createClipboard();
main_clipboard = she::instance()->createClipboard();
// Create the default-manager
manager = new CustomizedGuiManager();
@ -333,7 +334,7 @@ void gui_setup_screen(bool reload_font)
bool reinit = false;
main_display->setScale(screen_scaling);
ui::SetDisplay(main_display);
ui::set_display(main_display);
// Update guiscale factor
int old_guiscale = jguiscale();

View File

@ -0,0 +1,48 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_RES_PALETTE_RESOURCE_H_INCLUDED
#define APP_RES_PALETTE_RESOURCE_H_INCLUDED
#pragma once
#include "app/res/resource.h"
namespace raster {
class Palette;
}
namespace app {
class PaletteResource : public Resource {
public:
PaletteResource(raster::Palette* palette, const std::string& name)
: m_palette(palette)
, m_name(name) {
}
virtual ~PaletteResource() { }
virtual raster::Palette* palette() { return m_palette; }
virtual const std::string& name() const OVERRIDE { return m_name; }
private:
raster::Palette* m_palette;
std::string m_name;
};
} // namespace app
#endif

View File

@ -0,0 +1,59 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/res/palettes_loader_delegate.h"
#include "app/file_system.h"
#include "app/res/palette_resource.h"
#include "app/resource_finder.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/scoped_value.h"
#include "raster/palette.h"
namespace app {
std::string PalettesLoaderDelegate::resourcesLocation() const
{
std::string path;
ResourceFinder rf;
rf.includeDataDir("palettes");
while (rf.next()) {
if (base::is_directory(rf.filename())) {
path = rf.filename();
break;
}
}
return base::fix_path_separators(path);
}
Resource* PalettesLoaderDelegate::loadResource(const std::string& filename)
{
raster::Palette* palette = raster::Palette::load(filename.c_str());
if (!palette)
return NULL;
return new PaletteResource(palette, base::get_file_title(filename));
}
} // namespace app

View File

@ -0,0 +1,37 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_RES_PALETTES_LOADER_DELEGATE_H_INCLUDED
#define APP_RES_PALETTES_LOADER_DELEGATE_H_INCLUDED
#pragma once
#include "app/res/resources_loader_delegate.h"
#include "base/compiler_specific.h"
namespace app {
class PalettesLoaderDelegate : public ResourcesLoaderDelegate {
public:
// ResourcesLoaderDelegate impl
virtual std::string resourcesLocation() const OVERRIDE;
virtual Resource* loadResource(const std::string& filename) OVERRIDE;
};
} // namespace app
#endif

33
src/app/res/resource.h Normal file
View File

@ -0,0 +1,33 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_RES_RESOURCE_H_INCLUDED
#define APP_RES_RESOURCE_H_INCLUDED
#pragma once
namespace app {
class Resource {
public:
virtual ~Resource() { }
virtual const std::string& name() const = 0;
};
} // namespace app
#endif

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,78 +20,63 @@
#include "config.h"
#endif
#include "app/palettes_loader.h"
#include "app/res/resources_loader.h"
#include "app/file_system.h"
#include "app/res/resources_loader_delegate.h"
#include "app/resource_finder.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/scoped_value.h"
#include "raster/palette.h"
namespace app {
PalettesLoader::PalettesLoader()
: m_done(false)
ResourcesLoader::ResourcesLoader(ResourcesLoaderDelegate* delegate)
: m_delegate(delegate)
, m_done(false)
, m_cancel(false)
, m_thread(Bind<void>(&PalettesLoader::threadLoadPalettes, this))
, m_thread(Bind<void>(&ResourcesLoader::threadLoadResources, this))
{
PRINTF("PalettesLoader::PalettesLoader()\n");
PRINTF("ResourcesLoader::ResourcesLoader()\n");
}
PalettesLoader::~PalettesLoader()
ResourcesLoader::~ResourcesLoader()
{
m_thread.join();
PRINTF("PalettesLoader::~PalettesLoader()\n");
PRINTF("ResourcesLoader::~ResourcesLoader()\n");
}
void PalettesLoader::cancel()
void ResourcesLoader::cancel()
{
m_cancel = true;
}
bool PalettesLoader::done()
bool ResourcesLoader::done()
{
return m_done;
}
bool PalettesLoader::next(base::UniquePtr<raster::Palette>& palette, std::string& name)
bool ResourcesLoader::next(base::UniquePtr<Resource>& resource)
{
Item item;
if (m_queue.try_pop(item)) {
palette.reset(item.palette);
name = item.name;
Resource* rawResource;
if (m_queue.try_pop(rawResource)) {
resource.reset(rawResource);
return true;
}
else
return false;
}
// static
std::string PalettesLoader::palettesLocation()
void ResourcesLoader::threadLoadResources()
{
std::string path;
ResourceFinder rf;
rf.includeDataDir("palettes");
while (rf.next()) {
if (base::is_directory(rf.filename())) {
path = rf.filename();
break;
}
}
return base::fix_path_separators(path);
}
void PalettesLoader::threadLoadPalettes()
{
PRINTF("threadLoadPalettes()\n");
PRINTF("threadLoadResources()\n");
base::ScopedValue<bool> scoped(m_done, false, true);
std::string path = palettesLocation();
PRINTF("Loading palettes from %s...\n", path.c_str());
std::string path = m_delegate->resourcesLocation();
PRINTF("Loading resources from %s...\n", path.c_str());
if (path.empty())
return;
@ -108,12 +93,9 @@ void PalettesLoader::threadLoadPalettes()
if (m_cancel)
break;
raster::Palette* palette =
raster::Palette::load((*it)->getFileName().c_str());
if (palette) {
m_queue.push(Item(palette, base::get_file_title((*it)->getFileName())));
}
Resource* resource = m_delegate->loadResource((*it)->getFileName());
if (resource)
m_queue.push(resource);
}
}

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,50 +16,36 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_PALETTES_LOADER_H_INCLUDED
#define APP_PALETTES_LOADER_H_INCLUDED
#ifndef APP_RES_RESOURCES_LOADER_H_INCLUDED
#define APP_RES_RESOURCES_LOADER_H_INCLUDED
#pragma once
#include "base/concurrent_queue.h"
#include "base/thread.h"
#include "base/unique_ptr.h"
#include <string>
namespace raster {
class Palette;
}
namespace app {
class PalettesLoader {
class Resource;
class ResourcesLoaderDelegate;
class ResourcesLoader {
public:
PalettesLoader();
~PalettesLoader();
ResourcesLoader(ResourcesLoaderDelegate* delegate);
~ResourcesLoader();
void cancel();
bool done();
bool isDone() const { return m_done; }
bool next(base::UniquePtr<raster::Palette>& palette, std::string& name);
static std::string palettesLocation();
bool next(base::UniquePtr<Resource>& resource);
private:
void threadLoadPalettes();
void threadLoadResources();
struct Item {
raster::Palette* palette;
std::string name;
Item() : palette(NULL) {
}
Item(raster::Palette* palette, const std::string& name)
: palette(palette), name(name) {
}
};
typedef base::concurrent_queue<Item> Queue;
typedef base::concurrent_queue<Resource*> Queue;
ResourcesLoaderDelegate* m_delegate;
bool m_done;
bool m_cancel;
Queue m_queue;

View File

@ -0,0 +1,38 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_RES_RESOURCES_LOADER_DELEGATE_H_INCLUDED
#define APP_RES_RESOURCES_LOADER_DELEGATE_H_INCLUDED
#pragma once
#include <string>
namespace app {
class Resource;
class ResourcesLoaderDelegate {
public:
virtual ~ResourcesLoaderDelegate() { }
virtual std::string resourcesLocation() const = 0;
virtual Resource* loadResource(const std::string& filename) = 0;
};
} // namespace app
#endif

View File

@ -20,14 +20,13 @@
#include "config.h"
#endif
#include <allegro.h>
#include <cstdio>
#include "app/resource_finder.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/string.h"
#include <cstdio>
namespace app {
ResourceFinder::ResourceFinder()

View File

@ -25,6 +25,7 @@ namespace app {
enum FreehandAlgorithm {
kDefaultFreehandAlgorithm,
kPixelPerfectFreehandAlgorithm,
kDotsFreehandAlgorithm,
};
} // namespace app

View File

@ -52,6 +52,7 @@ namespace app {
virtual ~ISettings() { }
// General settings
virtual bool getZoomWithScrollWheel() = 0;
virtual bool getShowSpriteEditorScrollbars() = 0;
virtual bool getGrabAlpha() = 0;
virtual app::Color getFgColor() = 0;
@ -59,6 +60,7 @@ namespace app {
virtual tools::Tool* getCurrentTool() = 0;
virtual app::ColorSwatches* getColorSwatches() = 0;
virtual void setZoomWithScrollWheel(bool state) = 0;
virtual void setShowSpriteEditorScrollbars(bool state) = 0;
virtual void setGrabAlpha(bool state) = 0;
virtual void setFgColor(const app::Color& color) = 0;

View File

@ -212,6 +212,7 @@ UISettingsImpl::UISettingsImpl()
, m_globalDocumentSettings(new UIDocumentSettingsImpl)
, m_colorSwatches(NULL)
, m_selectionSettings(new UISelectionSettingsImpl)
, m_zoomWithScrollWheel(get_config_bool("Options", "ZoomWithMouseWheel", true))
, m_showSpriteEditorScrollbars(get_config_bool("Options", "ShowScrollbars", true))
, m_grabAlpha(get_config_bool("Options", "GrabAlpha", false))
{
@ -224,6 +225,7 @@ UISettingsImpl::UISettingsImpl()
UISettingsImpl::~UISettingsImpl()
{
set_config_bool("Options", "ZoomWithMouseWheel", m_zoomWithScrollWheel);
set_config_bool("Options", "ShowScrollbars", m_showSpriteEditorScrollbars);
set_config_bool("Options", "GrabAlpha", m_grabAlpha);
@ -244,6 +246,11 @@ UISettingsImpl::~UISettingsImpl()
//////////////////////////////////////////////////////////////////////
// General settings
bool UISettingsImpl::getZoomWithScrollWheel()
{
return m_zoomWithScrollWheel;
}
bool UISettingsImpl::getShowSpriteEditorScrollbars()
{
return m_showSpriteEditorScrollbars;
@ -277,6 +284,11 @@ app::ColorSwatches* UISettingsImpl::getColorSwatches()
return m_colorSwatches;
}
void UISettingsImpl::setZoomWithScrollWheel(bool state)
{
m_zoomWithScrollWheel = state;
}
void UISettingsImpl::setShowSpriteEditorScrollbars(bool state)
{
m_showSpriteEditorScrollbars = state;
@ -760,13 +772,19 @@ public:
tools::ToolBox* toolBox = App::instance()->getToolBox();
for (int i=0; i<2; ++i) {
if (algorithm == kPixelPerfectFreehandAlgorithm) {
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsPixelPerfect));
m_tool->setTracePolicy(i, tools::TracePolicyLast);
}
else {
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsLines));
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
switch (algorithm) {
case kDefaultFreehandAlgorithm:
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsLines));
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
break;
case kPixelPerfectFreehandAlgorithm:
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::AsPixelPerfect));
m_tool->setTracePolicy(i, tools::TracePolicyLast);
break;
case kDotsFreehandAlgorithm:
m_tool->setIntertwine(i, toolBox->getIntertwinerById(tools::WellKnownIntertwiners::None));
m_tool->setTracePolicy(i, tools::TracePolicyAccumulate);
break;
}
}
}

View File

@ -41,6 +41,7 @@ namespace app {
~UISettingsImpl();
// ISettings implementation
bool getZoomWithScrollWheel() OVERRIDE;
bool getShowSpriteEditorScrollbars() OVERRIDE;
bool getGrabAlpha() OVERRIDE;
app::Color getFgColor() OVERRIDE;
@ -48,6 +49,7 @@ namespace app {
tools::Tool* getCurrentTool() OVERRIDE;
app::ColorSwatches* getColorSwatches() OVERRIDE;
void setZoomWithScrollWheel(bool state) OVERRIDE;
void setShowSpriteEditorScrollbars(bool state) OVERRIDE;
void setGrabAlpha(bool state) OVERRIDE;
void setFgColor(const app::Color& color) OVERRIDE;
@ -76,6 +78,7 @@ namespace app {
app::ColorSwatches* m_colorSwatches;
std::vector<app::ColorSwatches*> m_colorSwatchesStore;
base::UniquePtr<ISelectionSettings> m_selectionSettings;
bool m_zoomWithScrollWheel;
bool m_showSpriteEditorScrollbars;
bool m_grabAlpha;
};

View File

@ -30,14 +30,13 @@
#include "base/bind.h"
#include "base/scoped_lock.h"
#include "base/thread.h"
#include "raster/conversion_alleg.h"
#include "raster/conversion_she.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "raster/primitives.h"
#include "raster/rotate.h"
#include "raster/sprite.h"
#include <allegro.h>
#include "she/system.h"
#define MAX_THUMBNAIL_SIZE 128
@ -72,11 +71,11 @@ private:
// Post load
fop_post_load(m_fop);
// Convert the loaded document into the Allegro bitmap "m_thumbnail".
// Convert the loaded document into the she::Surface.
const Sprite* sprite = (m_fop->document && m_fop->document->getSprite()) ? m_fop->document->getSprite():
NULL;
if (!fop_is_stop(m_fop) && sprite) {
// The palette to convert the Image to a BITMAP
// The palette to convert the Image
m_palette.reset(new Palette(*sprite->getPalette(FrameNumber(0))));
// Render the 'sprite' in one plain 'image'
@ -107,9 +106,13 @@ private:
// Set the thumbnail of the file-item.
if (m_thumbnail) {
BITMAP* bmp = create_bitmap_ex(16, m_thumbnail->getWidth(), m_thumbnail->getHeight());
convert_image_to_allegro(m_thumbnail, bmp, 0, 0, m_palette);
m_fileitem->setThumbnail(bmp);
she::Surface* thumbnail = she::instance()->createRgbaSurface(
m_thumbnail->getWidth(),
m_thumbnail->getHeight());
convert_image_to_surface(m_thumbnail, thumbnail, 0, 0, m_palette);
m_fileitem->setThumbnail(thumbnail);
}
}
catch (const std::exception& e) {

View File

@ -58,6 +58,9 @@ namespace app {
// Returns true if this ink moves cels
virtual bool isCelMovement() const { return false; }
// Returns true if this ink is used to mark slices
virtual bool isSlice() const { return false; }
// It is called when the tool-loop start (generally when the user
// presses a mouse button over a sprite editor)
virtual void prepareInk(ToolLoop* loop) { }

View File

@ -135,34 +135,27 @@ public:
class ZoomInk : public Ink {
public:
bool isZoom() const { return true; }
void prepareInk(ToolLoop* loop)
{
// Do nothing
}
void inkHline(int x1, int y, int x2, ToolLoop* loop)
{
// Do nothing
}
void prepareInk(ToolLoop* loop) { }
void inkHline(int x1, int y, int x2, ToolLoop* loop) { }
};
class MoveInk : public Ink {
public:
bool isCelMovement() const { return true; }
void prepareInk(ToolLoop* loop) { }
void inkHline(int x1, int y, int x2, ToolLoop* loop) { }
};
void prepareInk(ToolLoop* loop)
{
// Do nothing
}
void inkHline(int x1, int y, int x2, ToolLoop* loop)
{
// Do nothing
class SliceInk : public Ink {
public:
bool isSlice() const { return true; }
void prepareInk(ToolLoop* loop) { }
void inkHline(int x1, int y, int x2, ToolLoop* loop) {
// TODO show the selection-preview with a XOR color or something like that
draw_hline(loop->getDstImage(), x1, y, x2, loop->getPrimaryColor());
}
};

View File

@ -68,6 +68,7 @@ const char* WellKnownInks::PickBg = "pick_bg";
const char* WellKnownInks::Zoom = "zoom";
const char* WellKnownInks::Scroll = "scroll";
const char* WellKnownInks::Move = "move";
const char* WellKnownInks::Slice = "slice";
const char* WellKnownInks::Blur = "blur";
const char* WellKnownInks::Jumble = "jumble";
@ -95,9 +96,10 @@ ToolBox::ToolBox()
m_inks[WellKnownInks::ReplaceBgWithFg] = new EraserInk(EraserInk::ReplaceBgWithFg);
m_inks[WellKnownInks::PickFg] = new PickInk(PickInk::Fg);
m_inks[WellKnownInks::PickBg] = new PickInk(PickInk::Bg);
m_inks[WellKnownInks::Zoom] = new ZoomInk();
m_inks[WellKnownInks::Zoom] = new ZoomInk();
m_inks[WellKnownInks::Scroll] = new ScrollInk();
m_inks[WellKnownInks::Move] = new MoveInk();
m_inks[WellKnownInks::Slice] = new SliceInk();
m_inks[WellKnownInks::Blur] = new BlurInk();
m_inks[WellKnownInks::Jumble] = new JumbleInk();

View File

@ -52,6 +52,7 @@ namespace app {
extern const char* Zoom;
extern const char* Scroll;
extern const char* Move;
extern const char* Slice;
extern const char* Blur;
extern const char* Jumble;
};

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,25 +20,25 @@
#include "config.h"
#endif
#include <allegro.h>
#include <cstring>
#include "app/ui/color_bar.h"
#include "app/color.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/ini_file.h"
#include "app/modules/gui.h"
#include "app/ui/color_bar.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "she/surface.h"
#include "ui/graphics.h"
#include "ui/menu.h"
#include "ui/paint_event.h"
#include "ui/menu.h"
#include <cstring>
namespace app {
@ -51,10 +51,10 @@ using namespace ui;
ColorBar::ScrollableView::ScrollableView()
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
int l = theme->get_part(PART_EDITOR_SELECTED_W)->w;
int t = theme->get_part(PART_EDITOR_SELECTED_N)->h;
int r = theme->get_part(PART_EDITOR_SELECTED_E)->w;
int b = theme->get_part(PART_EDITOR_SELECTED_S)->h;
int l = theme->get_part(PART_EDITOR_SELECTED_W)->width();
int t = theme->get_part(PART_EDITOR_SELECTED_N)->height();
int r = theme->get_part(PART_EDITOR_SELECTED_E)->width();
int b = theme->get_part(PART_EDITOR_SELECTED_S)->height();
setBorder(gfx::Border(l, t, r, b));
}
@ -67,7 +67,7 @@ void ColorBar::ScrollableView::onPaint(ui::PaintEvent& ev)
getClientBounds(),
hasFocus() ? PART_EDITOR_SELECTED_NW:
PART_EDITOR_NORMAL_NW,
ColorNone);
gfx::ColorNone);
}
//////////////////////////////////////////////////////////////////////

View File

@ -20,8 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include "app/app.h"
#include "app/color.h"
#include "app/color_picker.h"
@ -181,8 +179,8 @@ void ColorButton::onPaint(PaintEvent& ev)
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
gfx::Rect rc = getClientBounds();
ui::Color bg = getBgColor();
if (is_transparent(bg))
gfx::Color bg = getBgColor();
if (gfx::is_transparent(bg))
bg = theme->getColor(ThemeColor::Face);
g->fillRect(bg, rc);
@ -207,13 +205,13 @@ void ColorButton::onPaint(PaintEvent& ev)
setTextQuiet(str.c_str());
ui::Color textcolor = ui::rgba(255, 255, 255);
gfx::Color textcolor = gfx::rgba(255, 255, 255);
if (color.isValid())
textcolor = color_utils::blackandwhite_neg(ui::rgba(color.getRed(), color.getGreen(), color.getBlue()));
textcolor = color_utils::blackandwhite_neg(gfx::rgba(color.getRed(), color.getGreen(), color.getBlue()));
gfx::Rect text;
getTextIconInfo(NULL, &text);
g->drawString(getText(), textcolor, ColorNone, false, text.getOrigin());
g->drawUIString(getText(), textcolor, gfx::ColorNone, text.getOrigin());
}
void ColorButton::onClick(Event& ev)

View File

@ -20,7 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include <vector>
#include "app/app.h"
@ -240,10 +239,10 @@ void ColorSelector::onFixWarningClick(ui::Event& ev)
{
try {
Palette* newPalette = get_current_palette(); // System current pal
color_t newColor = rgba(
color_t newColor = raster::rgba(
m_color.getRed(),
m_color.getGreen(),
m_color.getBlue());
m_color.getBlue(), 255);
int index = newPalette->findExactMatch(
m_color.getRed(),
m_color.getGreen(),

View File

@ -20,8 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include "app/color_utils.h"
#include "app/ui/color_sliders.h"
#include "base/bind.h"
@ -54,17 +52,17 @@ namespace {
}
void paint(Slider* slider, Graphics* g, const gfx::Rect& rc) {
ui::Color color = ui::ColorNone;
gfx::Color color = gfx::ColorNone;
for (int x=0; x < rc.w; ++x) {
switch (m_channel) {
case ColorSliders::Red:
color = ui::rgba(255 * x / (rc.w-1), m_color.getGreen(), m_color.getBlue());
color = gfx::rgba(255 * x / (rc.w-1), m_color.getGreen(), m_color.getBlue());
break;
case ColorSliders::Green:
color = ui::rgba(m_color.getRed(), 255 * x / (rc.w-1), m_color.getBlue());
color = gfx::rgba(m_color.getRed(), 255 * x / (rc.w-1), m_color.getBlue());
break;
case ColorSliders::Blue:
color = ui::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / (rc.w-1));
color = gfx::rgba(m_color.getRed(), m_color.getGreen(), 255 * x / (rc.w-1));
break;
case ColorSliders::Hue:
color = color_utils::color_for_ui(app::Color::fromHsv(360 * x / (rc.w-1), m_color.getSaturation(), m_color.getValue()));
@ -85,7 +83,6 @@ namespace {
private:
ColorSliders::Channel m_channel;
BITMAP* m_cachedBg;
app::Color m_color;
};

View File

@ -40,9 +40,12 @@
#include "base/bind.h"
#include "base/unique_ptr.h"
#include "raster/brush.h"
#include "raster/conversion_alleg.h"
#include "raster/conversion_she.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "she/scoped_surface_lock.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/button.h"
#include "ui/combobox.h"
#include "ui/int_entry.h"
@ -53,8 +56,6 @@
#include "ui/theme.h"
#include "ui/tooltips.h"
#include <allegro.h>
namespace app {
using namespace app::skin;
@ -63,8 +64,7 @@ using namespace ui;
using namespace tools;
class ContextBar::BrushTypeField : public Button
, public IButtonIcon
{
, public IButtonIcon {
public:
BrushTypeField()
: Button("")
@ -73,14 +73,16 @@ public:
setup_mini_look(this);
setIconInterface(this);
m_bitmap = create_bitmap_ex(32, 8, 8);
clear(m_bitmap);
m_bitmap = she::instance()->createRgbaSurface(8, 8);
she::ScopedSurfaceLock lock(m_bitmap);
lock->clear();
}
~BrushTypeField() {
closePopup();
setIconInterface(NULL);
destroy_bitmap(m_bitmap);
m_bitmap->dispose();
}
void setBrushSettings(IBrushSettings* brushSettings) {
@ -97,10 +99,10 @@ public:
Image* image = brush->get_image();
if (m_bitmap)
destroy_bitmap(m_bitmap);
m_bitmap = create_bitmap_ex(32, image->getWidth(), image->getHeight());
clear(m_bitmap);
convert_image_to_allegro(image, m_bitmap, 0, 0, palette);
m_bitmap->dispose();
m_bitmap = she::instance()->createRgbaSurface(image->getWidth(), image->getHeight());
convert_image_to_surface(image, m_bitmap, 0, 0, palette);
invalidate();
}
@ -113,22 +115,22 @@ public:
}
int getWidth() OVERRIDE {
return m_bitmap->w;
return m_bitmap->width();
}
int getHeight() OVERRIDE {
return m_bitmap->h;
return m_bitmap->height();
}
BITMAP* getNormalIcon() OVERRIDE {
she::Surface* getNormalIcon() OVERRIDE {
return m_bitmap;
}
BITMAP* getSelectedIcon() OVERRIDE {
she::Surface* getSelectedIcon() OVERRIDE {
return m_bitmap;
}
BITMAP* getDisabledIcon() OVERRIDE {
she::Surface* getDisabledIcon() OVERRIDE {
return m_bitmap;
}
@ -170,7 +172,7 @@ private:
PART_BRUSH_LINE);
m_brushTypeButton->ItemChange.connect(&BrushTypeField::onBrushTypeChange, this);
m_brushTypeButton->setTransparent(true);
m_brushTypeButton->setBgColor(ui::ColorNone);
m_brushTypeButton->setBgColor(gfx::ColorNone);
m_popupWindow->addChild(m_brushTypeButton);
m_popupWindow->openWindow();
@ -196,7 +198,7 @@ private:
setBrushSettings(brushSettings);
}
BITMAP* m_bitmap;
she::Surface* m_bitmap;
BrushType m_brushType;
PopupWindow* m_popupWindow;
ButtonSet* m_brushTypeButton;
@ -440,26 +442,144 @@ private:
bool m_lockChange;
};
class ContextBar::FreehandAlgorithmField : public CheckBox
class ContextBar::FreehandAlgorithmField : public Button
, public IButtonIcon
{
public:
FreehandAlgorithmField() : CheckBox("Pixel-perfect") {
setup_mini_font(this);
FreehandAlgorithmField()
: Button("")
, m_popupWindow(NULL)
, m_tooltipManager(NULL) {
setup_mini_look(this);
setIconInterface(this);
}
~FreehandAlgorithmField() {
closePopup();
setIconInterface(NULL);
}
void setupTooltips(TooltipManager* tooltipManager) {
m_tooltipManager = tooltipManager;
}
void setFreehandAlgorithm(FreehandAlgorithm algo) {
int part = PART_FREEHAND_ALGO_DEFAULT;
m_freehandAlgo = algo;
switch (m_freehandAlgo) {
case kDefaultFreehandAlgorithm:
part = PART_FREEHAND_ALGO_DEFAULT;
break;
case kPixelPerfectFreehandAlgorithm:
part = PART_FREEHAND_ALGO_PIXEL_PERFECT;
break;
case kDotsFreehandAlgorithm:
part = PART_FREEHAND_ALGO_DOTS;
break;
}
m_bitmap = static_cast<SkinTheme*>(getTheme())->get_part(part);
invalidate();
}
// IButtonIcon implementation
void destroy() OVERRIDE {
// Do nothing, BrushTypeField is added as a widget in the
// ContextBar, so it will be destroyed together with the
// ContextBar.
}
int getWidth() OVERRIDE {
return m_bitmap->width();
}
int getHeight() OVERRIDE {
return m_bitmap->height();
}
she::Surface* getNormalIcon() OVERRIDE {
return m_bitmap;
}
she::Surface* getSelectedIcon() OVERRIDE {
return m_bitmap;
}
she::Surface* getDisabledIcon() OVERRIDE {
return m_bitmap;
}
int getIconAlign() OVERRIDE {
return JI_CENTER | JI_MIDDLE;
}
protected:
void onClick(Event& ev) OVERRIDE {
CheckBox::onClick(ev);
Button::onClick(ev);
if (!m_popupWindow || !m_popupWindow->isVisible())
openPopup();
else
closePopup();
}
void onPreferredSize(PreferredSizeEvent& ev) {
ev.setPreferredSize(Size(16*jguiscale(),
16*jguiscale()));
}
private:
void openPopup() {
Border border = Border(2, 2, 2, 3)*jguiscale();
Rect rc = getBounds();
rc.y += rc.h;
rc.w *= 3;
m_popupWindow = new PopupWindow("", PopupWindow::kCloseOnClickInOtherWindow);
m_popupWindow->setAutoRemap(false);
m_popupWindow->setBorder(border);
m_popupWindow->setBounds(rc + border);
Region rgn(m_popupWindow->getBounds().createUnion(getBounds()));
m_popupWindow->setHotRegion(rgn);
m_freehandAlgoButton = new ButtonSet(3, 1, m_freehandAlgo,
PART_FREEHAND_ALGO_DEFAULT,
PART_FREEHAND_ALGO_PIXEL_PERFECT,
PART_FREEHAND_ALGO_DOTS);
m_freehandAlgoButton->ItemChange.connect(&FreehandAlgorithmField::onFreehandAlgoChange, this);
m_freehandAlgoButton->setTransparent(true);
m_freehandAlgoButton->setBgColor(gfx::ColorNone);
m_tooltipManager->addTooltipFor(m_freehandAlgoButton->getButtonAt(0), "Normal trace", JI_TOP);
m_tooltipManager->addTooltipFor(m_freehandAlgoButton->getButtonAt(1), "Pixel-perfect trace", JI_TOP);
m_tooltipManager->addTooltipFor(m_freehandAlgoButton->getButtonAt(2), "Dots", JI_TOP);
m_popupWindow->addChild(m_freehandAlgoButton);
m_popupWindow->openWindow();
}
void closePopup() {
if (m_popupWindow) {
m_popupWindow->closeWindow(NULL);
delete m_popupWindow;
m_popupWindow = NULL;
m_freehandAlgoButton = NULL;
}
}
void onFreehandAlgoChange() {
setFreehandAlgorithm(
(FreehandAlgorithm)m_freehandAlgoButton->getSelectedItem());
ISettings* settings = UIContext::instance()->getSettings();
Tool* currentTool = settings->getCurrentTool();
settings->getToolSettings(currentTool)
->setFreehandAlgorithm(isSelected() ?
kPixelPerfectFreehandAlgorithm:
kDefaultFreehandAlgorithm);
releaseFocus(
);
->setFreehandAlgorithm(m_freehandAlgo);
}
she::Surface* m_bitmap;
FreehandAlgorithm m_freehandAlgo;
PopupWindow* m_popupWindow;
ButtonSet* m_freehandAlgoButton;
TooltipManager* m_tooltipManager;
};
class ContextBar::SelectionModeField : public ButtonSet
@ -474,8 +594,7 @@ public:
->selection()->getSelectionMode());
}
void setupTooltips(TooltipManager* tooltipManager)
{
void setupTooltips(TooltipManager* tooltipManager) {
tooltipManager->addTooltipFor(getButtonAt(0), "Replace selection", JI_BOTTOM);
tooltipManager->addTooltipFor(getButtonAt(1), "Add to selection", JI_BOTTOM);
tooltipManager->addTooltipFor(getButtonAt(2), "Subtract from selection", JI_BOTTOM);
@ -572,11 +691,14 @@ ContextBar::ContextBar()
m_sprayBox->addChild(m_sprayWidth = new SprayWidthField());
m_sprayBox->addChild(m_spraySpeed = new SpraySpeedField());
Label* freehandLabel;
addChild(m_freehandBox = new HBox());
m_freehandBox->addChild(freehandLabel = new Label("Freehand:"));
m_freehandBox->addChild(m_freehandAlgo = new FreehandAlgorithmField());
setup_mini_font(m_toleranceLabel);
setup_mini_font(m_opacityLabel);
setup_mini_font(freehandLabel);
TooltipManager* tooltipManager = new TooltipManager();
addChild(tooltipManager);
@ -597,6 +719,7 @@ ContextBar::ContextBar()
"from the composition of all sprite layers.", JI_LEFT | JI_TOP);
m_selectionMode->setupTooltips(tooltipManager);
m_dropPixels->setupTooltips(tooltipManager);
m_freehandAlgo->setupTooltips(tooltipManager);
App::instance()->BrushSizeAfterChange.connect(&ContextBar::onBrushSizeChange, this);
App::instance()->BrushAngleAfterChange.connect(&ContextBar::onBrushAngleChange, this);
@ -681,7 +804,7 @@ void ContextBar::updateFromTool(tools::Tool* tool)
m_inkOpacity->setTextf("%d", toolSettings->getOpacity());
m_grabAlpha->setSelected(settings->getGrabAlpha());
m_freehandAlgo->setSelected(toolSettings->getFreehandAlgorithm() == kPixelPerfectFreehandAlgorithm);
m_freehandAlgo->setFreehandAlgorithm(toolSettings->getFreehandAlgorithm());
m_sprayWidth->setValue(toolSettings->getSprayWidth());
m_spraySpeed->setValue(toolSettings->getSpraySpeed());

View File

@ -23,6 +23,10 @@
#include "app/ui/document_view.h"
#include "app/app.h"
#include "app/document_event.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/editor/editor.h"
#include "app/ui/editor/editor_customization_delegate.h"
#include "app/ui/editor/editor_view.h"
@ -30,9 +34,6 @@
#include "app/ui/mini_editor.h"
#include "app/ui/workspace.h"
#include "base/path.h"
#include "app/document_event.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "ui/accelerator.h"
@ -74,6 +75,8 @@ public:
void onFrameChanged(Editor* editor) OVERRIDE {
App::instance()->getMainWindow()->getMiniEditor()->updateUsingEditor(this);
set_current_palette(editor->getSprite()->getPalette(editor->getFrame()), true);
}
void onLayerChanged(Editor* editor) OVERRIDE {

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,6 +20,8 @@
#include "config.h"
#endif
#include "app/ui/editor/editor.h"
#include "app/app.h"
#include "app/color.h"
#include "app/color_utils.h"
@ -28,10 +30,10 @@
#include "app/settings/settings.h"
#include "app/tools/ink.h"
#include "app/tools/tool.h"
#include "app/ui/editor/editor.h"
#include "app/ui_context.h"
#include "app/util/boundary.h"
#include "base/memory.h"
#include "raster/algo.h"
#include "raster/brush.h"
#include "raster/image.h"
#include "raster/layer.h"
@ -42,7 +44,6 @@
#include "ui/widget.h"
#include <algorithm>
#include <allegro.h>
#ifdef WIN32
#undef max
@ -53,18 +54,10 @@ namespace app {
using namespace ui;
/**********************************************************************/
/* drawing-cursor routines */
/**********************************************************************/
/**
* Returns true if the cursor of the editor needs subpixel movement.
*/
// Returns true if the cursor of the editor needs subpixel movement.
#define IS_SUBPIXEL(editor) ((editor)->m_zoom >= 2)
/**
* Maximum quantity of colors to save pixels overlapped by the cursor.
*/
// Maximum quantity of colors to save pixels overlapped by the cursor.
#define MAX_SAVED 4096
static struct {
@ -72,19 +65,19 @@ static struct {
int brush_size;
int brush_angle;
int nseg;
BoundSeg *seg;
BoundSeg* seg;
} cursor_bound = { 0, 0, 0, 0, NULL };
enum {
CURSOR_BRUSH = 1, // New cursor style (with preview)
CURSOR_CROSS_ONE = 2, // Old cursor style (deprecated)
CURSOR_BOUNDS = 4 // Old cursor boundaries (deprecated)
CURSOR_THINCROSS = 1,
CURSOR_THICKCROSS = 2,
CURSOR_BRUSHBOUNDS = 4
};
static int cursor_type = CURSOR_BRUSH;
static int cursor_type = CURSOR_THINCROSS;
static int cursor_negative;
static int saved_pixel[MAX_SAVED];
static gfx::Color saved_pixel[MAX_SAVED];
static int saved_pixel_n;
// These clipping regions are shared between all editors, so we cannot
@ -94,13 +87,13 @@ static gfx::Region old_clipping_region;
static void generate_cursor_boundaries();
static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color));
static void editor_cursor_cross(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color));
static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (*pixel)(BITMAP *bmp, int x, int y, int color));
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor, int x, int y, gfx::Color color, Editor::PixelDelegate pixel);
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor, int x, int y, gfx::Color color, int thickness, Editor::PixelDelegate pixel);
static void trace_brush_bounds(ui::Graphics* g, Editor* editor, int x, int y, gfx::Color color, Editor::PixelDelegate pixel);
static void savepixel(BITMAP *bmp, int x, int y, int color);
static void drawpixel(BITMAP *bmp, int x, int y, int color);
static void cleanpixel(BITMAP *bmp, int x, int y, int color);
static void savepixel(ui::Graphics* g, int x, int y, gfx::Color color);
static void drawpixel(ui::Graphics* g, int x, int y, gfx::Color color);
static void clearpixel(ui::Graphics* g, int x, int y, gfx::Color color);
static color_t get_brush_color(Sprite* sprite, Layer* layer);
@ -109,27 +102,17 @@ static color_t get_brush_color(Sprite* sprite, Layer* layer);
//////////////////////////////////////////////////////////////////////
static app::Color cursor_color;
static int _cursor_color;
static bool _cursor_mask;
static gfx::Color ui_cursor_color;
static bool is_cursor_mask;
static void update_cursor_color()
{
if (ji_screen)
_cursor_color = color_utils::color_for_allegro(cursor_color, bitmap_color_depth(ji_screen));
ui_cursor_color = color_utils::color_for_ui(cursor_color);
else
_cursor_color = 0;
ui_cursor_color = 0;
_cursor_mask = (cursor_color.getType() == app::Color::MaskType);
}
int Editor::get_raw_cursor_color()
{
return _cursor_color;
}
bool Editor::is_cursor_mask()
{
return _cursor_mask;
is_cursor_mask = (cursor_color.getType() == app::Color::MaskType);
}
app::Color Editor::get_cursor_color()
@ -228,19 +211,12 @@ void Editor::editor_cursor_exit()
current_brush = NULL;
}
/**
* Draws the brush cursor inside the specified editor.
*
* @warning You should clean the cursor before to use
* this routine with other editor.
*
* @param widget The editor widget
* @param x Absolute position in X axis of the mouse.
* @param y Absolute position in Y axis of the mouse.
*
* @see editor_clean_cursor
*/
void Editor::editor_draw_cursor(int x, int y, bool refresh)
// Draws the brush cursor inside the specified editor.
// Warning: You should clean the cursor before to use
// this routine with other editor.
//
// Note: x and y params are absolute positions of the mouse.
void Editor::drawBrushPreview(int x, int y, bool refresh)
{
ASSERT(m_cursor_thick == 0);
ASSERT(m_sprite != NULL);
@ -248,15 +224,14 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
// Get drawable region
getDrawableRegion(clipping_region, kCutTopWindows);
/* get cursor color */
cursor_negative = is_cursor_mask();
int color = get_raw_cursor_color();
// Get cursor color
cursor_negative = is_cursor_mask;
/* cursor in the screen (view) */
// Cursor in the screen (view)
m_cursor_screen_x = x;
m_cursor_screen_y = y;
/* get cursor position in the editor */
// Get cursor position in the editor
screenToEditor(x, y, &x, &y);
// Get the current tool
@ -269,8 +244,9 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
color_t brush_color = get_brush_color(m_sprite, m_layer);
color_t mask_color = m_sprite->getTransparentColor();
if (current_tool->getInk(0)->isSelection()) {
cursor_type = CURSOR_CROSS_ONE;
if (current_tool->getInk(0)->isSelection() ||
current_tool->getInk(0)->isSlice()) {
cursor_type = CURSOR_THICKCROSS;
}
else if (
// Use cursor bounds for inks that are effects (eraser, blur, etc.)
@ -278,18 +254,18 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
// or when the brush color is transparent and we are not in the background layer
(m_layer && !m_layer->isBackground() &&
brush_color == mask_color)) {
cursor_type = CURSOR_BOUNDS;
cursor_type = CURSOR_BRUSHBOUNDS;
}
else {
cursor_type = CURSOR_BRUSH;
cursor_type = CURSOR_THINCROSS;
}
// For cursor type 'bounds' we have to generate cursor boundaries
if (cursor_type & CURSOR_BOUNDS)
if (cursor_type & CURSOR_BRUSHBOUNDS)
generate_cursor_boundaries();
// draw pixel/brush preview
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
// Draw pixel/brush preview
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
IToolSettings* tool_settings = UIContext::instance()
->getSettings()
->getToolSettings(current_tool);
@ -323,18 +299,17 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
// Save area and draw the cursor
if (refresh) {
acquire_bitmap(ji_screen);
ji_screen->clip = false;
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, color, savepixel);
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, color, drawpixel);
ji_screen->clip = true;
release_bitmap(ji_screen);
ScreenGraphics g;
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, ui_cursor_color, savepixel);
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, ui_cursor_color, drawpixel);
}
// cursor thickness
m_cursor_thick = 1; // get_thickness_for_cursor();
// Cursor thickness
m_cursor_thick = 1;
// cursor in the editor (model)
// Cursor in the editor (model)
m_cursor_editor_x = x;
m_cursor_editor_y = y;
@ -342,7 +317,7 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
old_clipping_region = clipping_region;
}
void Editor::editor_move_cursor(int x, int y, bool refresh)
void Editor::moveBrushPreview(int x, int y, bool refresh)
{
ASSERT(m_sprite != NULL);
@ -351,21 +326,22 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
int old_x = m_cursor_editor_x;
int old_y = m_cursor_editor_y;
editor_clean_cursor(false);
editor_draw_cursor(x, y, false);
clearBrushPreview(false);
drawBrushPreview(x, y, false);
int new_x = m_cursor_editor_x;
int new_y = m_cursor_editor_y;
if (refresh) {
/* restore points */
acquire_bitmap(ji_screen);
ji_screen->clip = FALSE;
forEachBrushPixel(old_screen_x, old_screen_y, old_x, old_y, 0, cleanpixel);
ji_screen->clip = TRUE;
release_bitmap(ji_screen);
// Restore pixels
{
ScreenGraphics g;
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
forEachBrushPixel(&g, old_screen_x, old_screen_y, old_x, old_y, gfx::ColorNone, clearpixel);
}
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
Brush* brush = editor_get_current_brush();
gfx::Rect brushBounds = brush->getBounds();
gfx::Rect rc1(old_x+brushBounds.x, old_y+brushBounds.y, brushBounds.w, brushBounds.h);
@ -374,14 +350,10 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
(m_sprite, gfx::Region(rc1.createUnion(rc2)));
}
/* save area and draw the cursor */
int color = get_raw_cursor_color();
acquire_bitmap(ji_screen);
ji_screen->clip = false;
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, color, savepixel);
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, color, drawpixel);
ji_screen->clip = true;
release_bitmap(ji_screen);
// Save area and draw the cursor
ScreenGraphics g;
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, ui_cursor_color, savepixel);
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, ui_cursor_color, drawpixel);
}
}
@ -389,16 +361,16 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
* Cleans the brush cursor from the specified editor.
*
* The mouse position is got from the last
* call to @c editor_draw_cursor. So you must
* call to @c drawBrushPreview. So you must
* to use this routine only if you called
* @c editor_draw_cursor before with the specified
* @c drawBrushPreview before with the specified
* editor @a widget.
*
* @param widget The editor widget
*
* @see editor_draw_cursor
* @see drawBrushPreview
*/
void Editor::editor_clean_cursor(bool refresh)
void Editor::clearBrushPreview(bool refresh)
{
int x, y;
@ -411,16 +383,15 @@ void Editor::editor_clean_cursor(bool refresh)
y = m_cursor_editor_y;
if (refresh) {
/* restore points */
acquire_bitmap(ji_screen);
ji_screen->clip = FALSE;
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, 0, cleanpixel);
ji_screen->clip = TRUE;
release_bitmap(ji_screen);
// Restore pixels
ScreenGraphics g;
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, gfx::ColorNone, clearpixel);
}
// clean pixel/brush preview
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
// Clean pixel/brush preview
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
Brush* brush = editor_get_current_brush();
gfx::Rect brushBounds = brush->getBounds();
@ -443,12 +414,10 @@ void Editor::editor_clean_cursor(bool refresh)
old_clipping_region.clear();
}
/**
* Returns true if the cursor to draw in the editor has subpixel
* movement (a little pixel of the screen that indicates where is the
* mouse inside the pixel of the sprite).
*/
bool Editor::editor_cursor_is_subpixel()
// Returns true if the cursor to draw in the editor has subpixel
// movement (a little pixel of the screen that indicates where is the
// mouse inside the pixel of the sprite).
bool Editor::doesBrushPreviewNeedSubpixel()
{
return IS_SUBPIXEL(this);
}
@ -497,33 +466,33 @@ static void generate_cursor_boundaries()
}
void Editor::forEachBrushPixel(
ui::Graphics* g,
int screen_x, int screen_y,
int sprite_x, int sprite_y, int color,
void (*pixel)(BITMAP *bmp, int x, int y, int color))
int sprite_x, int sprite_y,
gfx::Color color,
Editor::PixelDelegate pixelDelegate)
{
saved_pixel_n = 0;
if (cursor_type & CURSOR_BRUSH) {
editor_cursor_brush(this, screen_x, screen_y, color, 1, pixel);
}
if (cursor_type & CURSOR_THINCROSS)
trace_thincross_pixels(g, this, screen_x, screen_y, color, pixelDelegate);
if (cursor_type & CURSOR_CROSS_ONE) {
editor_cursor_cross(this, sprite_x, sprite_y, color, 1, pixel);
}
if (cursor_type & CURSOR_THICKCROSS)
trace_thickcross_pixels(g, this, sprite_x, sprite_y, color, 1, pixelDelegate);
if (cursor_type & CURSOR_BOUNDS) {
editor_cursor_bounds(this, sprite_x, sprite_y, color, pixel);
}
if (cursor_type & CURSOR_BRUSHBOUNDS)
trace_brush_bounds(g, this, sprite_x, sprite_y, color, pixelDelegate);
if (IS_SUBPIXEL(this)) {
(*pixel)(ji_screen, screen_x, screen_y, color);
pixelDelegate(g, screen_x, screen_y, color);
}
}
//////////////////////////////////////////////////////////////////////
// New cross
// New Thin Cross
static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color))
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor,
int x, int y, gfx::Color color, Editor::PixelDelegate pixelDelegate)
{
static int cursor_cross[7*7] = {
0, 0, 0, 1, 0, 0, 0,
@ -541,17 +510,17 @@ static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thi
if (cursor_cross[v*7+u]) {
xout = x-3+u;
yout = y-3+v;
(*pixel)(ji_screen, xout, yout, color);
pixelDelegate(g, xout, yout, color);
}
}
}
}
//////////////////////////////////////////////////////////////////////
// Old cross
// Old Thick Cross
static void editor_cursor_cross(Editor* editor, int x, int y, int color, int thickness,
void (*pixel)(BITMAP *bmp, int x, int y, int color))
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor,
int x, int y, gfx::Color color, int thickness, Editor::PixelDelegate pixelDelegate)
{
static int cursor_cross[6*6] = {
0, 0, 1, 1, 0, 0,
@ -577,19 +546,33 @@ static void editor_cursor_cross(Editor* editor, int x, int y, int color, int thi
v-((thickness>>1)<<zoom)-3:
v-((thickness>>1)<<zoom)-3+(thickness<<zoom));
(*pixel)(ji_screen, xout, yout, color);
pixelDelegate(g, xout, yout, color);
}
}
}
}
//////////////////////////////////////////////////////////////////////
// Cursor Bounds
// Current Brush Bounds
static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (*pixel) (BITMAP *bmp, int x, int y, int color))
struct Data {
ui::Graphics* g;
gfx::Color color;
Editor::PixelDelegate pixelDelegate;
};
static void algo_line_proxy(int x, int y, void* _data)
{
Data* data = (Data*)_data;
data->pixelDelegate(data->g, x, y, data->color);
}
static void trace_brush_bounds(ui::Graphics* g, Editor* editor,
int x, int y, gfx::Color color, Editor::PixelDelegate pixelDelegate)
{
Data data = { g, color, pixelDelegate };
int c, x1, y1, x2, y2;
BoundSeg *seg;
BoundSeg* seg;
for (c=0; c<cursor_bound.nseg; c++) {
seg = cursor_bound.seg+c;
@ -623,42 +606,41 @@ static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (
}
}
do_line(ji_screen, x1, y1, x2, y2, color, pixel);
raster::algo_line(x1, y1, x2, y2, (void*)&data, algo_line_proxy);
}
}
//////////////////////////////////////////////////////////////////////
// Helpers
static void savepixel(BITMAP *bmp, int x, int y, int color)
static void savepixel(ui::Graphics* g, int x, int y, gfx::Color color)
{
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y)))
saved_pixel[saved_pixel_n++] = getpixel(bmp, x, y);
saved_pixel[saved_pixel_n++] = g->getPixel(x, y);
}
static void drawpixel(BITMAP *bmp, int x, int y, int color)
static void drawpixel(ui::Graphics* graphics, int x, int y, gfx::Color color)
{
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y))) {
if (cursor_negative) {
int r, g, b, c = saved_pixel[saved_pixel_n++];
int c = saved_pixel[saved_pixel_n++];
int r = gfx::getr(c);
int g = gfx::getg(c);
int b = gfx::getb(c);
r = getr(c);
g = getg(c);
b = getb(c);
putpixel(bmp, x, y, ui::to_system(color_utils::blackandwhite_neg(ui::rgba(r, g, b))));
graphics->putPixel(color_utils::blackandwhite_neg(gfx::rgba(r, g, b)), x, y);
}
else {
putpixel(bmp, x, y, color);
graphics->putPixel(color, x, y);
}
}
}
static void cleanpixel(BITMAP *bmp, int x, int y, int color)
static void clearpixel(ui::Graphics* g, int x, int y, gfx::Color color)
{
if (saved_pixel_n < MAX_SAVED) {
if (clipping_region.contains(gfx::Point(x, y)))
putpixel(bmp, x, y, saved_pixel[saved_pixel_n++]);
g->putPixel(saved_pixel[saved_pixel_n++], x, y);
else if (!old_clipping_region.isEmpty() &&
old_clipping_region.contains(gfx::Point(x, y)))
saved_pixel_n++;

View File

@ -27,8 +27,8 @@
#include "app/color_utils.h"
#include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/document_location.h"
#include "app/console.h"
#include "app/document_location.h"
#include "app/ini_file.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
@ -55,12 +55,14 @@
#include "app/util/render.h"
#include "base/bind.h"
#include "base/unique_ptr.h"
#include "raster/conversion_alleg.h"
#include "raster/conversion_she.h"
#include "raster/raster.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/ui.h"
#include <allegro.h>
#include <stdio.h>
#include <cstdio>
namespace app {
@ -297,7 +299,7 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
int thick = m_cursor_thick;
if (thick)
editor_clean_cursor();
clearBrushPreview();
if (use_refresh_region) {
getDrawableRegion(region, kCutTopWindows);
@ -315,7 +317,7 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
}
if (thick)
editor_draw_cursor(m_cursor_screen_x, m_cursor_screen_y);
drawBrushPreview(m_cursor_screen_x, m_cursor_screen_y);
}
void Editor::updateEditor()
@ -394,10 +396,10 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& rc, in
m_decorator->preRenderDecorator(&preRender);
}
SharedPtr<BITMAP> tmp(create_bitmap(width, height), destroy_bitmap);
convert_image_to_allegro(rendered, tmp, 0, 0, m_sprite->getPalette(m_frame));
she::Surface* tmp(she::instance()->createRgbaSurface(width, height));
convert_image_to_surface(rendered, tmp, 0, 0, m_sprite->getPalette(m_frame));
g->blit(tmp, 0, 0, dest_x, dest_y, width, height);
tmp->dispose();
}
}
}
@ -493,7 +495,7 @@ void Editor::drawSpriteClipped(const gfx::Region& updateRegion)
Region region;
getDrawableRegion(region, kCutTopWindows);
Graphics g(ji_screen, 0, 0);
ScreenGraphics g;
for (Region::const_iterator
it=region.begin(), end=region.end(); it != end; ++it) {
@ -585,7 +587,7 @@ void Editor::drawMaskSafe()
region.offset(-getBounds().getOrigin());
if (thick)
editor_clean_cursor();
clearBrushPreview();
else
jmouse_hide();
@ -600,7 +602,7 @@ void Editor::drawMaskSafe()
// Draw the cursor
if (thick)
editor_draw_cursor(m_cursor_screen_x, m_cursor_screen_y);
drawBrushPreview(m_cursor_screen_x, m_cursor_screen_y);
else
jmouse_show();
}
@ -637,7 +639,7 @@ void Editor::drawGrid(Graphics* g, const gfx::Rect& spriteBounds, const Rect& gr
while (grid.y-grid.h >= spriteBounds.y) grid.y -= grid.h;
// Get the grid's color
ui::Color grid_color = color_utils::color_for_ui(color);
gfx::Color grid_color = color_utils::color_for_ui(color);
// Draw horizontal lines
int x1 = spriteBounds.x;
@ -774,7 +776,7 @@ void Editor::showDrawingCursor()
if (!m_cursor_thick && canDraw()) {
jmouse_hide();
editor_draw_cursor(jmouse_x(0), jmouse_y(0));
drawBrushPreview(jmouse_x(0), jmouse_y(0));
jmouse_show();
}
}
@ -783,7 +785,7 @@ void Editor::hideDrawingCursor()
{
if (m_cursor_thick) {
jmouse_hide();
editor_clean_cursor();
clearBrushPreview();
jmouse_show();
}
}
@ -801,7 +803,7 @@ void Editor::moveDrawingCursor()
// when the mouse moves only).
if ((m_cursor_screen_x != x) || (m_cursor_screen_y != y)) {
jmouse_hide();
editor_move_cursor(x, y);
moveBrushPreview(x, y);
jmouse_show();
}
}
@ -1023,7 +1025,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
int old_cursor_thick = m_cursor_thick;
if (m_cursor_thick)
editor_clean_cursor();
clearBrushPreview();
// Editor without sprite
if (!m_sprite) {
@ -1049,7 +1051,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
// Draw the cursor again
if (old_cursor_thick != 0) {
editor_draw_cursor(jmouse_x(0), jmouse_y(0));
drawBrushPreview(jmouse_x(0), jmouse_y(0));
}
}
catch (const LockedDocumentException&) {

View File

@ -37,6 +37,8 @@
#define MIN_ZOOM 0
#define MAX_ZOOM 5
struct BITMAP;
namespace raster {
class Sprite;
class Layer;
@ -63,6 +65,8 @@ namespace app {
class Editor : public ui::Widget,
public DocumentSettingsObserver {
public:
typedef void (*PixelDelegate)(ui::Graphics* g, int x, int y, gfx::Color color);
enum EditorFlags {
kNoneFlag = 0,
kShowGridFlag = 1,
@ -176,8 +180,6 @@ namespace app {
// in cursor.cpp
static int get_raw_cursor_color();
static bool is_cursor_mask();
static app::Color get_cursor_color();
static void set_cursor_color(const app::Color& color);
@ -199,10 +201,10 @@ namespace app {
private:
void setStateInternal(const EditorStatePtr& newState);
void editor_update_quicktool();
void editor_draw_cursor(int x, int y, bool refresh = true);
void editor_move_cursor(int x, int y, bool refresh = true);
void editor_clean_cursor(bool refresh = true);
bool editor_cursor_is_subpixel();
void drawBrushPreview(int x, int y, bool refresh = true);
void moveBrushPreview(int x, int y, bool refresh = true);
void clearBrushPreview(bool refresh = true);
bool doesBrushPreviewNeedSubpixel();
void drawMaskSafe();
void drawMask(ui::Graphics* g);
@ -211,9 +213,11 @@ namespace app {
void editor_setcursor();
void forEachBrushPixel(
ui::Graphics* g,
int screen_x, int screen_y,
int sprite_x, int sprite_y, int color,
void (*pixel)(BITMAP *bmp, int x, int y, int color));
int sprite_x, int sprite_y,
gfx::Color color,
PixelDelegate pixelDelegate);
// Draws the specified portion of sprite in the editor. Warning:
// You should setup the clip of the screen before calling this

View File

@ -28,11 +28,10 @@
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
#include "she/surface.h"
#include "ui/paint_event.h"
#include "ui/resize_event.h"
#include <allegro.h>
namespace app {
using namespace app::skin;
@ -43,13 +42,13 @@ EditorView::EditorView(EditorView::Type type)
, m_type(type)
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
int l = theme->get_part(PART_EDITOR_SELECTED_W)->w;
int t = theme->get_part(PART_EDITOR_SELECTED_N)->h;
int r = theme->get_part(PART_EDITOR_SELECTED_E)->w;
int b = theme->get_part(PART_EDITOR_SELECTED_S)->h;
int l = theme->get_part(PART_EDITOR_SELECTED_W)->width();
int t = theme->get_part(PART_EDITOR_SELECTED_N)->height();
int r = theme->get_part(PART_EDITOR_SELECTED_E)->width();
int b = theme->get_part(PART_EDITOR_SELECTED_S)->height();
setBorder(gfx::Border(l, t, r, b));
setBgColor(ui::rgba(0, 0, 0));
setBgColor(gfx::rgba(0, 0, 0));
setupScrollbars();
UIContext::instance()->settings()->addObserver(this);

View File

@ -51,8 +51,6 @@
#include "ui/system.h"
#include "ui/view.h"
#include <allegro.h>
namespace app {
using namespace ui;

View File

@ -285,33 +285,31 @@ bool StandbyState::onMouseWheel(Editor* editor, MouseMessage* msg)
WHEEL_ACTION wheelAction = WHEEL_NONE;
bool scrollBigSteps = false;
// Without modifiers
if (msg->keyModifiers() == kKeyNoneModifier) {
if (msg->wheelDelta().x != 0)
// Alt+mouse wheel changes the fg/bg colors
if (msg->altPressed()) {
if (msg->shiftPressed())
wheelAction = WHEEL_BG;
else
wheelAction = WHEEL_FG;
}
// Normal behavior: mouse wheel zooms
else if (UIContext::instance()->settings()->getZoomWithScrollWheel()) {
if (msg->ctrlPressed())
wheelAction = WHEEL_FRAME;
else if (msg->wheelDelta().x != 0 || msg->shiftPressed())
wheelAction = WHEEL_HSCROLL;
else
wheelAction = WHEEL_ZOOM;
}
// For laptops, it's convenient to that Ctrl+wheel zoom (because
// it's the "pinch" gesture).
else {
#if 1 // TODO make it configurable
if (msg->altPressed()) {
if (msg->shiftPressed())
wheelAction = WHEEL_BG;
else
wheelAction = WHEEL_FG;
}
else if (msg->ctrlPressed()) {
wheelAction = WHEEL_FRAME;
}
#else
if (msg->ctrlPressed())
wheelAction = WHEEL_ZOOM;
else if (msg->wheelDelta().x != 0 || msg->shiftPressed())
wheelAction = WHEEL_HSCROLL;
else
wheelAction = WHEEL_VSCROLL;
if (msg->shiftPressed())
scrollBigSteps = true;
#endif
}
switch (wheelAction) {
@ -445,6 +443,11 @@ bool StandbyState::onSetCursor(Editor* editor)
jmouse_set_cursor(kMoveCursor);
return true;
}
else if (current_ink->isSlice()) {
jmouse_set_cursor(kNoCursor);
editor->showDrawingCursor();
return true;
}
}
// Draw

View File

@ -47,8 +47,6 @@
#include "raster/sprite.h"
#include "ui/ui.h"
#include <allegro.h>
namespace app {
using namespace ui;
@ -119,6 +117,7 @@ public:
((getInk()->isSelection() ||
getInk()->isEyedropper() ||
getInk()->isScrollMovement() ||
getInk()->isSlice() ||
getInk()->isZoom()) ? undo::DoesntModifyDocument:
undo::ModifyDocument))
, m_expandCelCanvas(m_context, m_docSettings->getTiledMode(), m_undoTransaction)

View File

@ -24,6 +24,7 @@
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "she/surface.h"
#include <allegro.h>
@ -73,7 +74,7 @@ TransformHandles::~TransformHandles()
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const gfx::Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
BITMAP* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
she::Surface* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
fixed angle = ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
@ -84,7 +85,7 @@ HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point&
for (size_t c=0; c<corners.size(); ++c)
editor->editorToScreen(corners[c].x, corners[c].y, &x[c], &y[c]);
int handle_rs[2] = { gfx->w*2, gfx->w*3 };
int handle_rs[2] = { gfx->width()*2, gfx->width()*3 };
for (int i=0; i<2; ++i) {
int handle_r = handle_rs[i];
for (size_t c=0; c<HANDLES; ++c) {
@ -107,7 +108,7 @@ HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point&
void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& transform)
{
BITMAP* bmp = ji_screen;
ScreenGraphics g;
fixed angle = ftofix(128.0 * transform.angle() / PI);
gfx::Transformation::Corners corners;
@ -118,6 +119,7 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
for (size_t c=0; c<corners.size(); ++c)
editor->editorToScreen(corners[c].x, corners[c].y, &x[c], &y[c]);
// TODO DO NOT COMMIT
#if 0 // Uncomment this if you want to see the bounds in red (only for debugging purposes)
// -----------------------------------------------
{
@ -128,19 +130,19 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
y2 = y1 + transform.bounds().h;
editor->editorToScreen(x1, y1, &x1, &y1);
editor->editorToScreen(x2, y2, &x2, &y2);
rect(bmp, x1, y1, x2, y2, makecol(255, 0, 0));
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(x1, y1, x2-x1+1, y2-y1+1));
x1 = transform.pivot().x;
y1 = transform.pivot().y;
editor->editorToScreen(x1, y1, &x1, &y1);
circle(bmp, x1, y1, 4, makecol(255, 0, 0));
g.drawRect(gfx::rgba(255, 0, 0), gfx::Rect(x1-2, y1-2, 5, 5));
}
// -----------------------------------------------
#endif
// Draw corner handle
for (size_t c=0; c<HANDLES; ++c) {
drawHandle(bmp,
drawHandle(&g,
(x[handles_info[c].i1]+x[handles_info[c].i2])/2,
(y[handles_info[c].i1]+y[handles_info[c].i2])/2,
angle + handles_info[c].angle);
@ -150,13 +152,9 @@ void TransformHandles::drawHandles(Editor* editor, const gfx::Transformation& tr
if (angle != 0) {
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
BITMAP* gfx = theme->get_part(PART_PIVOT_HANDLE);
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
#if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION >= 4
draw_sprite_ex(bmp, gfx, pivotBounds.x, pivotBounds.y, DRAW_SPRITE_TRANS, DRAW_SPRITE_NO_FLIP);
#else
draw_trans_sprite(bmp, gfx, pivotBounds.x, pivotBounds.y);
#endif
g.drawRgbaSurface(part, pivotBounds.x, pivotBounds.y);
}
}
@ -175,23 +173,23 @@ void TransformHandles::invalidateHandles(Editor* editor, const gfx::Transformati
// Invalidate each corner handle.
for (size_t c=0; c<HANDLES; ++c) {
BITMAP* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
she::Surface* part = theme->get_part(PART_TRANSFORMATION_HANDLE);
int u = (x[handles_info[c].i1]+x[handles_info[c].i2])/2;
int v = (y[handles_info[c].i1]+y[handles_info[c].i2])/2;
adjustHandle(u, v, gfx->w, gfx->h, angle + handles_info[c].angle);
adjustHandle(u, v, part->width(), part->height(), angle + handles_info[c].angle);
editor->invalidateRect(gfx::Rect(u, v, gfx->w, gfx->h));
editor->invalidateRect(gfx::Rect(u, v, part->width(), part->height()));
}
// Invalidate area where the pivot is.
if (angle != 0) {
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
BITMAP* gfx = theme->get_part(PART_PIVOT_HANDLE);
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
editor->invalidateRect(gfx::Rect(pivotBounds.x,
pivotBounds.y,
gfx->w, gfx->h));
editor->invalidateRect(
gfx::Rect(pivotBounds.x, pivotBounds.y,
part->width(), part->height()));
}
}
@ -200,7 +198,7 @@ gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
const gfx::Transformation::Corners& corners)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
BITMAP* gfx = theme->get_part(PART_PIVOT_HANDLE);
she::Surface* part = theme->get_part(PART_PIVOT_HANDLE);
int pvx, pvy;
editor->editorToScreen(transform.pivot().x, transform.pivot().y, &pvx, &pvy);
@ -208,13 +206,16 @@ gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
pvx += (1 << editor->getZoom()) / 2;
pvy += (1 << editor->getZoom()) / 2;
return gfx::Rect(pvx-gfx->w/2, pvy-gfx->h/2, gfx->w, gfx->h);
return gfx::Rect(
pvx-part->width()/2,
pvy-part->height()/2,
part->width(),
part->height());
}
bool TransformHandles::inHandle(const gfx::Point& pt, int x, int y, int gfx_w, int gfx_h, fixed angle)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
BITMAP* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
adjustHandle(x, y, gfx_w, gfx_h, angle);
@ -222,18 +223,14 @@ bool TransformHandles::inHandle(const gfx::Point& pt, int x, int y, int gfx_w, i
pt.y >= y && pt.y < y+gfx_h);
}
void TransformHandles::drawHandle(BITMAP* bmp, int x, int y, fixed angle)
void TransformHandles::drawHandle(Graphics* g, int x, int y, fixed angle)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
BITMAP* gfx = theme->get_part(PART_TRANSFORMATION_HANDLE);
she::Surface* part = theme->get_part(PART_TRANSFORMATION_HANDLE);
adjustHandle(x, y, gfx->w, gfx->h, angle);
adjustHandle(x, y, part->width(), part->height(), angle);
#if ALLEGRO_VERSION == 4 && ALLEGRO_SUB_VERSION >= 4
draw_sprite_ex(bmp, gfx, x, y, DRAW_SPRITE_TRANS, DRAW_SPRITE_NO_FLIP);
#else
draw_trans_sprite(bmp, gfx, x, y);
#endif
g->drawRgbaSurface(part, x, y);
}
void TransformHandles::adjustHandle(int& x, int& y, int handle_w, int handle_h, fixed angle)

View File

@ -26,7 +26,9 @@
#include <allegro/fixed.h>
struct BITMAP;
namespace ui {
class Graphics;
}
namespace app {
class Editor;
@ -51,7 +53,7 @@ namespace app {
const gfx::Transformation::Corners& corners);
bool inHandle(const gfx::Point& pt, int x, int y, int gfx_w, int gfx_h, fixed angle);
void drawHandle(BITMAP* bmp, int x, int y, fixed angle);
void drawHandle(ui::Graphics* g, int x, int y, fixed angle);
void adjustHandle(int& x, int& y, int handle_w, int handle_h, fixed angle);
};

View File

@ -25,6 +25,8 @@
#include "app/modules/gfx.h"
#include "app/thumbnail_generator.h"
#include "app/ui/skin/skin_theme.h"
#include "she/font.h"
#include "she/surface.h"
#include "ui/ui.h"
#include <algorithm>
@ -135,9 +137,9 @@ bool FileList::onProcessMessage(Message* msg)
gfx::Size itemSize = getFileItemSize(fi);
if (((mouseMsg->position().y >= y) &&
(mouseMsg->position().y < y+2+th+2)) ||
(mouseMsg->position().y < y+th+4*jguiscale())) ||
(it == m_list.begin() && mouseMsg->position().y < y) ||
(it == m_list.end()-1 && mouseMsg->position().y >= y+2+th+2)) {
(it == m_list.end()-1 && mouseMsg->position().y >= y+th+4*jguiscale())) {
m_selected = fi;
makeSelectedFileitemVisible();
break;
@ -197,7 +199,7 @@ bool FileList::onProcessMessage(Message* msg)
gfx::Rect vp = view->getViewportBounds();
if (select < 0)
select = 0;
select += sgn * vp.h / (2+getTextHeight()+2);
select += sgn * vp.h / (getTextHeight()+4*jguiscale());
break;
}
case kKeyLeft:
@ -273,7 +275,7 @@ bool FileList::onProcessMessage(Message* msg)
View* view = View::getView(this);
if (view) {
gfx::Point scroll = view->getViewScroll();
scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * 3*(2+getTextHeight()+2);
scroll += static_cast<MouseMessage*>(msg)->wheelDelta() * 3*(getTextHeight()+4*jguiscale());
view->setViewScroll(scroll);
}
break;
@ -307,9 +309,9 @@ void FileList::onPaint(ui::PaintEvent& ev)
int th = getTextHeight();
int x, y = bounds.y;
int evenRow = 0;
ui::Color bgcolor;
ui::Color fgcolor;
BITMAP* thumbnail = NULL;
gfx::Color bgcolor;
gfx::Color fgcolor;
she::Surface* thumbnail = NULL;
int thumbnail_y = 0;
g->fillRect(theme->getColor(ThemeColor::Background), bounds);
@ -335,30 +337,28 @@ void FileList::onPaint(ui::PaintEvent& ev)
theme->getColor(ThemeColor::FileListOddRowText);
}
x = bounds.x+2;
x = bounds.x+2*jguiscale();
// Item background
g->fillRect(bgcolor, gfx::Rect(bounds.x, y, bounds.w, itemSize.h));
if (fi->isFolder()) {
int icon_w = ji_font_text_len(getFont(), "[+]");
int icon_h = ji_font_get_size(getFont());
int icon_w = getFont()->textLength("[+]");
g->drawString("[+]", fgcolor, bgcolor, true,
gfx::Point(x, y+2));
x += icon_w+2;
g->drawUIString("[+]", fgcolor, bgcolor, gfx::Point(x, y+2*jguiscale()));
x += icon_w+2*jguiscale();
}
// item name
g->drawString(
fi->getDisplayName().c_str(),
fgcolor, bgcolor, true, gfx::Point(x, y+2));
fgcolor, bgcolor, gfx::Point(x, y+2*jguiscale()));
// draw progress bars
double progress;
ThumbnailGenerator::WorkerStatus workerStatus =
ThumbnailGenerator::instance()->getWorkerStatus(fi, progress);
if (workerStatus == ThumbnailGenerator::WorkingOnThumbnail) {
int barw = 64*jguiscale();
@ -383,15 +383,15 @@ void FileList::onPaint(ui::PaintEvent& ev)
// Draw the thumbnail
if (thumbnail) {
x = vp.x+vp.w-2*jguiscale()-thumbnail->w;
y = thumbnail_y-thumbnail->h/2+getBounds().y;
y = MID(vp.y+2*jguiscale(), y, vp.y+vp.h-3*jguiscale()-thumbnail->h);
x = vp.x+vp.w - 2*jguiscale() - thumbnail->width();
y = thumbnail_y - thumbnail->height()/2 + getBounds().y;
y = MID(vp.y+2*jguiscale(), y, vp.y+vp.h-3*jguiscale()-thumbnail->height());
x -= getBounds().x;
y -= getBounds().y;
g->blit(thumbnail, 0, 0, x, y, thumbnail->w, thumbnail->h);
g->drawRect(ui::rgba(0, 0, 0),
gfx::Rect(x-1, y-1, thumbnail->w+1, thumbnail->h+1));
g->blit(thumbnail, 0, 0, x, y, thumbnail->width(), thumbnail->height());
g->drawRect(gfx::rgba(0, 0, 0),
gfx::Rect(x-1, y-1, thumbnail->width()+1, thumbnail->height()+1));
}
}
@ -451,14 +451,12 @@ gfx::Size FileList::getFileItemSize(IFileItem* fi) const
{
int len = 0;
if (fi->isFolder()) {
len += ji_font_text_len(getFont(), "[+]")+2;
}
if (fi->isFolder())
len += getFont()->textLength("[+]") + 2*jguiscale();
len += ji_font_text_len(getFont(), fi->getDisplayName().c_str());
len += getFont()->textLength(fi->getDisplayName().c_str());
return gfx::Size(2+len+2,
2+getTextHeight()+2);
return gfx::Size(len+4*jguiscale(), getTextHeight()+4*jguiscale());
}
void FileList::makeSelectedFileitemVisible()
@ -479,8 +477,8 @@ void FileList::makeSelectedFileitemVisible()
if (fi == m_selected) {
if (y < vp.y)
scroll.y = y - getBounds().y;
else if (y > vp.y + vp.h - (2+th+2))
scroll.y = y - getBounds().y - vp.h + (2+th+2);
else if (y > vp.y + vp.h - (th+4*jguiscale()))
scroll.y = y - getBounds().y - vp.h + (th+4*jguiscale());
view->setViewScroll(scroll);
break;

View File

@ -23,9 +23,11 @@
#include "app/ui/file_selector.h"
#include "app/app.h"
#include "app/console.h"
#include "app/file/file.h"
#include "app/find_widget.h"
#include "app/ini_file.h"
#include "app/load_widget.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/recent_files.h"
@ -35,6 +37,7 @@
#include "base/bind.h"
#include "base/path.h"
#include "base/split_string.h"
#include "base/unique_ptr.h"
#include "ui/ui.h"
#include <algorithm>
@ -200,17 +203,21 @@ FileSelector::FileSelector()
Box* box = loader.loadWidgetT<Box>("file_selector.xml", "main");
addChild(box);
View* view = app::find_widget<View>(this, "fileview_container");
m_goBack = app::find_widget<Button>(this, "goback");
m_goForward = app::find_widget<Button>(this, "goforward");
m_goUp = app::find_widget<Button>(this, "goup");
m_location = app::find_widget<ComboBox>(this, "location");
m_fileType = app::find_widget<ComboBox>(this, "filetype");
m_fileName = app::find_widget<CustomFileNameEntry>(this, "filename");
View* view;
app::finder(this)
>> "fileview_container" >> view
>> "goback" >> m_goBack
>> "goforward" >> m_goForward
>> "goup" >> m_goUp
>> "newfolder" >> m_newFolder
>> "location" >> m_location
>> "filetype" >> m_fileType
>> "filename" >> m_fileName;
m_goBack->setFocusStop(false);
m_goForward->setFocusStop(false);
m_goUp->setFocusStop(false);
m_newFolder->setFocusStop(false);
set_gfxicon_to_button(m_goBack,
PART_COMBOBOX_ARROW_LEFT,
@ -227,10 +234,16 @@ FileSelector::FileSelector()
PART_COMBOBOX_ARROW_UP_SELECTED,
PART_COMBOBOX_ARROW_UP_DISABLED,
JI_CENTER | JI_MIDDLE);
set_gfxicon_to_button(m_newFolder,
PART_NEWFOLDER,
PART_NEWFOLDER_SELECTED,
PART_NEWFOLDER,
JI_CENTER | JI_MIDDLE);
setup_mini_look(m_goBack);
setup_mini_look(m_goForward);
setup_mini_look(m_goUp);
setup_mini_look(m_newFolder);
m_fileList = new FileList();
m_fileList->setId("fileview");
@ -240,6 +253,7 @@ FileSelector::FileSelector()
m_goBack->Click.connect(Bind<void>(&FileSelector::onGoBack, this));
m_goForward->Click.connect(Bind<void>(&FileSelector::onGoForward, this));
m_goUp->Click.connect(Bind<void>(&FileSelector::onGoUp, this));
m_newFolder->Click.connect(Bind<void>(&FileSelector::onNewFolder, this));
m_location->CloseListBox.connect(Bind<void>(&FileSelector::onLocationCloseListBox, this));
m_fileType->Change.connect(Bind<void>(&FileSelector::onFileTypeChange, this));
m_fileList->FileSelected.connect(Bind<void>(&FileSelector::onFileListFileSelected, this));
@ -613,6 +627,42 @@ void FileSelector::onGoUp()
m_fileList->goUp();
}
void FileSelector::onNewFolder()
{
base::UniquePtr<Window> window(load_widget<Window>("file_selector.xml", "newfolder_dialog"));
Button* ok;
Entry* name;
app::finder(window)
>> "ok" >> ok
>> "name" >> name;
window->openWindowInForeground();
if (window->getKiller() == ok) {
IFileItem* currentFolder = m_fileList->getCurrentFolder();
if (currentFolder) {
std::string dirname = name->getText();
// Create the new directory
try {
currentFolder->createDirectory(dirname);
// Enter in the new folder
for (FileItemList::const_iterator it=currentFolder->getChildren().begin(),
end=currentFolder->getChildren().end(); it != end; ++it) {
if ((*it)->getDisplayName() == dirname) {
m_fileList->setCurrentFolder(*it);
break;
}
}
}
catch (const std::exception& e) {
Console::showException(e);
}
}
}
}
// Hook for the 'location' combo-box
void FileSelector::onLocationCloseListBox()
{

View File

@ -53,6 +53,7 @@ namespace app {
void onGoBack();
void onGoForward();
void onGoUp();
void onNewFolder();
void onLocationCloseListBox();
void onFileTypeChange();
void onFileListFileSelected();
@ -62,6 +63,7 @@ namespace app {
ui::Button* m_goBack;
ui::Button* m_goForward;
ui::Button* m_goUp;
ui::Button* m_newFolder;
ui::ComboBox* m_location;
ui::ComboBox* m_fileType;
CustomFileNameEntry* m_fileName;

View File

@ -26,8 +26,8 @@
#include "app/commands/commands.h"
#include "app/launcher.h"
#include "app/load_widget.h"
#include "app/palettes_loader.h"
#include "app/ui/palette_listbox.h"
#include "app/res/palettes_loader_delegate.h"
#include "app/ui/palettes_listbox.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "ui/box.h"
@ -91,7 +91,7 @@ void PalettePopup::onLoad()
void PalettePopup::onOpenFolder()
{
launcher::open_folder(PalettesLoader::palettesLocation());
launcher::open_folder(PalettesLoaderDelegate().resourcesLocation());
}
} // namespace app

View File

@ -20,7 +20,7 @@
#define APP_UI_PALETTE_POPUP_H_INCLUDED
#pragma once
#include "app/ui/palette_listbox.h"
#include "app/ui/palettes_listbox.h"
#include "base/compiler_specific.h"
#include "ui/popup_window.h"
@ -45,7 +45,7 @@ namespace app {
private:
ui::View* m_view;
ui::Button* m_load;
PaletteListBox m_paletteListBox;
PalettesListBox m_paletteListBox;
};
} // namespace app

View File

@ -20,10 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include <stdlib.h>
#include <string.h>
#include "app/app.h"
#include "app/color.h"
#include "app/modules/gui.h"
@ -44,6 +40,9 @@
#include "ui/view.h"
#include "ui/widget.h"
#include <cstdlib>
#include <cstring>
namespace app {
using namespace ui;
@ -284,7 +283,7 @@ void PaletteView::onPaint(ui::PaintEvent& ev)
Palette* palette = get_current_palette();
int bordercolor = makecol(255, 255, 255);
g->fillRect(ui::rgba(0 , 0, 0), bounds);
g->fillRect(gfx::rgba(0 , 0, 0), bounds);
y = bounds.y + this->border_width.t;
c = 0;
@ -296,7 +295,7 @@ void PaletteView::onPaint(ui::PaintEvent& ev)
if (c >= palette->size())
break;
color = ui::rgba(
color = gfx::rgba(
rgba_getr(palette->getEntry(c)),
rgba_getg(palette->getEntry(c)),
rgba_getb(palette->getEntry(c)));

View File

@ -0,0 +1,94 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/ui/palettes_listbox.h"
#include "app/modules/palettes.h"
#include "app/res/palette_resource.h"
#include "app/res/palettes_loader_delegate.h"
#include "app/ui/skin/skin_theme.h"
#include "base/bind.h"
#include "raster/palette.h"
#include "ui/graphics.h"
#include "ui/listitem.h"
#include "ui/message.h"
#include "ui/paint_event.h"
#include "ui/preferred_size_event.h"
#include "ui/view.h"
namespace app {
using namespace ui;
PalettesListBox::PalettesListBox()
: ResourcesListBox(new ResourcesLoader(new PalettesLoaderDelegate))
{
}
raster::Palette* PalettesListBox::selectedPalette()
{
Resource* resource = selectedResource();
if (!resource)
return NULL;
return static_cast<PaletteResource*>(resource)->palette();
}
void PalettesListBox::onResourceChange(Resource* resource)
{
ResourcesListBox::onResourceChange(resource);
raster::Palette* palette = static_cast<PaletteResource*>(resource)->palette();
PalChange(palette);
}
void PalettesListBox::onPaintResource(Graphics* g, const gfx::Rect& bounds, Resource* resource)
{
raster::Palette* palette = static_cast<PaletteResource*>(resource)->palette();
gfx::Rect box(
bounds.x, bounds.y+bounds.h-6*jguiscale(),
4*jguiscale(), 4*jguiscale());
for (int i=0; i<palette->size(); ++i) {
raster::color_t c = palette->getEntry(i);
g->fillRect(gfx::rgba(
raster::rgba_getr(c),
raster::rgba_getg(c),
raster::rgba_getb(c)), box);
box.x += box.w;
}
// g->drawString(getText(), fgcolor, gfx::ColorNone, false,
// gfx::Point(
// bounds.x + jguiscale()*2,
// bounds.y + bounds.h/2 - g->measureUIString(getText()).h/2));
}
void PalettesListBox::onResourcePreferredSize(Resource* resource, gfx::Size& size)
{
size = gfx::Size(0, (2+16+2)*jguiscale());
}
} // namespace app

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,38 +16,30 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_UI_PALETTE_LISTBOX_H_INCLUDED
#define APP_UI_PALETTE_LISTBOX_H_INCLUDED
#ifndef APP_UI_PALETTES_LISTBOX_H_INCLUDED
#define APP_UI_PALETTES_LISTBOX_H_INCLUDED
#pragma once
#include "app/palettes_loader.h"
#include "base/compiler_specific.h"
#include "base/unique_ptr.h"
#include "ui/listbox.h"
#include "ui/timer.h"
#include "app/ui/resources_listbox.h"
namespace raster {
class Palette;
}
namespace app {
class PaletteListBox : public ui::ListBox {
class PalettesListBox : public ResourcesListBox {
public:
PaletteListBox();
PalettesListBox();
raster::Palette* selectedPalette();
Signal1<void, raster::Palette*> PalChange;
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onChangeSelectedItem() OVERRIDE;
void onTick();
void stop();
private:
base::UniquePtr<PalettesLoader> m_palettesLoader;
ui::Timer m_palettesTimer;
class LoadingItem;
LoadingItem* m_loadingItem;
virtual void onResourceChange(Resource* resource) OVERRIDE;
virtual void onPaintResource(ui::Graphics* g, const gfx::Rect& bounds, Resource* resource) OVERRIDE;
virtual void onResourcePreferredSize(Resource* resource, gfx::Size& size) OVERRIDE;
};
} // namespace app

View File

@ -30,7 +30,6 @@
#include "gfx/size.h"
#include "ui/ui.h"
#include <allegro.h>
#include <vector>
namespace app {

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,13 +20,12 @@
#include "config.h"
#endif
#include "app/ui/palette_listbox.h"
#include "app/ui/resources_listbox.h"
#include "app/modules/palettes.h"
#include "app/palettes_loader.h"
#include "app/res/resource.h"
#include "app/res/resources_loader.h"
#include "app/ui/skin/skin_theme.h"
#include "base/bind.h"
#include "raster/palette.h"
#include "ui/graphics.h"
#include "ui/listitem.h"
#include "ui/message.h"
@ -39,14 +38,14 @@ namespace app {
using namespace ui;
using namespace skin;
class PaletteListItem : public ListItem {
class ResourceListItem : public ListItem {
public:
PaletteListItem(raster::Palette* palette, const std::string& name)
: ListItem(name), m_palette(palette) {
ResourceListItem(Resource* resource)
: ListItem(resource->name()), m_resource(resource) {
}
raster::Palette* palette() const {
return m_palette;
Resource* resource() const {
return m_resource;
}
protected:
@ -64,7 +63,7 @@ protected:
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
Graphics* g = ev.getGraphics();
gfx::Rect bounds = getClientBounds();
ui::Color bgcolor, fgcolor;
gfx::Color bgcolor, fgcolor;
if (isSelected()) {
bgcolor = theme->getColor(ThemeColor::ListItemSelectedFace);
@ -77,37 +76,37 @@ protected:
g->fillRect(bgcolor, bounds);
gfx::Rect box(
bounds.x, bounds.y+bounds.h-6*jguiscale(),
4*jguiscale(), 4*jguiscale());
static_cast<ResourcesListBox*>(getParent())->
paintResource(g, bounds, m_resource);
// for (int i=0; i<m_palette->size(); ++i) {
// raster::color_t c = m_resource->getEntry(i);
for (int i=0; i<m_palette->size(); ++i) {
raster::color_t c = m_palette->getEntry(i);
// g->fillRect(gfx::rgba(
// raster::rgba_getr(c),
// raster::rgba_getg(c),
// raster::rgba_getb(c)), box);
g->fillRect(ui::rgba(
raster::rgba_getr(c),
raster::rgba_getg(c),
raster::rgba_getb(c)), box);
// box.x += box.w;
// }
box.x += box.w;
}
g->drawString(getText(), fgcolor, ui::ColorNone, false,
g->drawString(getText(), fgcolor, gfx::ColorNone,
gfx::Point(
bounds.x + jguiscale()*2,
bounds.y + bounds.h/2 - g->measureString(getText()).h/2));
bounds.y + bounds.h/2 - g->measureUIString(getText()).h/2));
}
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE {
ev.setPreferredSize(
gfx::Size(0, (2+16+2)*jguiscale()));
static_cast<ResourcesListBox*>(getParent())->
preferredResourceSize(m_resource));
}
private:
base::UniquePtr<raster::Palette> m_palette;
base::UniquePtr<Resource> m_resource;
};
class PaletteListBox::LoadingItem : public ListItem {
class ResourcesListBox::LoadingItem : public ListItem {
public:
LoadingItem()
: ListItem("Loading")
@ -131,30 +130,40 @@ private:
int m_state;
};
PaletteListBox::PaletteListBox()
: m_palettesTimer(100)
ResourcesListBox::ResourcesListBox(ResourcesLoader* resourcesLoader)
: m_resourcesLoader(resourcesLoader)
, m_resourcesTimer(100)
, m_loadingItem(NULL)
{
m_palettesTimer.Tick.connect(Bind<void>(&PaletteListBox::onTick, this));
m_resourcesTimer.Tick.connect(Bind<void>(&ResourcesListBox::onTick, this));
}
raster::Palette* PaletteListBox::selectedPalette()
Resource* ResourcesListBox::selectedResource()
{
if (PaletteListItem* item = dynamic_cast<PaletteListItem*>(getSelectedChild()))
return item->palette();
if (ResourceListItem* listItem = dynamic_cast<ResourceListItem*>(getSelectedChild()))
return listItem->resource();
else
return NULL;
}
bool PaletteListBox::onProcessMessage(ui::Message* msg)
void ResourcesListBox::paintResource(Graphics* g, const gfx::Rect& bounds, Resource* resource)
{
onPaintResource(g, bounds, resource);
}
gfx::Size ResourcesListBox::preferredResourceSize(Resource* resource)
{
gfx::Size pref(0, 0);
onResourcePreferredSize(resource, pref);
return pref;
}
bool ResourcesListBox::onProcessMessage(ui::Message* msg)
{
switch (msg->type()) {
case kOpenMessage: {
if (m_palettesLoader == NULL) {
m_palettesLoader.reset(new PalettesLoader());
m_palettesTimer.start();
}
m_resourcesTimer.start();
break;
}
@ -162,16 +171,26 @@ bool PaletteListBox::onProcessMessage(ui::Message* msg)
return ListBox::onProcessMessage(msg);
}
void PaletteListBox::onChangeSelectedItem()
void ResourcesListBox::onChangeSelectedItem()
{
raster::Palette* palette = selectedPalette();
if (palette)
PalChange(palette);
Resource* resource = selectedResource();
if (resource)
onResourceChange(resource);
}
void PaletteListBox::onTick()
void ResourcesListBox::onResourceChange(Resource* resource)
{
if (m_palettesLoader == NULL) {
// Do nothing
}
void ResourcesListBox::onPaintResource(Graphics* g, const gfx::Rect& bounds, Resource* resource)
{
// Do nothing
}
void ResourcesListBox::onTick()
{
if (m_resourcesLoader == NULL) {
stop();
return;
}
@ -182,11 +201,11 @@ void PaletteListBox::onTick()
}
m_loadingItem->makeProgress();
base::UniquePtr<raster::Palette> palette;
base::UniquePtr<Resource> resource;
std::string name;
if (!m_palettesLoader->next(palette, name)) {
if (m_palettesLoader->isDone()) {
if (!m_resourcesLoader->next(resource)) {
if (m_resourcesLoader->isDone()) {
stop();
PRINTF("Done\n");
@ -194,19 +213,19 @@ void PaletteListBox::onTick()
return;
}
base::UniquePtr<PaletteListItem> item(new PaletteListItem(palette, name));
insertChild(getItemsCount()-1, item);
base::UniquePtr<ResourceListItem> listItem(new ResourceListItem(resource));
insertChild(getItemsCount()-1, listItem);
layout();
View* view = View::getView(this);
if (view)
view->updateView();
palette.release();
item.release();
resource.release();
listItem.release();
}
void PaletteListBox::stop()
void ResourcesListBox::stop()
{
if (m_loadingItem) {
removeChild(m_loadingItem);
@ -216,7 +235,7 @@ void PaletteListBox::stop()
invalidate();
}
m_palettesTimer.stop();
m_resourcesTimer.stop();
}
} // namespace app

View File

@ -0,0 +1,62 @@
/* Aseprite
* Copyright (C) 2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_UI_RESOURCES_LISTBOX_H_INCLUDED
#define APP_UI_RESOURCES_LISTBOX_H_INCLUDED
#pragma once
#include "app/res/resources_loader.h"
#include "base/compiler_specific.h"
#include "base/unique_ptr.h"
#include "ui/listbox.h"
#include "ui/timer.h"
namespace app {
class ResourcesListBox : public ui::ListBox {
public:
ResourcesListBox(ResourcesLoader* resourcesLoader);
Resource* selectedResource();
void paintResource(ui::Graphics* g, const gfx::Rect& bounds, Resource* resource);
gfx::Size preferredResourceSize(Resource* resource);
protected:
virtual bool onProcessMessage(ui::Message* msg) OVERRIDE;
virtual void onChangeSelectedItem() OVERRIDE;
virtual void onResourceChange(Resource* resource) = 0;
// abstract
virtual void onPaintResource(ui::Graphics* g, const gfx::Rect& bounds, Resource* resource) = 0;
virtual void onResourcePreferredSize(Resource* resource, gfx::Size& size) = 0;
private:
void onTick();
void stop();
ResourcesLoader* m_resourcesLoader;
ui::Timer m_resourcesTimer;
class LoadingItem;
LoadingItem* m_loadingItem;
};
} // namespace app
#endif

View File

@ -23,8 +23,7 @@
#include "app/ui/skin/button_icon_impl.h"
#include "app/ui/skin/skin_theme.h"
#include <allegro.h>
#include "she/surface.h"
namespace app {
@ -51,25 +50,25 @@ void ButtonIconImpl::destroy()
int ButtonIconImpl::getWidth()
{
return m_theme->get_part(m_normalIcon)->w;
return m_theme->get_part(m_normalIcon)->width();
}
int ButtonIconImpl::getHeight()
{
return m_theme->get_part(m_normalIcon)->h;
return m_theme->get_part(m_normalIcon)->height();
}
BITMAP* ButtonIconImpl::getNormalIcon()
she::Surface* ButtonIconImpl::getNormalIcon()
{
return m_theme->get_part(m_normalIcon);
}
BITMAP* ButtonIconImpl::getSelectedIcon()
she::Surface* ButtonIconImpl::getSelectedIcon()
{
return m_theme->get_part(m_selectedIcon);
}
BITMAP* ButtonIconImpl::getDisabledIcon()
she::Surface* ButtonIconImpl::getDisabledIcon()
{
return m_theme->get_part(m_disabledIcon);
}

View File

@ -39,9 +39,9 @@ namespace app {
void destroy();
int getWidth();
int getHeight();
BITMAP* getNormalIcon();
BITMAP* getSelectedIcon();
BITMAP* getDisabledIcon();
she::Surface* getNormalIcon();
she::Surface* getSelectedIcon();
she::Surface* getDisabledIcon();
int getIconAlign();
public:

View File

@ -65,7 +65,7 @@ namespace app {
else
part = m_partNormal;
g->drawAlphaBitmap(theme->get_part(part), bounds.x, bounds.y);
g->drawRgbaSurface(theme->get_part(part), bounds.x, bounds.y);
}
private:

View File

@ -22,7 +22,7 @@
#include "app/ui/skin/skin_part.h"
#include <allegro.h>
#include "she/surface.h"
namespace app {
namespace skin {
@ -42,12 +42,12 @@ void SkinPart::clear()
it != end; ++it) {
ASSERT(*it != NULL);
destroy_bitmap(*it);
(*it)->dispose();
*it = NULL;
}
}
void SkinPart::setBitmap(size_t index, BITMAP* bitmap)
void SkinPart::setBitmap(size_t index, she::Surface* bitmap)
{
if (index >= m_bitmaps.size())
m_bitmaps.resize(index+1, NULL);

View File

@ -23,14 +23,16 @@
#include <vector>
#include "base/shared_ptr.h"
struct BITMAP;
namespace she {
class Surface;
}
namespace app {
namespace skin {
class SkinPart {
public:
typedef std::vector<BITMAP*> Bitmaps;
typedef std::vector<she::Surface*> Bitmaps;
SkinPart();
~SkinPart();
@ -40,9 +42,9 @@ namespace app {
void clear();
// It doesn't destroy the previous bitmap in the given "index".
void setBitmap(size_t index, BITMAP* bitmap);
void setBitmap(size_t index, she::Surface* bitmap);
BITMAP* getBitmap(size_t index) const {
she::Surface* getBitmap(size_t index) const {
return (index < m_bitmaps.size() ? m_bitmaps[index]: NULL);
}

View File

@ -99,6 +99,9 @@ namespace app {
PART_COMBOBOX_ARROW_RIGHT_SELECTED,
PART_COMBOBOX_ARROW_RIGHT_DISABLED,
PART_NEWFOLDER,
PART_NEWFOLDER_SELECTED,
SKIN_PART_NESW(PART_TOOLBUTTON_NORMAL),
SKIN_PART_NESW(PART_TOOLBUTTON_HOT),
SKIN_PART_NESW(PART_TOOLBUTTON_LAST),
@ -200,6 +203,13 @@ namespace app {
PART_DROP_PIXELS_CANCEL,
PART_DROP_PIXELS_CANCEL_SELECTED,
PART_FREEHAND_ALGO_DEFAULT,
PART_FREEHAND_ALGO_DEFAULT_SELECTED,
PART_FREEHAND_ALGO_PIXEL_PERFECT,
PART_FREEHAND_ALGO_PIXEL_PERFECT_SELECTED,
PART_FREEHAND_ALGO_DOTS,
PART_FREEHAND_ALGO_DOTS_SELECTED,
PARTS
};

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,8 @@
#include "app/ui/skin/skin_parts.h"
#include "app/ui/skin/style_sheet.h"
#include "base/compiler_specific.h"
#include "gfx/color.h"
#include "gfx/fwd.h"
#include "ui/color.h"
#include "ui/manager.h"
#include "ui/system.h"
#include "ui/theme.h"
@ -33,14 +33,16 @@
#include <map>
#include <string>
#include <allegro/color.h>
namespace ui {
class Entry;
class Graphics;
class IButtonIcon;
}
namespace she {
class Surface;
}
namespace app {
namespace skin {
@ -116,11 +118,11 @@ namespace app {
SkinTheme();
~SkinTheme();
ui::Color getColor(ThemeColor::Type k) const {
gfx::Color getColor(ThemeColor::Type k) const {
return m_colors[k];
}
FONT* getMiniFont() const { return m_minifont; }
she::Font* getMiniFont() const { return m_minifont; }
void reload_skin();
void reload_fonts();
@ -159,15 +161,15 @@ namespace app {
int get_button_selected_offset() const { return 0; } // TODO Configurable in xml
BITMAP* get_part(int part_i) const { return m_part[part_i]; }
BITMAP* get_toolicon(const char* tool_id) const;
she::Surface* get_part(int part_i) const { return m_part[part_i]; }
she::Surface* get_toolicon(const char* tool_id) const;
gfx::Size get_part_size(int part_i) const;
// Helper functions to draw bounds/hlines with sheet parts
void draw_bounds_array(ui::Graphics* g, const gfx::Rect& rc, int parts[8]);
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, int nw, ui::Color bg = ui::ColorNone);
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr skinPart, ui::Color bg = ui::ColorNone);
void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2);
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, int nw, gfx::Color bg = gfx::ColorNone);
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr skinPart, gfx::Color bg = gfx::ColorNone);
void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, gfx::Color bg1, gfx::Color bg2);
void draw_part_as_hline(ui::Graphics* g, const gfx::Rect& rc, int part);
void draw_part_as_vline(ui::Graphics* g, const gfx::Rect& rc, int part);
void paintProgressBar(ui::Graphics* g, const gfx::Rect& rc, float progress);
@ -180,7 +182,7 @@ namespace app {
return m_parts_by_id[id];
}
ui::Color getColorById(const std::string& id) {
gfx::Color getColorById(const std::string& id) {
return m_colors_by_id[id];
}
@ -192,31 +194,31 @@ namespace app {
int nw, int n, int ne, int e, int se, int s, int sw, int w);
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr& skinPart);
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc,
BITMAP* nw, BITMAP* n, BITMAP* ne,
BITMAP* e, BITMAP* se, BITMAP* s,
BITMAP* sw, BITMAP* w);
she::Surface* nw, she::Surface* n, she::Surface* ne,
she::Surface* e, she::Surface* se, she::Surface* s,
she::Surface* sw, she::Surface* w);
BITMAP* cropPartFromSheet(BITMAP* bmp, int x, int y, int w, int h);
ui::Color getWidgetBgColor(ui::Widget* widget);
void drawTextString(ui::Graphics* g, const char *t, ui::Color fg_color, ui::Color bg_color,
bool fill_bg, ui::Widget* widget, const gfx::Rect& rc,
she::Surface* sliceSheet(she::Surface* sur, const gfx::Rect& bounds);
gfx::Color getWidgetBgColor(ui::Widget* widget);
void drawTextString(ui::Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color,
ui::Widget* widget, const gfx::Rect& rc,
int selected_offset);
void drawEntryCaret(ui::Graphics* g, ui::Entry* widget, int x, int y);
void paintIcon(ui::Widget* widget, ui::Graphics* g, ui::IButtonIcon* iconInterface, int x, int y);
static FONT* loadFont(const char* userFont, const std::string& path);
static she::Font* loadFont(const char* userFont, const std::string& path);
std::string m_selected_skin;
BITMAP* m_sheet_bmp;
std::vector<BITMAP*> m_part;
she::Surface* m_sheet;
std::vector<she::Surface*> m_part;
std::map<std::string, SkinPartPtr> m_parts_by_id;
std::map<std::string, BITMAP*> m_toolicon;
std::map<std::string, ui::Color> m_colors_by_id;
std::map<std::string, she::Surface*> m_toolicon;
std::map<std::string, gfx::Color> m_colors_by_id;
std::vector<ui::Cursor*> m_cursors;
std::vector<ui::Color> m_colors;
std::vector<gfx::Color> m_colors;
StyleSheet m_stylesheet;
FONT* m_minifont;
she::Font* m_minifont;
};
inline Style* get_style(const std::string& id) {
@ -227,7 +229,7 @@ namespace app {
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getPartById(id);
}
inline ui::Color get_color_by_id(const std::string& id) {
inline gfx::Color get_color_by_id(const std::string& id) {
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getColorById(id);
}

View File

@ -24,11 +24,10 @@
#include "app/ui/skin/skin_theme.h"
#include "css/sheet.h"
#include "she/surface.h"
#include "ui/graphics.h"
#include "ui/theme.h"
#include <allegro.h>
namespace app {
namespace skin {
@ -53,16 +52,16 @@ void BackgroundRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const cha
if (m_part != NULL && m_part->size() > 0) {
if (m_part->size() == 1) {
if (!ui::is_transparent(m_color))
if (!gfx::is_transparent(m_color))
g->fillRect(m_color, bounds);
g->drawAlphaBitmap(m_part->getBitmap(0), bounds.x, bounds.y);
g->drawRgbaSurface(m_part->getBitmap(0), bounds.x, bounds.y);
}
else if (m_part->size() == 8) {
theme->draw_bounds_nw(g, bounds, m_part, m_color);
}
}
else if (!ui::is_transparent(m_color)) {
else if (!gfx::is_transparent(m_color)) {
g->fillRect(m_color, bounds);
}
}
@ -72,35 +71,35 @@ void TextRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* tex
SkinTheme* theme = static_cast<SkinTheme*>(ui::CurrentTheme::get());
if (text) {
g->drawString(text,
(ui::is_transparent(m_color) ?
g->drawAlignedUIString(text,
(gfx::is_transparent(m_color) ?
theme->getColor(ThemeColor::Text):
m_color),
ui::ColorNone,
gfx::ColorNone,
gfx::Rect(bounds).shrink(m_padding), m_align);
}
}
void IconRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text)
{
BITMAP* bmp = m_part->getBitmap(0);
she::Surface* bmp = m_part->getBitmap(0);
int x, y;
if (m_align & JI_RIGHT)
x = bounds.x2() - bmp->w;
x = bounds.x2() - bmp->width();
else if (m_align & JI_CENTER)
x = bounds.x + bounds.w/2 - bmp->w/2;
x = bounds.x + bounds.w/2 - bmp->width()/2;
else
x = bounds.x;
if (m_align & JI_BOTTOM)
y = bounds.y2() - bmp->h;
y = bounds.y2() - bmp->height();
else if (m_align & JI_MIDDLE)
y = bounds.y + bounds.h/2 - bmp->h/2;
y = bounds.y + bounds.h/2 - bmp->height()/2;
else
y = bounds.y;
g->drawAlphaBitmap(bmp, x, y);
g->drawRgbaSurface(bmp, x, y);
}
Rules::Rules(const css::Query& query) :
@ -169,12 +168,12 @@ gfx::Size Rules::preferredSize(const char* text)
{
gfx::Size sz(0, 0);
if (m_icon) {
sz.w += m_icon->getPart()->getBitmap(0)->w;
sz.h = m_icon->getPart()->getBitmap(0)->h;
sz.w += m_icon->getPart()->getBitmap(0)->width();
sz.h = m_icon->getPart()->getBitmap(0)->height();
}
if (m_text && text) {
ui::ScreenGraphics g;
gfx::Size textSize = g.measureString(text);
gfx::Size textSize = g.measureUIString(text);
//if (sz.w > 0) sz.w += 2; // TODO text separation
sz.w += textSize.w;
sz.h = MAX(sz.h, textSize.h);

View File

@ -27,8 +27,8 @@
#include "css/state.h"
#include "css/stateful_style.h"
#include "gfx/border.h"
#include "gfx/color.h"
#include "gfx/fwd.h"
#include "ui/color.h"
#include <map>
#include <string>
@ -56,26 +56,26 @@ namespace app {
class BackgroundRule : public Rule {
public:
BackgroundRule() : m_color(ui::ColorNone) { }
BackgroundRule() : m_color(gfx::ColorNone) { }
void setColor(ui::Color color) { m_color = color; }
void setColor(gfx::Color color) { m_color = color; }
void setPart(const SkinPartPtr& part) { m_part = part; }
protected:
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) OVERRIDE;
private:
ui::Color m_color;
gfx::Color m_color;
SkinPartPtr m_part;
};
class TextRule : public Rule {
public:
explicit TextRule() : m_align(0),
m_color(ui::ColorNone) { }
m_color(gfx::ColorNone) { }
void setAlign(int align) { m_align = align; }
void setColor(ui::Color color) { m_color = color; }
void setColor(gfx::Color color) { m_color = color; }
void setPadding(const gfx::Border& padding) { m_padding = padding; }
protected:
@ -83,7 +83,7 @@ namespace app {
private:
int m_align;
ui::Color m_color;
gfx::Color m_color;
gfx::Border m_padding;
};

View File

@ -113,13 +113,13 @@ SkinPartPtr StyleSheet::convertPart(const css::Value& value)
}
// static
ui::Color StyleSheet::convertColor(const css::Value& value)
gfx::Color StyleSheet::convertColor(const css::Value& value)
{
ui::Color color = ui::ColorNone;
gfx::Color color = gfx::ColorNone;
if (value.type() == css::Value::String) {
const std::string& color_id = value.string();
color = get_color_by_id(color_id);
if (color == ui::ColorNone)
if (color == gfx::ColorNone)
throw base::Exception("Unknown color '%s'\n", color_id.c_str());
}
return color;

View File

@ -23,7 +23,7 @@
#include "app/ui/skin/skin_part.h"
#include "css/rule.h"
#include "css/state.h"
#include "ui/color.h"
#include "gfx/color.h"
#include <map>
#include <string>
@ -63,7 +63,7 @@ namespace app {
Style* getStyle(const std::string& id);
static SkinPartPtr convertPart(const css::Value& value);
static ui::Color convertColor(const css::Value& value);
static gfx::Color convertColor(const css::Value& value);
private:
typedef std::map<std::string, Style*> StyleMap;

View File

@ -42,11 +42,12 @@
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "she/font.h"
#include "she/surface.h"
#include "ui/ui.h"
#include "undo/undo_history.h"
#include <algorithm>
#include <allegro.h>
#include <cstdarg>
#include <cstdio>
#include <cstring>
@ -478,7 +479,7 @@ void StatusBar::onPreferredSize(PreferredSizeEvent& ev)
void StatusBar::onPaint(ui::PaintEvent& ev)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color textColor = theme->getColorById(kStatusBarText);
gfx::Color textColor = theme->getColorById(kStatusBarText);
Rect rc = getClientBounds();
Graphics* g = ev.getGraphics();
@ -491,10 +492,10 @@ void StatusBar::onPaint(ui::PaintEvent& ev)
// Color
if (m_state == SHOW_COLOR) {
// Draw eyedropper icon
BITMAP* icon = theme->get_toolicon("eyedropper");
she::Surface* icon = theme->get_toolicon("eyedropper");
if (icon) {
g->drawAlphaBitmap(icon, x, rc.y + rc.h/2 - icon->h/2);
x += icon->w + 4*jguiscale();
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
x += icon->width() + 4*jguiscale();
}
// Draw color
@ -507,33 +508,33 @@ void StatusBar::onPaint(ui::PaintEvent& ev)
std::string str = m_color.toHumanReadableString(app_get_current_pixel_format(),
app::Color::LongHumanReadableString);
if (m_alpha < 255) {
char buf[512];
usprintf(buf, ", Alpha %d", m_alpha);
char buf[256];
sprintf(buf, ", Alpha %d", m_alpha);
str += buf;
}
g->drawString(str, textColor, ColorNone, false,
gfx::Point(x, rc.y + rc.h/2 - text_height(getFont())/2));
g->drawString(str, textColor, ColorNone,
gfx::Point(x, rc.y + rc.h/2 - getFont()->height()/2));
x += ji_font_text_len(getFont(), str.c_str()) + 4*jguiscale();
x += getFont()->textLength(str.c_str()) + 4*jguiscale();
}
// Show tool
if (m_state == SHOW_TOOL) {
// Draw eyedropper icon
BITMAP* icon = theme->get_toolicon(m_tool->getId().c_str());
she::Surface* icon = theme->get_toolicon(m_tool->getId().c_str());
if (icon) {
g->drawAlphaBitmap(icon, x, rc.y + rc.h/2 - icon->h/2);
x += icon->w + 4*jguiscale();
g->drawRgbaSurface(icon, x, rc.y + rc.h/2 - icon->height()/2);
x += icon->width() + 4*jguiscale();
}
}
// Status bar text
if (getTextLength() > 0) {
g->drawString(getText(), textColor, ColorNone, false,
gfx::Point(x, rc.y + rc.h/2 - text_height(getFont())/2));
g->drawString(getText(), textColor, ColorNone,
gfx::Point(x, rc.y + rc.h/2 - getFont()->height()/2));
x += ji_font_text_len(getFont(), getText().c_str()) + 4*jguiscale();
x += getFont()->textLength(getText().c_str()) + 4*jguiscale();
}
// Draw progress bar

View File

@ -1,5 +1,5 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,17 +22,18 @@
//#define CLOSE_BUTTON_IN_EACH_TAB
#include <algorithm>
#include <allegro.h>
#include <cmath>
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/tabs.h"
#include "she/font.h"
#include "she/surface.h"
#include "ui/intern.h"
#include "ui/ui.h"
#include <algorithm>
#include <cmath>
#define ARROW_W (12*jguiscale())
#define ANI_ADDING_TAB_TICKS 5
@ -361,7 +362,7 @@ void Tabs::onPaint(PaintEvent& ev)
gfx::Rect rect = getClientBounds();
gfx::Rect box(rect.x-m_scrollX, rect.y,
2*jguiscale(),
m_list_of_tabs.empty() ? 0: theme->get_part(PART_TAB_FILLER)->h);
m_list_of_tabs.empty() ? 0: theme->get_part(PART_TAB_FILLER)->height());
g->fillRect(theme->getColorById(kWindowFaceColorId), g->getClipBounds());
@ -432,10 +433,10 @@ void Tabs::onResize(ResizeEvent& ev)
void Tabs::onPreferredSize(PreferredSizeEvent& ev)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
gfx::Size reqsize(0, theme->get_part(PART_TAB_BOTTOM_NORMAL)->h);
gfx::Size reqsize(0, theme->get_part(PART_TAB_BOTTOM_NORMAL)->height());
if (!m_list_of_tabs.empty()) {
reqsize.h += theme->get_part(PART_TAB_FILLER)->h;
reqsize.h += theme->get_part(PART_TAB_FILLER)->height();
}
ev.setPreferredSize(reqsize);
@ -475,8 +476,8 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, boo
return;
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color text_color;
ui::Color face_color;
gfx::Color text_color;
gfx::Color face_color;
// Selected
if (selected) {
@ -496,26 +497,29 @@ void Tabs::drawTab(Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, boo
PART_TAB_NORMAL_NW,
face_color);
g->drawString(tab->text, text_color, face_color, false,
gfx::Point(box.x + 4*jguiscale(),
box.y + box.h/2 - text_height(this->getFont())/2+1 + y_delta));
g->drawString(tab->text, text_color, gfx::ColorNone,
gfx::Point(
box.x + 4*jguiscale(),
box.y + box.h/2 - getFont()->height()/2+1 + y_delta));
}
if (selected) {
theme->draw_bounds_nw(g, gfx::Rect(box.x, box.y2(), box.w, getBounds().y2()-box.y2()),
PART_TAB_BOTTOM_SELECTED_NW,
theme->getColor(ThemeColor::TabSelectedFace));
theme->draw_bounds_nw(g,
gfx::Rect(box.x, box.y2(), box.w, getBounds().y2()-box.y2()),
PART_TAB_BOTTOM_SELECTED_NW,
theme->getColor(ThemeColor::TabSelectedFace));
}
else {
theme->draw_part_as_hline(g, gfx::Rect(box.x, box.y2(), box.w, getBounds().y2()-box.y2()),
PART_TAB_BOTTOM_NORMAL);
theme->draw_part_as_hline(g,
gfx::Rect(box.x, box.y2(), box.w, getBounds().y2()-box.y2()),
PART_TAB_BOTTOM_NORMAL);
}
#ifdef CLOSE_BUTTON_IN_EACH_TAB
BITMAP* close_icon = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL);
g->drawAlphaBitmap(close_icon,
box.x2() - 4*jguiscale() - close_icon->w,
box.y + box.h/2 - close_icon->h/2+1 * jguiscale());
she::Surface* close_icon = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL);
g->drawRgbaSurface(close_icon,
box.x2() - 4*jguiscale() - close_icon->width(),
box.y + box.h/2 - close_icon->height()/2+1 * jguiscale());
#endif
}
@ -660,10 +664,10 @@ void Tabs::calcTabWidth(Tab* tab)
int border = 4*jguiscale();
#ifdef CLOSE_BUTTON_IN_EACH_TAB
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
int close_icon_w = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL)->w;
tab->width = (border + text_length(getFont(), tab->text.c_str()) + border + close_icon_w + border);
int close_icon_w = theme->get_part(PART_WINDOW_CLOSE_BUTTON_NORMAL)->width();
tab->width = (border + getFont()->textLength(tab->text.c_str()) + border + close_icon_w + border);
#else
tab->width = (border + text_length(getFont(), tab->text.c_str()) + border);
tab->width = (border + getFont()->textLength(tab->text.c_str()) + border);
#endif
}

View File

@ -1146,10 +1146,9 @@ void Timeline::drawHeaderFrame(ui::Graphics* g, FrameNumber frame)
char buf[256];
std::sprintf(buf, "%d", (frame+1)%100); // Draw only the first two digits.
FONT* oldFont = g->getFont();
she::Font* oldFont = g->getFont();
g->setFont(((SkinTheme*)getTheme())->getMiniFont());
drawPart(g, bounds, buf, m_timelineBoxStyle,
is_active, is_hover, is_clicked);
drawPart(g, bounds, buf, m_timelineBoxStyle, is_active, is_hover, is_clicked);
g->setFont(oldFont);
}

View File

@ -39,9 +39,9 @@
#include "base/compiler_specific.h"
#include "base/signal.h"
#include "gfx/size.h"
#include "she/surface.h"
#include "ui/ui.h"
#include <allegro.h>
#include <string>
namespace app {
@ -78,9 +78,9 @@ private:
static Size getToolIconSize(Widget* widget)
{
SkinTheme* theme = static_cast<SkinTheme*>(widget->getTheme());
BITMAP* icon = theme->get_toolicon("configuration");
she::Surface* icon = theme->get_toolicon("configuration");
if (icon)
return Size(icon->w, icon->h);
return Size(icon->width(), icon->height());
else
return Size(16, 16) * jguiscale();
}
@ -318,8 +318,8 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
gfx::Rect bounds = getClientBounds();
Graphics* g = ev.getGraphics();
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
ui::Color normalFace = theme->getColor(ThemeColor::ButtonNormalFace);
ui::Color hotFace = theme->getColor(ThemeColor::ButtonHotFace);
gfx::Color normalFace = theme->getColor(ThemeColor::ButtonNormalFace);
gfx::Color hotFace = theme->getColor(ThemeColor::ButtonHotFace);
ToolBox* toolbox = App::instance()->getToolBox();
ToolGroupList::iterator it = toolbox->begin_group();
int groups = toolbox->getGroupsCount();
@ -330,7 +330,7 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
for (int c=0; c<groups; ++c, ++it) {
ToolGroup* tool_group = *it;
Tool* tool = m_selectedInGroup[tool_group];
ui::Color face;
gfx::Color face;
int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
@ -349,11 +349,11 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
theme->draw_bounds_nw(g, toolrc, nw, face);
// Draw the tool icon
BITMAP* icon = theme->get_toolicon(tool->getId().c_str());
she::Surface* icon = theme->get_toolicon(tool->getId().c_str());
if (icon) {
g->drawAlphaBitmap(icon,
toolrc.x+toolrc.w/2-icon->w/2,
toolrc.y+toolrc.h/2-icon->h/2);
g->drawRgbaSurface(icon,
toolrc.x+toolrc.w/2-icon->width()/2,
toolrc.y+toolrc.h/2-icon->height()/2);
}
}
@ -367,11 +367,11 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
PART_TOOLBUTTON_LAST_NW,
isHot ? hotFace: normalFace);
BITMAP* icon = theme->get_toolicon("configuration");
she::Surface* icon = theme->get_toolicon("configuration");
if (icon) {
g->drawAlphaBitmap(icon,
toolrc.x+toolrc.w/2-icon->w/2,
toolrc.y+toolrc.h/2-icon->h/2);
g->drawRgbaSurface(icon,
toolrc.x+toolrc.w/2-icon->width()/2,
toolrc.y+toolrc.h/2-icon->height()/2);
}
// Draw button to show/hide mini editor
@ -387,9 +387,9 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
icon = theme->get_toolicon("minieditor");
if (icon) {
g->drawAlphaBitmap(icon,
toolrc.x+toolrc.w/2-icon->w/2,
toolrc.y+toolrc.h/2-icon->h/2);
g->drawRgbaSurface(icon,
toolrc.x+toolrc.w/2-icon->width()/2,
toolrc.y+toolrc.h/2-icon->height()/2);
}
}
@ -467,7 +467,7 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
m_popupWindow->setHotRegion(rgn);
m_popupWindow->setTransparent(true);
m_popupWindow->setBgColor(ui::ColorNone);
m_popupWindow->setBgColor(gfx::ColorNone);
m_popupWindow->setAutoRemap(false);
m_popupWindow->setBounds(rc);
toolstrip->setBounds(rc);
@ -741,7 +741,7 @@ void ToolBar::ToolStrip::onPaint(PaintEvent& ev)
for (ToolIterator it = toolbox->begin(); it != toolbox->end(); ++it) {
Tool* tool = *it;
if (tool->getGroup() == m_group) {
ui::Color face;
gfx::Color face;
int nw;
if (UIContext::instance()->getSettings()->getCurrentTool() == tool ||
@ -759,11 +759,11 @@ void ToolBar::ToolStrip::onPaint(PaintEvent& ev)
theme->draw_bounds_nw(g, toolrc, nw, face);
// Draw the tool icon
BITMAP* icon = theme->get_toolicon(tool->getId().c_str());
she::Surface* icon = theme->get_toolicon(tool->getId().c_str());
if (icon) {
g->drawAlphaBitmap(icon,
toolrc.x+toolrc.w/2-icon->w/2,
toolrc.y+toolrc.h/2-icon->h/2);
g->drawRgbaSurface(icon,
toolrc.x+toolrc.w/2-icon->width()/2,
toolrc.y+toolrc.h/2-icon->height()/2);
}
}
}

View File

@ -20,9 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include <string.h>
#include "app/app.h"
#include "app/color.h"
#include "app/document_location.h"

View File

@ -132,6 +132,10 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
if (it != m_typeCreators.end()) {
widget = it->second->createWidgetFromXml(elem);
}
// Oneof
else if (elem_name == "panel") {
widget = new Panel();
}
// Boxes
else if (elem_name == "box") {
bool horizontal = bool_attr_is_true(elem, "horizontal");
@ -301,9 +305,14 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
/* listitem */
else if (elem_name == "listitem") {
const char *text = elem->Attribute("text");
const char* text = elem->Attribute("text");
const char* value = elem->Attribute("value");
widget = new ListItem(text ? TRANSLATE_ATTR(text): "");
ListItem* listitem = new ListItem(text ? TRANSLATE_ATTR(text): "");
if (value) {
listitem->setValue(value);
}
widget = listitem;
}
/* splitter */
else if (elem_name == "splitter") {

Some files were not shown because too many files have changed in this diff Show More