Merge branch 'new-theme-impl'

This commit is contained in:
David Capello 2017-03-13 18:19:11 -03:00
commit 1729e0e658
251 changed files with 6753 additions and 4749 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@
*.exe.manifest
*.log
*.res
.DS_Store
# CMake output
build

3
.gitmodules vendored
View File

@ -42,3 +42,6 @@
[submodule "third_party/cmark"]
path = third_party/cmark
url = https://github.com/aseprite/cmark.git
[submodule "third_party/harfbuzz"]
path = third_party/harfbuzz
url = https://github.com/aseprite/harfbuzz.git

View File

@ -1,5 +1,5 @@
# Aseprite
# Copyright (C) 2001-2016 David Capello
# Copyright (C) 2001-2017 David Capello
#
# Parts of this file come from the Allegro 4.4 CMakeLists.txt
@ -143,6 +143,7 @@ set(LOADPNG_DIR ${CMAKE_SOURCE_DIR}/third_party/loadpng)
set(LIBWEBP_DIR ${CMAKE_SOURCE_DIR}/third_party/libwebp)
set(PIXMAN_DIR ${CMAKE_SOURCE_DIR}/third_party/pixman)
set(FREETYPE_DIR ${CMAKE_SOURCE_DIR}/third_party/freetype2)
set(HARFBUZZ_DIR ${CMAKE_SOURCE_DIR}/third_party/harfbuzz)
set(SIMPLEINI_DIR ${CMAKE_SOURCE_DIR}/third_party/simpleini)
set(TINYXML_DIR ${CMAKE_SOURCE_DIR}/third_party/tinyxml)
set(ZLIB_DIR ${CMAKE_SOURCE_DIR}/third_party/zlib)
@ -263,6 +264,10 @@ else()
endif()
include_directories(${FREETYPE_INCLUDE_DIRS})
# harfbuzz
set(HARFBUZZ_LIBRARIES harfbuzz)
set(HARFBUZZ_INCLUDE_DIRS ${HARFBUZZ_DIR}/src)
if(USE_SHARED_GIFLIB)
find_package(GIF REQUIRED)
else()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

48
data/fonts/fonts.xml Normal file
View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<fonts>
<!-- Preset fonts that can be used by all themes -->
<font name="Arial"
type="truetype"
file="Arial.ttf" />
<font name="Arial Unicode"
type="truetype"
file_win="arialuni.ttf"
file_mac="Arial Unicode.ttf" />
<font name="Unicode Korean"
type="truetype"
file_win="malgun.ttf">
<fallback font="Arial Unicode" />
</font>
<font name="Unicode Chinese"
type="truetype"
file_win="msjh.ttc">
<fallback font="Unicode Korean" size="8" />
</font>
<font name="Unicode Japanese"
type="truetype"
file_win="YuGothR.ttc">
<fallback font="Unicode Chinese" size="8" />
</font>
<font name="Unicode"
type="truetype"
file="Arial.ttf"
file_mac="Arial Unicode.ttf">
<fallback font="Unicode Japanese" size="8" />
</font>
<font name="Aseprite"
type="spritesheet"
file="aseprite_font.png">
<fallback font="Unicode" size="8" />
</font>
<font name="Aseprite Mini"
type="spritesheet"
file="aseprite_mini.png">
<fallback font="Unicode" size="6" />
</font>
</fonts>

View File

@ -445,8 +445,8 @@
<key tool="eyedropper" shortcut="I" />
<key tool="hand" shortcut="H" />
<key tool="move" shortcut="V" />
<key tool="slice" shortcut="C" />
<key tool="zoom" shortcut="Z" />
<!-- key tool="slice" shortcut="K" /-->
<key tool="paint_bucket" shortcut="G" />
@ -769,6 +769,7 @@
<item command="ShowLayerEdges" text="&amp;Layer Edges" />
<item command="ShowSelectionEdges" text="&amp;Selection Edges" />
<item command="ShowGrid" text="&amp;Grid" />
<item command="ShowSlices" text="Sl&amp;ices" />
<item command="ShowPixelGrid" text="&amp;Pixel Grid" />
<separator />
<item command="ShowBrushPreview" text="&amp;Brush Preview" />
@ -915,6 +916,11 @@
<item command="RemoveFrameTag" text="&amp;Remove Tag" />
</menu>
<menu id="slice_popup">
<item command="SliceProperties" text="Slice &amp;Properties..." />
<item command="RemoveSlice" text="&amp;Remove Slice" />
</menu>
<menu id="palette_popup">
<item command="PaletteEditor" text="&amp;Palette Editor">
<param name="switch" value="true" />
@ -1118,15 +1124,15 @@
ink="move"
controller="freehand"
/>
<!-- tool id="slice"
<tool id="slice"
text="Slice Tool"
fill="always"
fill="none"
ink="slice"
controller="two_points"
pointshape="pixel"
intertwine="as_rectangles"
tracepolicy="last"
/-->
/>
</group>
<group id="paint_bucket" text="Paint Bucket Tool">

View File

@ -349,6 +349,7 @@
<option id="grid" type="bool" default="false" migrate="grid.visible" />
<option id="pixel_grid" type="bool" default="false" migrate="pixel_grid.visible" />
<option id="brush_preview" type="bool" default="true" />
<option id="slices" type="bool" default="true" />
</section>
</document>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -336,7 +336,7 @@ brush_preview = Brush Preview:
brush_preview_none = None
brush_preview_edges = Brush Edges
brush_preview_full = Full Real-time Brush Preview
cursor_color_type = Crosshair & Brush Edges Color:
cursor_color_type = Crosshair && Brush Edges Color:
cursor_neg_bw = Negative Black and White
cursor_specific_color = Specific Color
bg_checked = Checked Background
@ -438,6 +438,17 @@ open_dmp_file = Open the following file to debug your compilation:
do_it_later = Do it later
delete_file = Delete file, I've already sent it
[slice_properties]
title = Slice Properties
name = Slice Name:
user_data_tooltip = User Data
bounds = Bounds:
center = 9-Slices
x = X
y = Y
width = Width
height = Height
[sprite_properties]
title = Sprite Properties
filename = File name:
@ -508,7 +519,6 @@ in_front_toolip = For all kind of layers (background and transparents)
title = Undo History
[user_data]
title = User Data
user_data = User Data:
color = Color:

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<sprite>
<slices theme="theme.xml" />
</sprite>

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,7 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<skin name="Default"
author="Ilija Melentijevic &amp; David Capello"
url="http://ilkke.blogspot.com/">
<theme name="Default"
author="Ilija Melentijevic &amp; David Capello"
url="http://ilkke.blogspot.com/">
<fonts>
<font id="default" font="Aseprite" />
<font id="mini" font="Aseprite Mini" />
</fonts>
<dimensions>
<dim id="scrollbar_size" value="12" />
@ -29,7 +34,6 @@
<color id="selected" value="#ff5555" />
<color id="separator_label" value="#2c4c91" />
<color id="background" value="#ffffff" />
<color id="desktop" value="#968275" />
<color id="textbox_text" value="#000000" />
<color id="textbox_face" value="#ffffff" />
<color id="textbox_code_face" value="#eeeeee" />
@ -37,11 +41,8 @@
<color id="link_text" value="#2c4c91" />
<color id="link_hover" value="#ff5555" />
<color id="button_normal_text" value="#000000" />
<color id="button_normal_face" value="#c6c6c6" />
<color id="button_hot_text" value="#000000" />
<color id="button_hot_face" value="#ffffff" />
<color id="button_selected_text" value="#ffffff" />
<color id="button_selected_face" value="#7c909f" />
<color id="check_hot_face" value="#ffebb6" />
<color id="check_focus_face" value="#c6c6c6" />
<color id="radio_hot_face" value="#ffebb6" />
@ -59,21 +60,16 @@
<color id="editor_sprite_border" value="#000000" />
<color id="editor_sprite_bottom_border" value="#41412c" />
<color id="editor_layer_edges" value="#0000ff" />
<color id="editor_view_face" value="#000000" />
<color id="listitem_normal_text" value="#000000" />
<color id="listitem_normal_face" value="#ffffff" />
<color id="listitem_selected_text" value="#ffffff" />
<color id="listitem_selected_face" value="#ff5555" />
<color id="slider_empty_text" value="#000000" />
<color id="slider_empty_face" value="#aecbdf" />
<color id="slider_full_text" value="#ffffff" />
<color id="slider_full_face" value="#7d929e" />
<color id="tab_normal_text" value="#000000" />
<color id="tab_normal_face" value="#c6c6c6" />
<color id="tab_active_text" value="#ffffff" />
<color id="tab_active_face" value="#7d929e" />
<color id="splitter_normal_face" value="#7d929e" />
<color id="scrollbar_bg_face" value="#7d929e" />
<color id="scrollbar_thumb_face" value="#c6c6c6" />
<color id="popup_window_border" value="#000000" />
<color id="tooltip_text" value="#000000" />
<color id="tooltip_face" value="#ffff7d" />
@ -198,18 +194,13 @@
<part id="sunken_mini_focused" x="16" y="80" w1="4" w2="4" w3="4" h1="3" h2="6" h3="3" />
<part id="window" x="0" y="0" w1="3" w2="7" w3="3" h1="15" h2="4" h3="5" />
<part id="menu" x="0" y="96" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
<part id="window_close_button_normal" x="16" y="0" w="9" h="11" />
<part id="window_close_button_hot" x="25" y="0" w="9" h="11" />
<part id="window_close_button_selected" x="34" y="0" w="9" h="11" />
<part id="window_play_button_normal" x="16" y="11" w="9" h="11" />
<part id="window_play_button_hot" x="25" y="11" w="9" h="11" />
<part id="window_play_button_selected" x="34" y="11" w="9" h="11" />
<part id="window_stop_button_normal" x="16" y="22" w="9" h="11" />
<part id="window_stop_button_hot" x="25" y="22" w="9" h="11" />
<part id="window_stop_button_selected" x="34" y="22" w="9" h="11" />
<part id="window_center_button_normal" x="16" y="33" w="9" h="11" />
<part id="window_center_button_hot" x="25" y="33" w="9" h="11" />
<part id="window_center_button_selected" x="34" y="33" w="9" h="11" />
<part id="window_button_normal" x="16" y="0" w="9" h="11" />
<part id="window_button_hot" x="25" y="0" w="9" h="11" />
<part id="window_button_selected" x="34" y="0" w="9" h="11" />
<part id="window_close_icon" x="16" y="11" w="5" h="6" />
<part id="window_play_icon" x="21" y="11" w="5" h="6" />
<part id="window_stop_icon" x="26" y="11" w="5" h="6" />
<part id="window_center_icon" x="31" y="11" w="5" h="6" />
<part id="slider_full" x="0" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
<part id="slider_empty" x="16" y="144" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
<part id="slider_full_focused" x="0" y="160" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
@ -261,9 +252,8 @@
<part id="colorbar_1" x="16" y="192" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_2" x="0" y="208" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_3" x="16" y="208" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_border_fg" x="0" y="224" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_border_bg" x="16" y="224" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_border_hotfg" x="32" y="224" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_selection_hot" x="0" y="224" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="colorbar_selection" x="16" y="224" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="scrollbar_bg" x="64" y="144" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="scrollbar_thumb" x="64" y="160" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
<part id="mini_scrollbar_bg" x="64" y="176" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
@ -291,12 +281,6 @@
<part id="target_frames" x="176" y="224" w="32" h="16" />
<part id="target_layers" x="208" y="224" w="32" h="16" />
<part id="target_frames_layers" x="240" y="224" w="32" h="16" />
<part id="brush_circle" x="144" y="144" w="7" h="8" />
<part id="brush_circle_selected" x="144" y="152" w="7" h="8" />
<part id="brush_square" x="160" y="144" w="7" h="8" />
<part id="brush_square_selected" x="160" y="152" w="7" h="8" />
<part id="brush_line" x="176" y="144" w="6" h="6" />
<part id="brush_line_selected" x="176" y="152" w="6" h="6" />
<part id="selection_replace" x="176" y="160" w="7" h="7" />
<part id="selection_replace_selected" x="176" y="168" w="7" h="7" />
<part id="selection_add" x="192" y="160" w="7" h="7" />
@ -421,286 +405,468 @@
<part id="icon_grid" x="224" y="264" w="8" h="8" />
<part id="icon_save" x="232" y="264" w="8" h="8" />
<part id="icon_save_small" x="240" y="264" w="8" h="8" />
<part id="icon_slice" x="248" y="264" w="8" h="8" />
</parts>
<stylesheet>
<styles>
<!-- label -->
<style id="label">
<text color="text" />
</style>
<style id="label:disabled">
<text color="disabled" />
<style id="box" />
<style id="grid" />
<style id="window_without_title" border="3">
<background color="window_face" />
<border part="menu" />
</style>
<!-- link -->
<style id="link">
<text color="link_text" />
</style>
<style id="link:hover">
<text color="link_hover" />
<style id="window_with_title" border="6" border-top="17">
<background color="window_face" />
<border part="window" />
</style>
<!-- browser_link -->
<style id="browser_link" base="link">
<text padding-top="1" />
</style>
<!-- view -->
<style id="view">
<background part="sunken_normal" />
</style>
<style id="view:active">
<background part="sunken_focused" />
</style>
<!-- window -->
<style id="window">
<background color="window_face" part="window" />
</style>
<style id="window_title">
<style id="window_title_label" margin-top="5" margin-left="5">
<background color="window_titlebar_face" />
<text color="window_titlebar_text" align="left" valign="middle" />
<text color="window_titlebar_text" align="left middle" />
</style>
<style id="menubox">
<background color="window_face" part="menu" />
<style id="window_close_button" margin-top="3" margin-right="3">
<background part="window_button_normal" align="center middle" />
<background part="window_button_hot" state="mouse" align="center middle" />
<background part="window_button_selected" state="selected" align="center middle" />
<icon part="window_close_icon" color="button_normal_text" />
<icon part="window_close_icon" color="button_hot_text" state="mouse" />
<icon part="window_close_icon" color="button_selected_text" state="selected" />
</style>
<style id="popup_window">
<background color="window_face" />
<border part="menu" />
</style>
<style id="transparent_popup_window">
<!-- nothing (transparent) -->
</style>
<style id="menu">
<background color="window_face" />
</style>
<style id="menubox" extends="menu">
</style>
<style id="menubar" extends="menubox">
</style>
<style id="desktop">
<background color="desktop" />
<background color="window_face" />
</style>
<style id="tooltip_window">
<background part="tooltip" />
</style>
<style id="tooltip_window_arrow">
<background part="tooltip_arrow" />
</style>
<style id="tooltip_face">
<background color="tooltip_face" />
</style>
<style id="tooltip_text">
<background color="tooltip_face" />
<text color="tooltip_text" align="left" />
</style>
<style id="label" padding="1">
<text color="text" align="left" />
<text color="disabled" align="left" state="disabled" />
</style>
<style id="link">
<text color="link_text" align="left" />
<text color="link_hover" align="left" state="mouse" />
</style>
<style id="browser_link" extends="link" padding-top="1">
</style>
<style id="workspace_label">
<text color="workspace_text" align="left" />
</style>
<style id="workspace_link">
<text color="workspace_link" align="left" />
<text color="workspace_link_hover" align="left" state="mouse" />
</style>
<style id="workspace_update_link" padding-right="16">
<background part="button_normal" />
<background part="button_hot" state="mouse" />
<background part="button_selected" state="selected" />
<icon part="warning_box" align="right" />
<text color="button_normal_text" />
<text color="button_hot_text" state="mouse" />
<text color="button_selected_text" state="selected" />
</style>
<style id="view" border="3" border-top="4">
<background color="window_face" />
<border part="sunken_normal" />
<border part="sunken_focused" state="focus" />
</style>
<style id="editor_view">
<background color="editor_view_face" />
<border part="editor_normal" />
<border part="editor_selected" state="selected" />
</style>
<style id="workspace_view" border-top="4" extends="view">
<border part="editor_normal" />
<border part="editor_selected" state="focus" />
</style>
<style id="colorbar_view">
<border part="editor_normal" />
<border part="editor_selected" state="focus" />
</style>
<style id="button">
<background part="button_normal" />
<background part="button_hot" state="mouse" />
<background part="button_focused" state="focus" />
<background part="button_selected" state="selected" />
<text color="button_normal_text" />
<text color="button_hot_text" state="mouse" />
<text color="button_selected_text" state="selected" />
</style>
<style id="mini_button">
<background part="toolbutton_last" />
<background part="toolbutton_hot" state="mouse" />
<background part="toolbutton_hot" state="focus" />
<background part="toolbutton_pushed" state="selected" />
<text color="button_normal_text" />
<text color="button_hot_text" state="mouse" />
<text color="button_selected_text" state="selected" />
</style>
<style id="combobox_button" extends="mini_button">
<icon part="combobox_arrow_down" />
<icon part="combobox_arrow_down_selected" state="selected" />
<icon part="combobox_arrow_down_disabled" state="disabled" />
</style>
<style id="drop_down_button" extends="button">
<background part="drop_down_button_left_normal" />
<background part="drop_down_button_left_selected" state="selected" />
<background part="drop_down_button_left_hot" state="mouse" />
<background part="drop_down_button_left_focused" state="focus" />
</style>
<style id="drop_down_expand_button" extends="button">
<background part="drop_down_button_right_normal" />
<background part="drop_down_button_right_selected" state="selected" />
<background part="drop_down_button_right_hot" state="mouse" />
<background part="drop_down_button_right_focused" state="focus" />
<icon part="combobox_arrow_down" />
<icon part="combobox_arrow_down_selected" state="selected" />
<icon part="combobox_arrow_down_disabled" state="disabled" />
</style>
<style id="go_back_button" extends="mini_button">
<icon part="combobox_arrow_left" />
<icon part="combobox_arrow_left_selected" state="selected" />
<icon part="combobox_arrow_left_disabled" state="disabled" />
</style>
<style id="go_forward_button" extends="mini_button">
<icon part="combobox_arrow_right" />
<icon part="combobox_arrow_right_selected" state="selected" />
<icon part="combobox_arrow_right_disabled" state="disabled" />
</style>
<style id="go_up_button" extends="mini_button">
<icon part="combobox_arrow_up" />
<icon part="combobox_arrow_up_selected" state="selected" />
<icon part="combobox_arrow_up_disabled" state="disabled" />
</style>
<style id="new_folder_button" extends="mini_button">
<icon part="newfolder" />
<icon part="newfolder_selected" state="selected" />
</style>
<style id="color_wheel_options" border="1">
<background color="editor_face" />
<background color="check_hot_face" state="mouse" />
<background color="check_hot_face" state="selected" />
<icon part="pal_options" />
</style>
<style id="recover_sprites_button" extends="button"
border="0" padding="8">
</style>
<style id="new_frame_button" extends="mini_button">
</style>
<style id="color_button" extends="mini_button" border="5" font="mini">
</style>
<style id="splitter">
<background color="face" />
</style>
<style id="workspace_splitter">
<background color="workspace" />
</style>
<style id="horizontal_separator"
border-left="2"
border-top="4"
border-right="2"
border-bottom="0">
<background part="separator_horz" color="window_face" align="middle" />
<text color="separator_label" x="4" align="left middle" />
</style>
<style id="menu_separator" extends="horizontal_separator">
</style>
<style id="separator_in_view" extends="horizontal_separator">
<background part="separator_horz" color="background" align="middle" />
</style>
<style id="vertical_separator"
border-left="4"
border-top="2"
border-right="1"
border-bottom="2">
<background part="separator_vert" align="center" />
</style>
<style id="recent_item" />
<style id="recent_file" border="2">
<background color="background" />
<background color="menuitem_hot_face" state="mouse" />
<background color="listitem_selected_face" state="selected" />
<text color="text" align="left" x="2" />
<text color="listitem_selected_text" align="left" x="2" state="selected" />
</style>
<style id="recent_file_detail" border="2" border-left="0" extends="recent_file">
<text color="disabled" align="left" x="2" />
</style>
<style id="news_item" border="2">
<background color="background" />
<background color="menuitem_hot_face" state="mouse" />
<background color="listitem_selected_face" state="selected" />
<text color="text" align="left" x="2" />
<text color="listitem_selected_text" align="left" x="2" state="selected" />
</style>
<style id="news_item_detail" extends="news_item" border="2">
<text color="disabled" align="left top wordwrap" x="2" />
<text color="listitem_selected_text" align="left top wordwrap" x="2" state="selected" />
</style>
<!-- scrollbar -->
<style id="scrollbar">
<background color="scrollbar_bg_face" part="scrollbar_bg" />
<background part="scrollbar_bg" />
</style>
<style id="scrollbar_thumb">
<background color="scrollbar_thumb_face" part="scrollbar_thumb" />
<background part="scrollbar_thumb" />
</style>
<!-- mini_scrollbar -->
<style id="mini_scrollbar">
<background part="mini_scrollbar_bg" />
</style>
<style id="mini_scrollbar:hover">
<background part="mini_scrollbar_bg_hot" />
<background part="mini_scrollbar_bg_hot" state="mouse" />
</style>
<style id="mini_scrollbar_thumb">
<background part="mini_scrollbar_thumb" />
<background part="mini_scrollbar_thumb_hot" state="mouse" />
</style>
<style id="mini_scrollbar_thumb:hover">
<background part="mini_scrollbar_thumb_hot" />
</style>
<!-- transparent_scrollbar -->
<style id="transparent_scrollbar">
<background part="transparent_scrollbar_bg" />
</style>
<style id="transparent_scrollbar:hover">
<background part="transparent_scrollbar_bg_hot" />
<background part="transparent_scrollbar_bg_hot" state="mouse" />
</style>
<style id="transparent_scrollbar_thumb">
<background part="transparent_scrollbar_thumb" />
</style>
<style id="transparent_scrollbar_thumb:hover">
<background part="transparent_scrollbar_thumb_hot" />
<background part="transparent_scrollbar_thumb_hot" state="mouse" />
</style>
<style id="main_tabs">
<background color="window_face" />
</style>
<style id="workspace_tabs">
<background color="workspace" />
</style>
<style id="tab">
<background part="tab_normal" align="middle" />
<background part="tab_active" align="middle" state="focus" />
<text color="tab_normal_text" align="left" valign="middle" padding-left="4" padding-top="2" />
<text color="tab_active_text" state="focus" />
</style>
<style id="tab_text">
<text color="tab_normal_text" align="left middle" x="4" y="1" />
<text color="tab_active_text" align="left middle" x="4" y="1" state="focus" />
</style>
<style id="tab_bottom">
<background part="tab_bottom_normal" align="middle" />
<background part="tab_bottom_active" color="tab_active_face" state="focus" />
</style>
<style id="tab_filler">
<background part="tab_filler" align="middle" />
</style>
<style id="tab_icon">
<background part="tab_icon_bg_hover" state="mouse" />
<background part="tab_icon_bg_clicked" state="selected" />
</style>
<style id="tab_close_icon" extends="tab_icon">
<icon part="tab_close_icon_normal" align="left middle" x="3" />
<icon part="tab_close_icon_active" align="left middle" x="3" state="focus" />
<icon part="tab_close_icon_normal" align="left middle" x="3" state="selected" />
</style>
<style id="tab_modified_icon" extends="tab_icon">
<icon part="tab_modified_icon_normal" align="left middle" x="3" />
<icon part="tab_modified_icon_active" align="left middle" x="3" state="focus" />
<icon part="tab_modified_icon_normal" align="left middle" x="3" state="selected" />
</style>
<style id="tab_home">
<icon part="tab_home_icon_normal" align="left middle" x="4" y="1" />
<icon part="tab_home_icon_active" align="left middle" x="4" y="1" state="focus" />
</style>
<style id="flag">
<background part="flag_normal" color="flag_normal" />
<background part="flag_highlight" color="flag_active" state="focus" />
<background part="flag_highlight" color="flag_clicked" state="selected" />
</style>
<style id="warning_box" padding-left="2" padding-right="2">
<background color="workspace" />
<background color="hot_face" state="mouse" />
<icon part="warning_box" align="center middle" />
</style>
<!-- timeline -->
<style id="timeline">
<background color="timeline_normal" part="timeline_normal" />
</style>
<!-- timeline_box -->
<style id="timeline_box">
<background color="timeline_normal" part="timeline_normal" />
<text color="timeline_normal_text" align="center" valign="middle" />
<background color="timeline_hover" part="timeline_hover" state="mouse" />
<background color="timeline_active" part="timeline_active" state="focus" />
<background color="timeline_active_hover" part="timeline_active_hover" state="focus mouse" />
<background color="timeline_clicked" part="timeline_clicked" state="selected" />
</style>
<style id="timeline_box:hover">
<background color="timeline_hover" part="timeline_hover" />
<text color="timeline_hover_text" />
<style id="timeline_open_eye" extends="timeline_box">
<icon part="timeline_open_eye_normal" />
<icon part="timeline_open_eye_active" state="focus" />
<icon part="timeline_open_eye_active" state="selected" />
<icon part="timeline_open_eye_normal" color="disabled" state="disabled" />
</style>
<style id="timeline_box:active">
<background color="timeline_active" part="timeline_active" />
<text color="timeline_active_text" />
<style id="timeline_closed_eye" extends="timeline_box">
<icon part="timeline_closed_eye_normal" />
<icon part="timeline_closed_eye_active" state="focus" />
<icon part="timeline_closed_eye_active" state="selected" />
<icon part="timeline_closed_eye_normal" color="disabled" state="disabled" />
</style>
<style id="timeline_box:active:hover">
<background color="timeline_active_hover" part="timeline_active_hover" />
<text color="timeline_active_hover_text" />
<style id="timeline_open_padlock" extends="timeline_box">
<icon part="timeline_open_padlock_normal" />
<icon part="timeline_open_padlock_active" state="focus" />
<icon part="timeline_open_padlock_active" state="selected" />
<icon part="timeline_open_padlock_normal" color="disabled" state="disabled" />
</style>
<style id="timeline_box:clicked">
<background color="timeline_clicked" part="timeline_clicked" />
<text color="timeline_clicked_text" />
<style id="timeline_closed_padlock" extends="timeline_box">
<icon part="timeline_closed_padlock_normal" />
<icon part="timeline_closed_padlock_active" state="focus" />
<icon part="timeline_closed_padlock_active" state="selected" />
<icon part="timeline_closed_padlock_normal" color="disabled" state="disabled" />
</style>
<!-- timeline_eye -->
<style id="timeline_open_eye" base="timeline_box">
<icon part="timeline_open_eye_normal" align="center" valign="middle" />
<style id="timeline_continuous" extends="timeline_box">
<icon part="timeline_continuous_normal" />
<icon part="timeline_continuous_active" state="focus" />
<icon part="timeline_continuous_active" state="selected" />
</style>
<style id="timeline_open_eye:active">
<icon part="timeline_open_eye_active" />
<style id="timeline_discontinuous" extends="timeline_box">
<icon part="timeline_discontinuous_normal" />
<icon part="timeline_discontinuous_active" state="focus" />
<icon part="timeline_discontinuous_active" state="selected" />
</style>
<style id="timeline_open_eye:disabled">
<icon color="disabled" />
<style id="timeline_closed_group" extends="timeline_box">
<icon part="timeline_closed_group_normal" />
<icon part="timeline_closed_group_active" state="focus" />
<icon part="timeline_closed_group_active" state="selected" />
</style>
<style id="timeline_closed_eye" base="timeline_box">
<icon part="timeline_closed_eye_normal" align="center" valign="middle" />
<style id="timeline_open_group" extends="timeline_box">
<icon part="timeline_open_group_normal" />
<icon part="timeline_open_group_active" state="focus" />
<icon part="timeline_open_group_active" state="selected" />
</style>
<style id="timeline_closed_eye:active">
<icon part="timeline_closed_eye_active" />
<style id="timeline_layer" extends="timeline_box">
<text color="timeline_normal_text" align="left middle" x="2" />
<text color="timeline_hover_text" align="left middle" x="2" state="mouse" />
<text color="timeline_active_text" align="left middle" x="2" state="focus" />
<text color="timeline_active_hover_text" align="left middle" x="2" state="focus mouse" />
<text color="timeline_clicked_text" align="left middle" x="2" state="selected" />
</style>
<style id="timeline_closed_eye:disabled">
<icon color="disabled" />
</style>
<!-- timeline_padlock -->
<style id="timeline_open_padlock" base="timeline_box">
<icon part="timeline_open_padlock_normal" align="center" valign="middle" />
</style>
<style id="timeline_open_padlock:active">
<icon part="timeline_open_padlock_active" />
</style>
<style id="timeline_open_padlock:disabled">
<icon color="disabled" />
</style>
<style id="timeline_closed_padlock" base="timeline_box">
<icon part="timeline_closed_padlock_normal" align="center" valign="middle" />
</style>
<style id="timeline_closed_padlock:active">
<icon part="timeline_closed_padlock_active" />
</style>
<style id="timeline_closed_padlock:disabled">
<icon color="disabled" />
</style>
<!-- timeline_continuous -->
<style id="timeline_continuous" base="timeline_box">
<icon part="timeline_continuous_normal" align="center" valign="middle" />
</style>
<style id="timeline_continuous:active">
<icon part="timeline_continuous_active" />
</style>
<style id="timeline_discontinuous" base="timeline_box">
<icon part="timeline_discontinuous_normal" align="center" valign="middle" />
</style>
<style id="timeline_discontinuous:active">
<icon part="timeline_discontinuous_active" />
</style>
<!-- timeline_group -->
<style id="timeline_closed_group" base="timeline_box">
<icon part="timeline_closed_group_normal" align="center" valign="middle" />
</style>
<style id="timeline_closed_group:active">
<icon part="timeline_closed_group_active" />
</style>
<style id="timeline_open_group" base="timeline_box">
<icon part="timeline_open_group_normal" align="center" valign="middle" />
</style>
<style id="timeline_open_group:active">
<icon part="timeline_open_group_active" />
</style>
<!-- timeline_layer -->
<style id="timeline_layer" base="timeline_box">
<text align="left" valign="middle" padding-left="4" />
</style>
<style id="timeline_layer_text_only" base="timeline_layer">
<style id="timeline_layer_text_only" extends="timeline_layer">
<background color="none" part="none" repeat="none" />
<background color="none" part="none" repeat="none" state="mouse" />
<background color="none" part="none" repeat="none" state="focus" />
<background color="none" part="none" repeat="none" state="focus mouse" />
</style>
<style id="timeline_layer_text_only:hover" base="timeline_layer">
<background color="none" part="none" repeat="none" />
<style id="timeline_header_frame" extends="timeline_box" font="mini">
<text color="timeline_normal_text" />
<text color="timeline_hover_text" state="mouse" />
<text color="timeline_active_text" state="focus" />
<text color="timeline_active_hover_text" state="focus mouse" />
<text color="timeline_clicked_text" state="selected" />
</style>
<style id="timeline_layer_text_only:active" base="timeline_layer">
<background color="none" part="none" repeat="none" />
</style>
<style id="timeline_layer_text_only:active:hover" base="timeline_layer">
<background color="none" part="none" repeat="none" />
</style>
<!-- timeline_selected_cel -->
<style id="timeline_selected_cel">
<background color="timeline_clicked" part="timeline_clicked" />
<text color="timeline_clicked_text" />
</style>
<!-- timeline_empty_frame -->
<style id="timeline_empty_frame">
<icon part="timeline_empty_frame_normal" align="center" valign="middle" />
<icon part="timeline_empty_frame_normal" />
<icon part="timeline_empty_frame_active" state="focus" />
</style>
<style id="timeline_empty_frame:active">
<icon part="timeline_empty_frame_active" />
</style>
<!--timeline_keyframe-->
<style id="timeline_keyframe">
<icon part="timeline_keyframe_normal" align="center" valign="middle" />
<icon part="timeline_keyframe_normal" />
<icon part="timeline_keyframe_active" state="focus" />
</style>
<style id="timeline_keyframe:active">
<icon part="timeline_keyframe_active" />
</style>
<style id="timeline_from_left">
<icon part="timeline_from_left_normal" align="center" valign="middle" />
<icon part="timeline_from_left_normal" />
<icon part="timeline_from_left_active" state="focus" />
</style>
<style id="timeline_from_left:active">
<icon part="timeline_from_left_active" />
</style>
<style id="timeline_from_right">
<icon part="timeline_from_right_normal" align="center" valign="middle" />
<icon part="timeline_from_right_normal" />
<icon part="timeline_from_right_active" state="focus" />
</style>
<style id="timeline_from_right:active">
<icon part="timeline_from_right_active" />
</style>
<style id="timeline_from_both">
<icon part="timeline_from_both_normal" align="center" valign="middle" />
<icon part="timeline_from_both_normal" />
<icon part="timeline_from_both_active" state="focus" />
</style>
<style id="timeline_from_both:active">
<icon part="timeline_from_both_active" />
</style>
<style id="timeline_left_link">
<icon part="timeline_left_link_active" align="center" valign="middle" />
<icon part="timeline_left_link_active" />
</style>
<style id="timeline_right_link">
<icon part="timeline_right_link_active" align="center" valign="middle" />
<icon part="timeline_right_link_active" />
</style>
<style id="timeline_both_links">
<icon part="timeline_both_links_active" align="center" valign="middle" />
<icon part="timeline_both_links_active" />
</style>
<!-- timeline_gear -->
<style id="timeline_gear" base="timeline_box">
<icon part="timeline_gear" align="center" valign="middle" />
<style id="timeline_gear" extends="timeline_box">
<icon part="timeline_gear" />
<icon part="timeline_gear_active" state="focus" />
<icon part="timeline_gear_active" state="selected" />
</style>
<style id="timeline_gear:active">
<icon part="timeline_gear_active" />
<style id="timeline_onionskin" extends="timeline_box">
<icon part="timeline_onionskin" />
<icon part="timeline_onionskin_active" state="focus" />
<icon part="timeline_onionskin_active" state="selected" />
</style>
<style id="timeline_gear:clicked">
<icon part="timeline_gear_active" />
</style>
<!-- timeline_onionskin -->
<style id="timeline_onionskin" base="timeline_box">
<icon part="timeline_onionskin" align="center" valign="middle" />
</style>
<style id="timeline_onionskin:active">
<icon part="timeline_onionskin_active" />
</style>
<style id="timeline_onionskin:clicked">
<icon part="timeline_onionskin_active" />
</style>
<!-- timeline_onionskin_range -->
<style id="timeline_onionskin_range">
<background part="timeline_onionskin_range" />
</style>
<!-- paddings -->
<style id="timeline_padding">
<background color="timeline_normal" part="timeline_padding" />
</style>
@ -713,202 +879,29 @@
<style id="timeline_padding_br">
<background color="timeline_normal" part="timeline_padding_br" />
</style>
<!-- timeline_range_outline -->
<style id="timeline_range_outline">
<background part="colorbar_selection" state="focus" />
<background part="colorbar_selection_hot" state="focus mouse" />
</style>
<style id="timeline_range_outline:active">
<background part="colorbar_border_hotfg" />
</style>
<style id="timeline_range_outline:hover">
<background part="colorbar_border_fg" />
</style>
<!-- timeline_drop_layer_deco -->
<style id="timeline_drop_layer_deco">
<background part="timeline_drop_layer_deco" />
</style>
<!-- timeline_drop_frame_deco -->
<style id="timeline_drop_frame_deco">
<background part="timeline_drop_frame_deco" />
</style>
<!-- timeline_loop_range -->
<style id="timeline_loop_range">
<background part="timeline_loop_range" />
</style>
<!-- flag -->
<style id="flag">
<background part="flag_normal" color="flag_normal" />
</style>
<style id="flag:active">
<background part="flag_highlight" color="flag_active" />
</style>
<style id="flag:clicked">
<background part="flag_highlight" color="flag_clicked" />
<style id="shade_selection">
<background part="colorbar_selection_hot" />
</style>
<!-- warning_box -->
<style id="warning_box">
<background color="workspace" />
<icon part="warning_box" align="center" valign="middle" />
</style>
<style id="warning_box:hover">
<background color="hot_face" />
<style id="colorbar_selection">
<background part="colorbar_selection" />
<background part="colorbar_selection_hot" state="mouse" />
</style>
<!-- tab -->
<style id="tab">
<background part="tab_normal" color="tab_normal_face" repeat="repeat-x" />
<text color="tab_normal_text" align="left" valign="middle" padding-left="4" padding-top="2" />
</style>
<style id="tab:active">
<background part="tab_active" color="tab_active_face" />
<text color="tab_active_text" />
</style>
</styles>
<!-- tab_text -->
<style id="tab_text">
<text color="tab_normal_text" align="left" valign="middle" padding-left="4" padding-top="2" />
</style>
<style id="tab_text:active">
<text color="tab_active_text" />
</style>
<!-- tab_bottom -->
<style id="tab_bottom">
<background part="tab_bottom_normal" color="tab_normal_face" repeat="repeat-x" />
</style>
<style id="tab_bottom:active">
<background part="tab_bottom_active" color="tab_active_face" />
</style>
<!-- tab_filler -->
<style id="tab_filler">
<background part="tab_filler" color="window_face" repeat="repeat-x" />
</style>
<!-- tab_icon -->
<style id="tab_icon">
<icon align="left" valign="middle" x="3" />
</style>
<style id="tab_icon:hover">
<background part="tab_icon_bg_hover" />
</style>
<style id="tab_icon:clicked">
<background part="tab_icon_bg_clicked" />
</style>
<!-- tab_close_icon -->
<style id="tab_close_icon" base="tab_icon">
<icon part="tab_close_icon_normal" />
</style>
<style id="tab_close_icon:hover">
<icon part="tab_close_icon_normal" />
</style>
<style id="tab_close_icon:active">
<icon part="tab_close_icon_active" />
</style>
<style id="tab_close_icon:clicked">
<icon part="tab_close_icon_normal" />
</style>
<!-- tab_modified_icon -->
<style id="tab_modified_icon" base="tab_icon">
<icon part="tab_modified_icon_normal" />
</style>
<style id="tab_modified_icon:hover">
<icon part="tab_modified_icon_normal" />
</style>
<style id="tab_modified_icon:active">
<icon part="tab_modified_icon_active" />
</style>
<style id="tab_modified_icon:clicked">
<icon part="tab_modified_icon_normal" />
</style>
<!-- tab_home -->
<style id="tab_home">
<icon part="tab_home_icon_normal" align="left" valign="middle" x="4" y="1" />
</style>
<style id="tab_home:active">
<icon part="tab_home_icon_active" />
</style>
<!-- workspace_label -->
<style id="workspace_label">
<text color="workspace_text" />
</style>
<!-- workspace_link -->
<style id="workspace_link">
<text color="workspace_link" valign="middle" />
</style>
<style id="workspace_link:hover">
<text color="workspace_link_hover" />
</style>
<!-- workspace_link -->
<style id="workspace_update_link" base="workspace_link">
<background part="button_normal" color="button_normal_face" />
<icon part="warning_box" align="right" x="-4" y="4" />
<text padding-left="4" />
</style>
<style id="workspace_update_link:hover">
<background part="button_hot" color="button_hot_face" />
<text color="button_hot_text" />
</style>
<style id="workspace_update_link:clicked">
<background part="button_selected" color="button_selected_face" />
<text color="button_selected_text" />
</style>
<!-- workspace_view -->
<style id="workspace_view">
<background part="editor_normal" />
</style>
<style id="workspace_view:active">
<background part="editor_selected" />
</style>
<!-- recent_file -->
<style id="recent_file">
<background color="background" />
<text color="text" valign="middle" padding-left="2" padding-right="2" padding-top="3" padding-bottom="1" />
</style>
<style id="recent_file:hover">
<background color="menuitem_hot_face" />
</style>
<style id="recent_file:active">
<background color="listitem_selected_face" />
<text color="listitem_selected_text" />
</style>
<!-- recent_file_detail -->
<style id="recent_file_detail" base="recent_file">
<text color="disabled" valign="top" />
</style>
<!-- news_item -->
<style id="news_item">
<background color="background" />
<text color="text" valign="middle" padding-left="2" padding-right="2" padding-top="3" padding-bottom="3" />
</style>
<style id="news_item:hover">
<background color="menuitem_hot_face" />
</style>
<style id="news_item:active">
<background color="listitem_selected_face" />
<text color="listitem_selected_text" />
</style>
<!-- news_item_detail -->
<style id="news_item_detail" base="news_item">
<text color="disabled" valign="top" wordwrap="true" padding-top="0" padding-bottom="0" />
</style>
</stylesheet>
</skin>
</theme>

View File

@ -1,23 +1,23 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<window id="file_selector" text="">
<vbox id="main">
<box horizontal="true">
<box horizontal="true" noborders="true">
<button text="" id="go_back_button" bevel="2 0 2 0" tooltip="@file_selector.go_back_button_tooltip" />
<button text="" id="go_forward_button" bevel="0 2 0 2" tooltip="@file_selector.go_forward_button_tooltip" />
<button text="" id="go_back_button" style="go_back_button" tooltip="@.go_back_button_tooltip" />
<button text="" id="go_forward_button" style="go_forward_button" tooltip="@.go_forward_button_tooltip" />
</box>
<button text="" id="go_up_button" tooltip="@file_selector.go_up_button_tooltip" />
<button text="" id="new_folder_button" tooltip="@file_selector.new_folder_button_tooltip" />
<button text="" id="go_up_button" style="go_up_button" tooltip="@.go_up_button_tooltip" />
<button text="" id="new_folder_button" style="new_folder_button" tooltip="@.new_folder_button_tooltip" />
<combobox id="location" expansive="true" />
</box>
<vbox id="file_view_placeholder" expansive="true" />
<grid columns="2">
<label text="@file_selector.file_name" />
<label text="@.file_name" />
<box id="file_name_placeholder" cell_align="horizontal" />
<label text="@file_selector.file_type" />
<label text="@.file_type" />
<hbox cell_align="horizontal">
<combobox id="file_type" minwidth="70" />
<vbox>

View File

@ -1,10 +1,10 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
<hbox noborders="true" id="recover_sprites_placeholder">
<boxfiller />
<button id="recover_sprites" text="@.recover" border="8" />
<button id="recover_sprites" text="@.recover" style="recover_sprites_button" />
<boxfiller />
</hbox>
@ -20,8 +20,10 @@
</vbox>
</hbox>
<splitter horizontal="true" noborders="true" childspacing="2"
expansive="true" by="percetage" position="50" >
<splitter vertical="true" noborders="true" childspacing="2">
expansive="true" by="percetage" position="50"
style="workspace_splitter">
<splitter vertical="true" noborders="true" childspacing="2"
style="workspace_splitter">
<vbox id="files_placeholder">
<label text="@home_view.recent_files" style="workspace_label" />
<view id="files_view" expansive="true" style="workspace_view" />

View File

@ -1,5 +1,5 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2015 by David Capello -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<window id="main_window" noborders="true" desktop="true">
<vbox noborders="true" expansive="true">
@ -7,14 +7,16 @@
<hbox noborders="true" id="tabs_placeholder" />
<splitter id="color_bar_splitter"
horizontal="true" expansive="true"
by="pixel">
by="pixel"
style="workspace_splitter">
<vbox noborders="true" id="color_bar_placeholder" />
<vbox noborders="true" expansive="true">
<vbox noborders="true" id="context_bar_placeholder" />
<hbox noborders="true" expansive="true">
<splitter id="timeline_splitter"
vertical="true" expansive="true"
by="percetage" position="100">
by="percetage" position="100"
style="workspace_splitter">
<hbox noborders="true" id="workspace_placeholder" expansive="true" />
<vbox noborders="true" id="timeline_placeholder" expansive="true" />
</splitter>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Aseprite -->
<!-- Copyright (C) 2017 by David Capello -->
<gui>
<window id="slice_properties" text="@.title">
<grid columns="2">
<label text="@.name" />
<hbox>
<entry maxsize="256" id="name" magnet="true" expansive="true" />
<button id="user_data" icon="icon_user_data" tooltip="@.user_data_tooltip" />
</hbox>
<separator horizontal="true" cell_hspan="2" />
<box />
<hbox homogeneous="true">
<label text="@.x" />
<label text="@.y" />
<label text="@.width" />
<label text="@.height" />
</hbox>
<label text="@.bounds" />
<hbox homogeneous="true">
<entry maxsize="8" id="bounds_x" />
<entry maxsize="8" id="bounds_y" />
<entry maxsize="8" id="bounds_w" />
<entry maxsize="8" id="bounds_h" />
</hbox>
<check text="@.center" id="center" />
<hbox homogeneous="true">
<entry maxsize="8" id="center_x" />
<entry maxsize="8" id="center_y" />
<entry maxsize="8" id="center_w" />
<entry maxsize="8" id="center_h" />
</hbox>
<separator horizontal="true" cell_hspan="2" />
<hbox cell_hspan="2">
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>

View File

@ -1,12 +1,12 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<tipwindow id="user_data" text="@.title">
<vbox>
<label text="@.user_data" />
<tipwindow id="user_data">
<vbox style="tooltip_face">
<label text="@.user_data" style="tooltip_text" />
<entry id="text" magnet="true" maxsize="65535" minwidth="128" expansive="true" />
<hbox>
<label text="@.color" />
<label text="@.color" style="tooltip_text" />
<colorpicker id="color" expansive="true" />
</hbox>
</vbox>

View File

@ -486,6 +486,47 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
# [harfbuzz](http://harfbuzz.org)
```
HarfBuzz is licensed under the so-called "Old MIT" license. Details follow.
For parts of HarfBuzz that are licensed under different licenses see individual
files names COPYING in subdirectories where applicable.
Copyright © 2010,2011,2012 Google, Inc.
Copyright © 2012 Mozilla Foundation
Copyright © 2011 Codethink Limited
Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
Copyright © 2009 Keith Stribley
Copyright © 2009 Martin Hosken and SIL International
Copyright © 2007 Chris Wilson
Copyright © 2006 Behdad Esfahbod
Copyright © 2005 David Turner
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
Copyright © 1998-2004 David Turner and Werner Lemberg
For full copyright notices consult the individual files in the package.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the
above copyright notice and the following two paragraphs appear in
all copies of this software.
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
```
# [libjpeg](http://www.ijg.org/)
```
@ -884,6 +925,24 @@ and releases new versions, with the help of Yves Berquin, Andrew
Ellerton, and the tinyXml community.
```
# [ucdn](https://github.com/grigorig/ucdn)
```
Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```
# [Wintab API](http://www.wacomeng.com/windows/docs/WintabBackground.htm)
```

View File

@ -291,15 +291,41 @@ belongs to that cel, etc.
DWORD Flags
1 = Has text
2 = Has color
+ If flags has bit 1:
+ If flags have bit 1:
STRING Text
+ If flags has bit 2:
+ If flags have bit 2:
BYTE Color Red (0-255)
BYTE Color Green (0-255)
BYTE Color Blue (0-255)
BYTE Color Alpha (0-255)
```
### Slices Chunk (0x2021)
Field | Details |
----------- | -------------------------------- |
DWORD | Number of slices
BYTE[8] | Reserved
For each slice... |
DWORD | Number of "slice keys"
DWORD | Flags
| 1 - It's a 9-patches slice
DWORD | Reserved
STRING | Name
For each slice key ... |
DWORD | Frame number (this slice is valid from
| this frame to the end of the animation)
SIGNED WORD | Slice X position
SIGNED WORD | Slice Y position
WORD | Slice Width (can be 0 if this slice hidden in the
| animation from the given frame)
WORD | Slice Height
If flags have bit 1 |
SIGNED WORD | Center X position (relative to slice bounds)
SIGNED WORD | Center Y position
WORD | Center Width
WORD | Center Height
### Notes
#### NOTE.1

2
laf

@ -1 +1 @@
Subproject commit 2630b895fa15b1ff863d47d4ca0ad12e93c22fa9
Subproject commit f232eac37ef0c8a0f5324ed3154b314c64b9eb13

View File

@ -1,5 +1,5 @@
# Aseprite
# Copyright (C) 2001-2016 David Capello
# Copyright (C) 2001-2017 David Capello
######################################################################
# Compiler-specific flags
@ -87,7 +87,6 @@ set(UNDO_TESTS OFF CACHE BOOL "Compile undo tests")
add_subdirectory(undo)
add_subdirectory(cfg)
add_subdirectory(css)
add_subdirectory(doc)
add_subdirectory(filters)
add_subdirectory(fixmath)
@ -97,6 +96,7 @@ add_subdirectory(gfx)
add_subdirectory(net)
add_subdirectory(render)
add_subdirectory(docio)
add_subdirectory(ft)
add_subdirectory(she)
add_subdirectory(ui)
@ -193,7 +193,6 @@ if(ENABLE_TESTS)
find_tests(gfx gfx-lib)
find_tests(doc doc-lib)
find_tests(render render-lib)
find_tests(css css-lib)
find_tests(ui ui-lib)
find_tests(app/cli app-lib)
find_tests(app/file app-lib)

View File

@ -15,7 +15,6 @@ because they don't depend on any other component.
* [allegro](allegro/): Modified version of [Allegro](http://alleg.sourceforge.net/) library, used for keyboard/mouse input, and drawing 2D graphics on screen.
* [clip](https://github.com/aseprite/clip): Clipboard library.
* [css](css/): Pseudo-style sheet library.
* [fixmath](fixmath/): Fixed point operations (original code from Allegro code by Shawn Hargreaves).
* [flic](https://github.com/aseprite/flic): Library to load/save FLI/FLC files.
* [gfx](gfx/): Abstract graphics structures like point, size, rectangle, region, color, etc.

View File

@ -41,15 +41,15 @@ add_custom_command(
DEPENDS gen)
list(APPEND generated_files ${output_fn})
# Generate skin.xml.h from data/skins/default/skin.xml
set(skin_xml ${CMAKE_SOURCE_DIR}/data/skins/default/skin.xml)
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/skin.xml.h)
# Generate theme.xml.h from data/themes/default/theme.xml
set(theme_xml ${CMAKE_SOURCE_DIR}/data/themes/default/theme.xml)
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/theme.xml.h)
add_custom_command(
OUTPUT ${output_fn}
COMMAND ${CMAKE_BINARY_DIR}/bin/gen --input ${skin_xml} --skin > ${output_fn}.tmp
COMMAND ${CMAKE_BINARY_DIR}/bin/gen --input ${theme_xml} --theme > ${output_fn}.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${output_fn}.tmp ${output_fn}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
MAIN_DEPENDENCY ${skin_xml}
MAIN_DEPENDENCY ${theme_xml}
DEPENDS gen)
list(APPEND generated_files ${output_fn})
@ -89,6 +89,20 @@ include_directories(${CMAKE_BINARY_DIR}/third_party/cmark)
######################################################################
# app-lib target
# These specific-platform files should be in an external library
# (e.g. "base" or "she").
set(app_platform_files)
if(WIN32)
set(app_platform_files
font_path_win.cpp)
elseif(APPLE)
set(app_platform_files
font_path_osx.mm)
else()
set(app_platform_files
font_path_unix.cpp)
endif()
set(data_recovery_files)
if(NOT ENABLE_TRIAL_MODE)
set(data_recovery_files
@ -148,6 +162,7 @@ add_library(app-lib
cmd/add_frame_tag.cpp
cmd/add_layer.cpp
cmd/add_palette.cpp
cmd/add_slice.cpp
cmd/background_from_layer.cpp
cmd/clear_cel.cpp
cmd/clear_image.cpp
@ -174,6 +189,7 @@ add_library(app-lib
cmd/remove_frame_tag.cpp
cmd/remove_layer.cpp
cmd/remove_palette.cpp
cmd/remove_slice.cpp
cmd/replace_image.cpp
cmd/reselect_mask.cpp
cmd/set_cel_bounds.cpp
@ -195,6 +211,8 @@ add_library(app-lib
cmd/set_palette.cpp
cmd/set_pixel_format.cpp
cmd/set_pixel_ratio.cpp
cmd/set_slice_key.cpp
cmd/set_slice_name.cpp
cmd/set_sprite_size.cpp
cmd/set_total_frames.cpp
cmd/set_transparent_color.cpp
@ -207,6 +225,7 @@ add_library(app-lib
cmd/with_frame_tag.cpp
cmd/with_image.cpp
cmd/with_layer.cpp
cmd/with_slice.cpp
cmd/with_sprite.cpp
cmd_sequence.cpp
cmd_transaction.cpp
@ -293,6 +312,7 @@ add_library(app-lib
commands/cmd_remove_frame.cpp
commands/cmd_remove_frame_tag.cpp
commands/cmd_remove_layer.cpp
commands/cmd_remove_slice.cpp
commands/cmd_repeat_last_export.cpp
commands/cmd_reselect_mask.cpp
commands/cmd_reverse_frames.cpp
@ -310,6 +330,7 @@ add_library(app-lib
commands/cmd_set_palette_entry_size.cpp
commands/cmd_set_same_ink.cpp
commands/cmd_show.cpp
commands/cmd_slice_properties.cpp
commands/cmd_sprite_properties.cpp
commands/cmd_sprite_size.cpp
commands/cmd_switch_colors.cpp
@ -356,6 +377,7 @@ add_library(app-lib
file_system.cpp
filename_formatter.cpp
flatten.cpp
font_path.cpp
gui_xml.cpp
i18n/strings.cpp
ini_file.cpp
@ -418,6 +440,7 @@ add_library(app-lib
ui/editor/editor_view.cpp
ui/editor/moving_cel_state.cpp
ui/editor/moving_pixels_state.cpp
ui/editor/moving_slice_state.cpp
ui/editor/moving_symmetry_state.cpp
ui/editor/navigate_state.cpp
ui/editor/pivot_helpers.cpp
@ -455,15 +478,13 @@ add_library(app-lib
ui/search_entry.cpp
ui/select_accelerator.cpp
ui/skin/button_icon_impl.cpp
ui/skin/font_data.cpp
ui/skin/skin_part.cpp
ui/skin/skin_property.cpp
ui/skin/skin_slider_property.cpp
ui/skin/skin_style_property.cpp
ui/skin/skin_theme.cpp
ui/skin/style.cpp
ui/skin/style_sheet.cpp
ui/slice_window.cpp
ui/status_bar.cpp
ui/styled_button.cpp
ui/tabs.cpp
ui/timeline.cpp
ui/toolbar.cpp
@ -490,6 +511,7 @@ add_library(app-lib
widget_loader.cpp
xml_document.cpp
xml_exception.cpp
${app_platform_files}
${data_recovery_files}
${scripting_files}
${generated_files})
@ -498,7 +520,6 @@ target_link_libraries(app-lib
laf-base
cfg-lib
clip
css-lib
doc-lib
docio-lib
filters-lib
@ -517,7 +538,8 @@ target_link_libraries(app-lib
${PNG_LIBRARIES}
${WEBP_LIBRARIES}
${ZLIB_LIBRARIES}
${FREETYPE_LIBRARIES})
${FREETYPE_LIBRARIES}
${HARFBUZZ_LIBRARIES})
if(ENABLE_SCRIPTING)
target_link_libraries(app-lib script-lib)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -89,6 +89,7 @@ void AppMenus::reload()
m_celPopupMenu.reset(loadMenuById(handle, "cel_popup"));
m_celMovementPopupMenu.reset(loadMenuById(handle, "cel_movement_popup"));
m_frameTagPopupMenu.reset(loadMenuById(handle, "frame_tag_popup"));
m_slicePopupMenu.reset(loadMenuById(handle, "slice_popup"));
m_palettePopupMenu.reset(loadMenuById(handle, "palette_popup"));
m_inkPopupMenu.reset(loadMenuById(handle, "ink_popup"));
@ -231,12 +232,14 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem)
// Create the item
AppMenuItem* menuitem = new AppMenuItem(elem->Attribute("text"), command, params);
if (!menuitem)
return NULL;
return nullptr;
/* has it a ID? */
menuitem->processMnemonicFromText();
// Has it a ID?
const char* id = elem->Attribute("id");
if (id) {
/* recent list menu */
// Recent list menu
if (strcmp(id, "recent_list") == 0) {
m_recentListMenuitem = menuitem;
}
@ -282,6 +285,7 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command, const Param
m_celPopupMenu,
m_celMovementPopupMenu,
m_frameTagPopupMenu,
m_slicePopupMenu,
m_palettePopupMenu,
m_inkPopupMenu
};

View File

@ -46,6 +46,7 @@ namespace app {
Menu* getCelPopupMenu() { return m_celPopupMenu; }
Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu; }
Menu* getFrameTagPopupMenu() { return m_frameTagPopupMenu; }
Menu* getSlicePopupMenu() { return m_slicePopupMenu; }
Menu* getPalettePopupMenu() { return m_palettePopupMenu; }
Menu* getInkPopupMenu() { return m_inkPopupMenu; }
@ -67,6 +68,7 @@ namespace app {
base::UniquePtr<Menu> m_celPopupMenu;
base::UniquePtr<Menu> m_celMovementPopupMenu;
base::UniquePtr<Menu> m_frameTagPopupMenu;
base::UniquePtr<Menu> m_slicePopupMenu;
base::UniquePtr<Menu> m_palettePopupMenu;
base::UniquePtr<Menu> m_inkPopupMenu;
obs::scoped_connection m_recentFilesConn;

64
src/app/cmd/add_slice.cpp Normal file
View File

@ -0,0 +1,64 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/add_slice.h"
#include "doc/slice.h"
#include "doc/slice_io.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
using namespace doc;
AddSlice::AddSlice(Sprite* sprite, Slice* slice)
: WithSprite(sprite)
, WithSlice(slice)
, m_size(0)
{
}
void AddSlice::onExecute()
{
Sprite* sprite = this->sprite();
Slice* slice = this->slice();
sprite->slices().add(slice);
sprite->incrementVersion();
}
void AddSlice::onUndo()
{
Sprite* sprite = this->sprite();
Slice* slice = this->slice();
write_slice(m_stream, slice);
m_size = size_t(m_stream.tellp());
sprite->slices().remove(slice);
sprite->incrementVersion();
delete slice;
}
void AddSlice::onRedo()
{
Sprite* sprite = this->sprite();
Slice* slice = read_slice(m_stream);
sprite->slices().add(slice);
sprite->incrementVersion();
m_stream.str(std::string());
m_stream.clear();
m_size = 0;
}
} // namespace cmd
} // namespace app

43
src/app/cmd/add_slice.h Normal file
View File

@ -0,0 +1,43 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_ADD_SLICE_H_INCLUDED
#define APP_CMD_ADD_SLICE_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_slice.h"
#include "app/cmd/with_sprite.h"
#include <sstream>
namespace app {
namespace cmd {
using namespace doc;
class AddSlice : public Cmd
, public WithSprite
, public WithSlice {
public:
AddSlice(Sprite* sprite, Slice* slice);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
private:
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -0,0 +1,39 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/remove_slice.h"
namespace app {
namespace cmd {
using namespace doc;
RemoveSlice::RemoveSlice(Sprite* sprite, Slice* slice)
: AddSlice(sprite, slice)
{
}
void RemoveSlice::onExecute()
{
AddSlice::onUndo();
}
void RemoveSlice::onUndo()
{
AddSlice::onRedo();
}
void RemoveSlice::onRedo()
{
AddSlice::onUndo();
}
} // namespace cmd
} // namespace app

View File

@ -0,0 +1,30 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_REMOVE_SLICE_H_INCLUDED
#define APP_CMD_REMOVE_SLICE_H_INCLUDED
#pragma once
#include "app/cmd/add_slice.h"
namespace app {
namespace cmd {
using namespace doc;
class RemoveSlice : public AddSlice {
public:
RemoveSlice(Sprite* sprite, Slice* slice);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -0,0 +1,55 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/set_slice_key.h"
#include "doc/slice.h"
#include "doc/slices.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
SetSliceKey::SetSliceKey(Slice* slice,
const doc::frame_t frame,
const doc::SliceKey& sliceKey)
: WithSlice(slice)
, m_frame(frame)
, m_newSliceKey(sliceKey)
{
auto it = slice->getIteratorByFrame(frame);
if (it != slice->end() && it->frame() == frame)
m_oldSliceKey = *it->value();
}
void SetSliceKey::onExecute()
{
if (!m_newSliceKey.isEmpty())
slice()->insert(m_frame, m_newSliceKey);
else
slice()->remove(m_frame);
slice()->incrementVersion();
slice()->owner()->sprite()->incrementVersion();
}
void SetSliceKey::onUndo()
{
if (!m_oldSliceKey.isEmpty())
slice()->insert(m_frame, m_oldSliceKey);
else
slice()->remove(m_frame);
slice()->incrementVersion();
slice()->owner()->sprite()->incrementVersion();
}
} // namespace cmd
} // namespace app

View File

@ -0,0 +1,43 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_SET_SLICE_KEY_H_INCLUDED
#define APP_CMD_SET_SLICE_KEY_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_slice.h"
#include "doc/frame.h"
#include "doc/slice.h"
namespace app {
namespace cmd {
using namespace doc;
class SetSliceKey : public Cmd
, public WithSlice {
public:
SetSliceKey(Slice* slice,
const doc::frame_t frame,
const doc::SliceKey& sliceKey);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
private:
doc::frame_t m_frame;
doc::SliceKey m_oldSliceKey;
doc::SliceKey m_newSliceKey;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -0,0 +1,41 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/set_slice_name.h"
#include "doc/document.h"
#include "doc/document_event.h"
#include "doc/slice.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
SetSliceName::SetSliceName(Slice* slice, const std::string& name)
: WithSlice(slice)
, m_oldName(slice->name())
, m_newName(name)
{
}
void SetSliceName::onExecute()
{
slice()->setName(m_newName);
slice()->incrementVersion();
}
void SetSliceName::onUndo()
{
slice()->setName(m_oldName);
slice()->incrementVersion();
}
} // namespace cmd
} // namespace app

View File

@ -0,0 +1,40 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_SET_SLICE_NAME_H_INCLUDED
#define APP_CMD_SET_SLICE_NAME_H_INCLUDED
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_slice.h"
#include <string>
namespace app {
namespace cmd {
using namespace doc;
class SetSliceName : public Cmd
, public WithSlice {
public:
SetSliceName(Slice* slice, const std::string& name);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this);
}
private:
std::string m_oldName;
std::string m_newName;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -0,0 +1,31 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/with_slice.h"
#include "doc/slice.h"
namespace app {
namespace cmd {
using namespace doc;
WithSlice::WithSlice(Slice* slice)
: m_sliceId(slice->id())
{
}
Slice* WithSlice::slice()
{
return get<Slice>(m_sliceId);
}
} // namespace cmd
} // namespace app

33
src/app/cmd/with_slice.h Normal file
View File

@ -0,0 +1,33 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_CMD_WITH_SLICE_H_INCLUDED
#define APP_CMD_WITH_SLICE_H_INCLUDED
#pragma once
#include "doc/object_id.h"
namespace doc {
class Slice;
}
namespace app {
namespace cmd {
using namespace doc;
class WithSlice {
public:
WithSlice(Slice* slice);
Slice* slice();
private:
ObjectId m_sliceId;
};
} // namespace cmd
} // namespace app
#endif

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -72,7 +72,9 @@ void AboutCommand::onExecute(Context* context)
grid->addChildInCell(website, 2, 1, 0);
grid->addChildInCell(bottom_box1, 2, 1, 0);
close_button->processMnemonicFromText();
close_button->setFocusMagnet(true);
close_button->setMinSize(gfx::Size(60*guiscale(), 0));
author3_line->addChild(author3);
author3_line->addChild(author4);

View File

@ -13,7 +13,6 @@
#include "app/commands/command.h"
#include "app/context.h"
#include "app/file_selector.h"
#include "app/modules/gui.h"
#include "app/resource_finder.h"
#include "app/tools/tool.h"
#include "app/tools/tool_box.h"
@ -214,7 +213,7 @@ private:
g->drawUIText(text(), fg, bg,
gfx::Point(
bounds.x + m_level*16 * guiscale(),
bounds.y + 2*guiscale()));
bounds.y + 2*guiscale()), 0);
if (m_key && !m_key->accels().empty()) {
std::string buf;
@ -277,13 +276,13 @@ private:
m_changeConn = obs::connection();
m_changeButton.reset(new Button(""));
m_changeConn = m_changeButton->Click.connect(base::Bind<void>(&KeyItem::onChangeAccel, this, i));
setup_mini_look(m_changeButton.get());
m_changeButton->setStyle(SkinTheme::instance()->newStyles.miniButton());
addChild(m_changeButton.get());
m_deleteConn = obs::connection();
m_deleteButton.reset(new Button(""));
m_deleteConn = m_deleteButton->Click.connect(base::Bind<void>(&KeyItem::onDeleteAccel, this, i));
setup_mini_look(m_deleteButton.get());
m_deleteButton->setStyle(SkinTheme::instance()->newStyles.miniButton());
addChild(m_deleteButton.get());
m_changeButton->setBgColor(gfx::ColorNone);
@ -292,12 +291,13 @@ private:
const char* label = "x";
m_deleteButton->setBgColor(gfx::ColorNone);
m_deleteButton->setBounds(gfx::Rect(
itemBounds.x + itemBounds.w + 2*guiscale(),
itemBounds.y,
Graphics::measureUITextLength(
label, font()) + 4*guiscale(),
itemBounds.h));
m_deleteButton->setBounds(
gfx::Rect(
itemBounds.x + itemBounds.w + 2*guiscale(),
itemBounds.y,
Graphics::measureUITextLength(
label, font()) + 4*guiscale(),
itemBounds.h));
m_deleteButton->setText(label);
invalidate();
@ -309,7 +309,7 @@ private:
m_addConn = obs::connection();
m_addButton.reset(new Button(""));
m_addConn = m_addButton->Click.connect(base::Bind<void>(&KeyItem::onAddAccel, this));
setup_mini_look(m_addButton.get());
m_addButton->setStyle(SkinTheme::instance()->newStyles.miniButton());
addChild(m_addButton.get());
itemBounds.w = 8*guiscale() + Graphics::measureUITextLength("Add", font());
@ -510,7 +510,7 @@ private:
if (!group) {
group = new Separator(
section()->children()[sectionIdx]->text(), HORIZONTAL);
group->setBgColor(SkinTheme::instance()->colors.background());
group->setStyle(SkinTheme::instance()->newStyles.separatorInView());
searchList()->addChild(group);
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -124,7 +124,9 @@ void OpenFileCommand::onExecute(Context* context)
if (m_filename.empty())
return;
int flags = (m_repeatCheckbox ? FILE_LOAD_SEQUENCE_ASK_CHECKBOX: 0);
int flags =
FILE_LOAD_DATA_FILE |
(m_repeatCheckbox ? FILE_LOAD_SEQUENCE_ASK_CHECKBOX: 0);
switch (m_seqDecision) {
case SequenceDecision::Ask:

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -17,6 +17,7 @@
#include "app/resource_finder.h"
#include "app/send_crash.h"
#include "app/ui/color_button.h"
#include "app/ui/skin/skin_theme.h"
#include "base/bind.h"
#include "base/convert_to.h"
#include "base/fs.h"
@ -589,7 +590,7 @@ private:
static std::string userThemeFolder() {
ResourceFinder rf;
rf.includeDataDir("skins");
rf.includeDataDir(skin::SkinTheme::kThemesFolderName);
// Create user folder to store skins
try {
@ -605,7 +606,7 @@ private:
static std::vector<std::string> themeFolders() {
ResourceFinder rf;
rf.includeDataDir("skins");
rf.includeDataDir(skin::SkinTheme::kThemesFolderName);
std::vector<std::string> paths;
while (rf.next())

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -40,8 +40,7 @@ RefreshCommand::RefreshCommand()
void RefreshCommand::onExecute(Context* context)
{
ui::CurrentTheme::get()->regenerate();
ui::get_theme()->regenerate();
app_refresh_screen();
// Print memory information

View File

@ -0,0 +1,114 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/app.h"
#include "app/cmd/remove_slice.h"
#include "app/cmd/set_slice_key.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/document_api.h"
#include "app/modules/gui.h"
#include "app/ui/status_bar.h"
#include "app/transaction.h"
#include "base/convert_to.h"
#include "doc/slice.h"
#include "doc/sprite.h"
#include "ui/alert.h"
#include "ui/widget.h"
namespace app {
class RemoveSliceCommand : public Command {
public:
RemoveSliceCommand();
Command* clone() const override { return new RemoveSliceCommand(*this); }
protected:
void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
private:
std::string m_sliceName;
ObjectId m_sliceId;
};
RemoveSliceCommand::RemoveSliceCommand()
: Command("RemoveSlice",
"Remove Slice",
CmdRecordableFlag)
{
}
void RemoveSliceCommand::onLoadParams(const Params& params)
{
m_sliceName = params.get("name");
std::string id = params.get("id");
if (!id.empty())
m_sliceId = ObjectId(base::convert_to<doc::ObjectId>(id));
else
m_sliceId = NullId;
}
bool RemoveSliceCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite |
ContextFlags::HasActiveLayer);
}
void RemoveSliceCommand::onExecute(Context* context)
{
const ContextReader reader(context);
const Sprite* sprite = reader.sprite();
frame_t frame = reader.frame();
const Slice* foundSlice = nullptr;
if (!m_sliceName.empty())
foundSlice = sprite->slices().getByName(m_sliceName);
else if (m_sliceId != NullId)
foundSlice = sprite->slices().getById(m_sliceId);
if (!foundSlice)
return;
std::string sliceName = foundSlice->name();
{
ContextWriter writer(reader, 500);
Document* document(writer.document());
Sprite* sprite(writer.sprite());
Transaction transaction(writer.context(), "Remove Slice");
Slice* slice = const_cast<Slice*>(foundSlice);
if (slice->size() > 1) {
transaction.execute(new cmd::SetSliceKey(slice, frame, SliceKey()));
}
else {
transaction.execute(new cmd::RemoveSlice(sprite, slice));
}
transaction.commit();
document->notifyGeneralUpdate();
}
StatusBar::instance()->invalidate();
if (!sliceName.empty())
StatusBar::instance()->showTip(1000, "Slice '%s' removed", sliceName.c_str());
else
StatusBar::instance()->showTip(1000, "Slice removed");
}
Command* CommandFactory::createRemoveSliceCommand()
{
return new RemoveSliceCommand;
}
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -171,6 +171,28 @@ protected:
}
};
class ShowSlicesCommand : public Command {
public:
ShowSlicesCommand()
: Command("ShowSlices",
"Show Slices",
CmdUIOnlyFlag) {
}
Command* clone() const override { return new ShowSlicesCommand(*this); }
protected:
bool onChecked(Context* ctx) override {
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
return docPref.show.slices();
}
void onExecute(Context* ctx) override {
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
docPref.show.slices(!docPref.show.slices());
}
};
Command* CommandFactory::createShowExtrasCommand()
{
return new ShowExtrasCommand;
@ -201,4 +223,9 @@ Command* CommandFactory::createShowBrushPreviewCommand()
return new ShowBrushPreviewCommand;
}
Command* CommandFactory::createShowSlicesCommand()
{
return new ShowSlicesCommand;
}
} // namespace app

View File

@ -0,0 +1,119 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/cmd/set_slice_key.h"
#include "app/cmd/set_slice_name.h"
#include "app/cmd/set_user_data.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/transaction.h"
#include "app/ui/slice_window.h"
#include "base/convert_to.h"
#include "doc/slice.h"
#include "doc/sprite.h"
namespace app {
using namespace ui;
class SlicePropertiesCommand : public Command {
public:
SlicePropertiesCommand();
Command* clone() const override { return new SlicePropertiesCommand(*this); }
protected:
void onLoadParams(const Params& params) override;
bool onEnabled(Context* context) override;
void onExecute(Context* context) override;
private:
std::string m_sliceName;
ObjectId m_sliceId;
};
SlicePropertiesCommand::SlicePropertiesCommand()
: Command("SliceProperties",
"Slice Properties",
CmdUIOnlyFlag)
, m_sliceId(NullId)
{
}
void SlicePropertiesCommand::onLoadParams(const Params& params)
{
m_sliceName = params.get("name");
std::string id = params.get("id");
if (!id.empty())
m_sliceId = ObjectId(base::convert_to<doc::ObjectId>(id));
else
m_sliceId = NullId;
}
bool SlicePropertiesCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
}
void SlicePropertiesCommand::onExecute(Context* context)
{
const ContextReader reader(context);
const Sprite* sprite = reader.sprite();
frame_t frame = reader.frame();
const Slice* foundSlice = nullptr;
if (!m_sliceName.empty())
foundSlice = sprite->slices().getByName(m_sliceName);
else if (m_sliceId != NullId)
foundSlice = sprite->slices().getById(m_sliceId);
if (!foundSlice)
return;
const doc::SliceKey* key = foundSlice->getByFrame(frame);
if (!key)
return;
SliceWindow window(sprite, foundSlice, frame);
if (!window.show())
return;
{
ContextWriter writer(reader, 500);
Transaction transaction(writer.context(), "Slice Properties");
Slice* slice = const_cast<Slice*>(foundSlice);
std::string name = window.nameValue();
if (slice->name() != name)
transaction.execute(new cmd::SetSliceName(slice, name));
if (slice->userData() != window.userDataValue())
transaction.execute(new cmd::SetUserData(slice, window.userDataValue()));
if (key->bounds() != window.boundsValue() ||
key->center() != window.centerValue()) {
SliceKey newKey = *key;
newKey.setBounds(window.boundsValue());
newKey.setCenter(window.centerValue());
transaction.execute(new cmd::SetSliceKey(slice, frame, newKey));
}
transaction.commit();
writer.document()->notifyGeneralUpdate();
}
}
Command* CommandFactory::createSlicePropertiesCommand()
{
return new SlicePropertiesCommand;
}
} // namespace app

View File

@ -98,6 +98,7 @@ FOR_EACH_COMMAND(Refresh)
FOR_EACH_COMMAND(RemoveFrame)
FOR_EACH_COMMAND(RemoveFrameTag)
FOR_EACH_COMMAND(RemoveLayer)
FOR_EACH_COMMAND(RemoveSlice)
FOR_EACH_COMMAND(RepeatLastExport)
FOR_EACH_COMMAND(ReplaceColor)
FOR_EACH_COMMAND(ReselectMask)
@ -125,6 +126,8 @@ FOR_EACH_COMMAND(ShowLayerEdges)
FOR_EACH_COMMAND(ShowOnionSkin)
FOR_EACH_COMMAND(ShowPixelGrid)
FOR_EACH_COMMAND(ShowSelectionEdges)
FOR_EACH_COMMAND(ShowSlices)
FOR_EACH_COMMAND(SliceProperties)
FOR_EACH_COMMAND(SnapToGrid)
FOR_EACH_COMMAND(SpriteProperties)
FOR_EACH_COMMAND(SpriteSize)

View File

@ -39,6 +39,12 @@ FilterWindow::FilterWindow(const char* title, const char* cfgSection,
, m_showPreview("&Preview")
, m_tiledCheck(withTiled == WithTiledCheckBox ? new CheckBox("&Tiled") : NULL)
{
m_okButton.processMnemonicFromText();
m_cancelButton.processMnemonicFromText();
m_showPreview.processMnemonicFromText();
if (m_tiledCheck)
m_tiledCheck->processMnemonicFromText();
m_targetButton.setTarget(filterMgr->getTarget());
m_targetButton.TargetChange.connect(&FilterWindow::onTargetButtonChange, this);
m_okButton.Click.connect(&FilterWindow::onOk, this);

View File

@ -59,10 +59,8 @@ Console::Console(Context* ctx)
TextBox* textbox = new TextBox("", WORDWRAP);
Button* button = new Button("&Cancel");
if (!grid || !textbox || !button)
return;
// The "button" closes the console
button->processMnemonicFromText();
button->Click.connect(base::Bind<void>(&Window::closeWindow, window, button));
view->attachToView(textbox);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -31,6 +31,8 @@
#include "doc/layer.h"
#include "doc/palette.h"
#include "doc/palette_io.h"
#include "doc/slice.h"
#include "doc/slice_io.h"
#include "doc/sprite.h"
#include "doc/string_io.h"
#include "doc/subobjects_io.h"
@ -286,6 +288,17 @@ private:
}
}
// Read slices
int nslices = read32(s);
if (nslices >= 1 && nslices < 0xffffff) {
for (int i = 0; i < nslices; ++i) {
ObjectId sliceId = read32(s);
Slice* slice = loadObject<Slice*>("slice", sliceId, &Reader::readSlice);
if (slice)
spr->slices().add(slice);
}
}
return spr.release();
}
@ -350,6 +363,10 @@ private:
return read_frame_tag(s, false);
}
Slice* readSlice(std::ifstream& s) {
return read_slice(s, false);
}
// Fix issues that the restoration process could produce.
void fixUndetectedDocumentIssues(app::Document* doc) {
Sprite* spr = doc->sprite();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -30,6 +30,8 @@
#include "doc/layer.h"
#include "doc/palette.h"
#include "doc/palette_io.h"
#include "doc/slice.h"
#include "doc/slice_io.h"
#include "doc/sprite.h"
#include "doc/string_io.h"
@ -72,6 +74,10 @@ public:
if (!saveObject("frtag", frtag, &Writer::writeFrameTag))
return false;
for (Slice* slice : spr->slices())
if (!saveObject("slice", slice, &Writer::writeSlice))
return false;
// Get all layers (visible, hidden, subchildren, etc.)
LayerList layers = spr->allLayers();
@ -155,6 +161,11 @@ private:
for (FrameTag* frtag : spr->frameTags())
write32(s, frtag->id());
// IDs of all slices
write32(s, spr->slices().size());
for (const Slice* slice : spr->slices())
write32(s, slice->id());
return true;
}
@ -220,6 +231,11 @@ private:
return true;
}
bool writeSlice(std::ofstream& s, Slice* slice) {
write_slice(s, slice);
return true;
}
template<typename T>
bool saveObject(const char* prefix, T* obj, bool (Writer::*writeMember)(std::ofstream&, T*)) {
if (isCanceled())

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -39,6 +39,7 @@
#define ASE_FILE_CHUNK_FRAME_TAGS 0x2018
#define ASE_FILE_CHUNK_PALETTE 0x2019
#define ASE_FILE_CHUNK_USER_DATA 0x2020
#define ASE_FILE_CHUNK_SLICES 0x2021
#define ASE_FILE_LAYER_IMAGE 0
#define ASE_FILE_LAYER_GROUP 1
@ -54,6 +55,8 @@
#define ASE_CEL_EXTRA_FLAG_PRECISE_BOUNDS 1
#define ASE_SLICE_FLAG_HAS_CENTER_BOUNDS 1
namespace app {
using namespace base;
@ -139,6 +142,9 @@ static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Ma
static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags);
static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags,
const frame_t fromFrame, const frame_t toFrame);
static void ase_file_read_slices_chunk(FILE* f, Slices* slices);
static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header, const Slices* slices,
const frame_t fromFrame, const frame_t toFrame);
static void ase_file_read_user_data_chunk(FILE* f, UserData* userData);
static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_header, const UserData* userData);
static bool ase_has_groups(LayerGroup* group);
@ -325,6 +331,10 @@ bool AseFormat::onLoad(FileOp* fop)
ase_file_read_frame_tags_chunk(f, &sprite->frameTags());
break;
case ASE_FILE_CHUNK_SLICES:
ase_file_read_slices_chunk(f, &sprite->slices());
break;
case ASE_FILE_CHUNK_USER_DATA: {
UserData userData;
ase_file_read_user_data_chunk(f, &userData);
@ -455,6 +465,13 @@ bool AseFormat::onSave(FileOp* fop)
ase_file_write_frame_tags_chunk(f, &frame_header, &sprite->frameTags(),
fop->roi().fromFrame(),
fop->roi().toFrame());
// Writer slice chunks
if (sprite->slices().size() > 0)
ase_file_write_slices_chunk(f, &frame_header,
&sprite->slices(),
fop->roi().fromFrame(),
fop->roi().toFrame());
}
// Write cel chunks
@ -1593,7 +1610,7 @@ static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_head
int tags = 0;
for (const FrameTag* tag : *frameTags) {
// Skip tags that are outside the given ROI
// Skip tags that are outside of the given ROI
if (tag->fromFrame() > toFrame ||
tag->toFrame() < fromFrame)
continue;
@ -1668,6 +1685,120 @@ static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_heade
}
}
static void ase_file_read_slices_chunk(FILE* f, Slices* slices)
{
size_t nslices = fgetl(f); // Number of slices
fgetl(f); // 8 bytes reserved
fgetl(f);
for (size_t i=0; i<nslices; ++i) {
size_t nkeys = fgetl(f); // Number of keys
int flags = fgetl(f); // Flags
fgetl(f); // 4 bytes reserved
std::string name = ase_file_read_string(f); // Name
base::UniquePtr<Slice> slice(new Slice);
slice->setName(name);
// For each key
for (size_t j=0; j<nkeys; ++j) {
frame_t frame = fgetl(f);
gfx::Rect bounds, center;
bounds.x = fgetl(f);
bounds.y = fgetl(f);
bounds.w = fgetl(f);
bounds.h = fgetl(f);
if (flags & ASE_SLICE_FLAG_HAS_CENTER_BOUNDS) {
center.x = fgetl(f);
center.y = fgetl(f);
center.w = fgetl(f);
center.h = fgetl(f);
}
slice->insert(frame, SliceKey(bounds, center));
}
slices->add(slice);
slice.release();
}
}
static void ase_file_write_slices_chunk(FILE* f, ASE_FrameHeader* frame_header,
const Slices* slices,
const frame_t fromFrame,
const frame_t toFrame)
{
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_SLICES);
size_t nslices = 0;
for (Slice* slice : *slices) {
// Skip slices that are outside of the given ROI
if (slice->range(fromFrame, toFrame).empty())
continue;
++nslices;
}
fputl(nslices, f);
fputl(0, f); // 8 reserved bytes
fputl(0, f);
for (Slice* slice : *slices) {
// Skip slices that are outside of the given ROI
auto range = slice->range(fromFrame, toFrame);
if (range.empty())
continue;
int flags = 0;
for (auto key : range) {
if (key && !key->center().isEmpty()) {
flags |= ASE_SLICE_FLAG_HAS_CENTER_BOUNDS;
break;
}
}
fputl(range.countKeys(), f); // number of keys
fputl(flags, f); // flags
fputl(0, f); // 4 bytes reserved
ase_file_write_string(f, slice->name()); // slice name
frame_t frame = fromFrame;
const SliceKey* oldKey = nullptr;
for (auto key : range) {
if (frame == fromFrame || key != oldKey) {
fputl(frame, f);
fputl(key ? key->bounds().x: 0, f);
fputl(key ? key->bounds().y: 0, f);
fputl(key ? key->bounds().w: 0, f);
fputl(key ? key->bounds().h: 0, f);
if (flags & ASE_SLICE_FLAG_HAS_CENTER_BOUNDS) {
if (key && !key->center().isEmpty()) {
fputl(key->center().x, f);
fputl(key->center().y, f);
fputl(key->center().w, f);
fputl(key->center().h, f);
}
else {
fputl(0, f);
fputl(0, f);
fputl(key ? key->bounds().w: 0, f);
fputl(key ? key->bounds().h: 0, f);
}
}
oldKey = key;
}
++frame;
}
--nslices;
}
ASSERT(nslices == 0);
}
static bool ase_has_groups(LayerGroup* group)
{
for (Layer* child : group->layers()) {

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -21,12 +21,14 @@
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/status_bar.h"
#include "app/xml_document.h"
#include "base/fs.h"
#include "base/mutex.h"
#include "base/scoped_lock.h"
#include "base/shared_ptr.h"
#include "base/string.h"
#include "doc/doc.h"
#include "doc/slice.h" // TODO add this header file in doc.h
#include "docio/detect_format.h"
#include "render/quantization.h"
#include "render/render.h"
@ -41,6 +43,36 @@ namespace app {
using namespace base;
namespace {
void updateXmlPartFromSliceKey(const SliceKey* key, TiXmlElement* xmlPart)
{
xmlPart->SetAttribute("x", key->bounds().x);
xmlPart->SetAttribute("y", key->bounds().y);
if (key->center().isEmpty()) {
xmlPart->SetAttribute("w", key->bounds().w);
xmlPart->SetAttribute("h", key->bounds().h);
if (xmlPart->Attribute("w1")) xmlPart->RemoveAttribute("w1");
if (xmlPart->Attribute("w2")) xmlPart->RemoveAttribute("w2");
if (xmlPart->Attribute("w3")) xmlPart->RemoveAttribute("w3");
if (xmlPart->Attribute("h1")) xmlPart->RemoveAttribute("h1");
if (xmlPart->Attribute("h2")) xmlPart->RemoveAttribute("h2");
if (xmlPart->Attribute("h3")) xmlPart->RemoveAttribute("h3");
}
else {
xmlPart->SetAttribute("w1", key->center().x);
xmlPart->SetAttribute("w2", key->center().w);
xmlPart->SetAttribute("w3", key->bounds().w - key->center().x2());
xmlPart->SetAttribute("h1", key->center().y);
xmlPart->SetAttribute("h2", key->center().h);
xmlPart->SetAttribute("h3", key->bounds().h - key->center().y2());
if (xmlPart->Attribute("w")) xmlPart->RemoveAttribute("w");
if (xmlPart->Attribute("h")) xmlPart->RemoveAttribute("h");
}
}
} // anonymous namespace
std::string get_readable_extensions()
{
std::string buf;
@ -285,13 +317,21 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context, const char* filena
}
}
}
else
else {
fop->m_filename = filename;
}
/* load just one frame */
// Load just one frame
if (flags & FILE_LOAD_ONE_FRAME)
fop->m_oneframe = true;
// Does data file exist?
if (flags & FILE_LOAD_DATA_FILE) {
std::string dataFilename = base::replace_extension(filename, "aseprite-data");
if (base::is_file(dataFilename))
fop->m_dataFilename = dataFilename;
}
done:;
return fop.release();
}
@ -520,6 +560,11 @@ FileOp* FileOp::createSaveDocumentOperation(const Context* context,
fop->m_document->setFormatOptions(opts);
}
// Does data file exist?
std::string dataFilename = base::replace_extension(filename, "aseprite-data");
if (base::is_file(dataFilename))
fop->m_dataFilename = dataFilename;
return fop.release();
}
@ -650,9 +695,17 @@ void FileOp::operate(IFileOpProgress* progress)
// Direct load from one file.
else {
// Call the "load" procedure.
if (!m_format->load(this))
if (!m_format->load(this)) {
setError("Error loading sprite from file \"%s\"\n",
m_filename.c_str());
}
}
// Load special data from .aseprite-data file
if (m_document &&
m_document->sprite() &&
!m_dataFilename.empty()) {
loadData();
}
}
// Save //////////////////////////////////////////////////////////////////////
@ -707,9 +760,18 @@ void FileOp::operate(IFileOpProgress* progress)
// Direct save to a file.
else {
// Call the "save" procedure.
if (!m_format->save(this))
if (!m_format->save(this)) {
setError("Error saving the sprite in the file \"%s\"\n",
m_filename.c_str());
}
}
// Save special data from .aseprite-data file
if (m_document &&
m_document->sprite() &&
!hasError() &&
!m_dataFilename.empty()) {
saveData();
}
#else
setError(
@ -896,7 +958,7 @@ Image* FileOp::sequenceImage(PixelFormat pixelFormat, int w, int h)
void FileOp::setError(const char *format, ...)
{
char buf_error[4096];
char buf_error[4096]; // TODO possible stack overflow
va_list ap;
va_start(ap, format);
vsnprintf(buf_error, sizeof(buf_error), format, ap);
@ -995,4 +1057,141 @@ void FileOp::prepareForSequence()
m_formatOptions.reset();
}
void FileOp::loadData()
{
try {
XmlDocumentRef xmlDoc = open_xml(m_dataFilename);
TiXmlHandle handle(xmlDoc.get());
TiXmlElement* xmlSlices = handle
.FirstChild("sprite")
.FirstChild("slices").ToElement();
// Update theme.xml file
if (xmlSlices &&
xmlSlices->Attribute("theme")) {
std::string themeFileName = xmlSlices->Attribute("theme");
// Open theme XML file
XmlDocumentRef xmlThemeDoc = open_xml(
base::join_path(base::get_file_path(m_dataFilename), themeFileName));
TiXmlHandle themeHandle(xmlThemeDoc.get());
for (TiXmlElement* xmlPart = themeHandle
.FirstChild("theme")
.FirstChild("parts")
.FirstChild("part").ToElement();
xmlPart;
xmlPart=xmlPart->NextSiblingElement()) {
const char* partId = xmlPart->Attribute("id");
if (!partId)
continue;
auto slice = new doc::Slice();
slice->setName(partId);
doc::SliceKey key;
int x = strtol(xmlPart->Attribute("x"), NULL, 10);
int y = strtol(xmlPart->Attribute("y"), NULL, 10);
if (xmlPart->Attribute("w1")) {
int w1 = xmlPart->Attribute("w1") ? strtol(xmlPart->Attribute("w1"), NULL, 10): 0;
int w2 = xmlPart->Attribute("w2") ? strtol(xmlPart->Attribute("w2"), NULL, 10): 0;
int w3 = xmlPart->Attribute("w3") ? strtol(xmlPart->Attribute("w3"), NULL, 10): 0;
int h1 = xmlPart->Attribute("h1") ? strtol(xmlPart->Attribute("h1"), NULL, 10): 0;
int h2 = xmlPart->Attribute("h2") ? strtol(xmlPart->Attribute("h2"), NULL, 10): 0;
int h3 = xmlPart->Attribute("h3") ? strtol(xmlPart->Attribute("h3"), NULL, 10): 0;
key.setBounds(gfx::Rect(x, y, w1+w2+w3, h1+h2+h3));
key.setCenter(gfx::Rect(w1, h1, w2, h2));
}
else if (xmlPart->Attribute("w")) {
int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0;
int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0;
key.setBounds(gfx::Rect(x, y, w, h));
}
slice->insert(0, key);
m_document->sprite()->slices().add(slice);
}
}
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}
void FileOp::saveData()
{
try {
XmlDocumentRef xmlDoc = open_xml(m_dataFilename);
TiXmlHandle handle(xmlDoc.get());
TiXmlElement* xmlSlices = handle
.FirstChild("sprite")
.FirstChild("slices").ToElement();
if (xmlSlices &&
xmlSlices->Attribute("theme")) {
// Open theme XML file
std::string themeFileName = base::join_path(
base::get_file_path(m_dataFilename), xmlSlices->Attribute("theme"));
XmlDocumentRef xmlThemeDoc = open_xml(themeFileName);
TiXmlHandle themeHandle(xmlThemeDoc.get());
TiXmlElement* xmlNext = nullptr;
std::set<std::string> existent;
TiXmlElement* xmlParts =
themeHandle
.FirstChild("theme")
.FirstChild("parts").ToElement();
for (TiXmlElement* xmlPart=(TiXmlElement*)xmlParts->FirstChild("part");
xmlPart;
xmlPart=xmlNext) {
xmlNext = xmlPart->NextSiblingElement();
const char* partId = xmlPart->Attribute("id");
if (!partId)
continue;
bool found = false;
for (auto slice : m_document->sprite()->slices()) {
const SliceKey* key;
if ((slice->name() == partId) &&
(key = slice->getByFrame(0))) {
existent.insert(slice->name());
updateXmlPartFromSliceKey(key, xmlPart);
found = true;
break;
}
}
// Delete this <part> element (as the slice was removed)
if (!found)
xmlPart->Parent()->RemoveChild(xmlPart);
}
for (auto slice : m_document->sprite()->slices()) {
const SliceKey* key;
if (existent.find(slice->name()) == existent.end() &&
(key = slice->getByFrame(0))) {
TiXmlElement xmlPart("part");
xmlPart.SetAttribute("id", slice->name().c_str());
updateXmlPartFromSliceKey(key, &xmlPart);
xmlParts->InsertAfterChild(xmlParts->LastChild(), xmlPart);
}
}
save_xml(xmlThemeDoc, themeFileName);
}
}
catch (const std::exception& ex) {
setError("Error loading data file: %s\n", ex.what());
}
}
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -25,6 +25,7 @@
#define FILE_LOAD_SEQUENCE_ASK_CHECKBOX 0x00000004
#define FILE_LOAD_SEQUENCE_YES 0x00000008
#define FILE_LOAD_ONE_FRAME 0x00000010
#define FILE_LOAD_DATA_FILE 0x00000020
namespace doc {
class Document;
@ -173,6 +174,7 @@ namespace app {
// releaseDocument() member function)
Document* m_document; // Loaded document, or document to be saved.
std::string m_filename; // File-name to load/save.
std::string m_dataFilename; // File-name for a special XML .aseprite-data where extra sprite data can be stored
FileOpROI m_roi;
// Shared fields between threads.
@ -206,6 +208,8 @@ namespace app {
} m_seq;
void prepareForSequence();
void loadData();
void saveData();
};
// Available extensions for each load/save operation.

32
src/app/font_path.cpp Normal file
View File

@ -0,0 +1,32 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/font_path.h"
#include "base/fs.h"
namespace app {
std::string find_font(const std::string& filename)
{
std::vector<std::string> fontDirs;
get_font_dirs(fontDirs);
std::string fn;
for (const std::string& dir : fontDirs) {
fn = base::join_path(dir, filename);
if (base::is_file(fn))
return fn;
}
return std::string();
}
} // namespace app

21
src/app/font_path.h Normal file
View File

@ -0,0 +1,21 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_FONT_PATH_H_INCLUDED
#define APP_FONT_PATH_H_INCLUDED
#pragma once
#include <string>
#include <vector>
namespace app {
void get_font_dirs(std::vector<std::string>& fontDirs);
std::string find_font(const std::string& filename);
} // namespace app
#endif

23
src/app/font_path_osx.mm Normal file
View File

@ -0,0 +1,23 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/font_path.h"
namespace app {
void get_font_dirs(std::vector<std::string>& fontDirs)
{
// TODO use a Cocoa API to get the list of paths
fontDirs.push_back("~/Library/Fonts");
fontDirs.push_back("/Library/Fonts");
fontDirs.push_back("/System/Library/Fonts/");
}
} // namespace app

View File

@ -0,0 +1,49 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/font_path.h"
#include "base/fs.h"
#include <queue>
namespace app {
std::vector<std::string> g_cache;
void get_font_dirs(std::vector<std::string>& fontDirs)
{
if (!g_cache.empty()) {
fontDirs = g_cache;
return;
}
std::queue<std::string> q;
q.push("~/.fonts");
q.push("/usr/local/share/fonts");
q.push("/usr/share/fonts");
while (!q.empty()) {
std::string fontDir = q.front();
q.pop();
fontDirs.push_back(fontDir);
for (const auto& file : base::list_files(fontDir)) {
std::string fullpath = base::join_path(fontDir, file);
if (base::is_directory(fullpath))
q.push_back(fontDir); // Add subdirectory in the queue
}
}
g_cache = fontDirs;
}
} // namespace app

31
src/app/font_path_win.cpp Normal file
View File

@ -0,0 +1,31 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/font_path.h"
#include "base/string.h"
#include <cctype>
#include <windows.h>
#include <shlobj.h>
namespace app {
void get_font_dirs(std::vector<std::string>& fontDirs)
{
std::vector<wchar_t> buf(MAX_PATH+1);
HRESULT hr = SHGetFolderPath(
nullptr, CSIDL_FONTS, nullptr,
SHGFP_TYPE_DEFAULT, &buf[0]);
if (hr == S_OK)
fontDirs.push_back(base::to_utf8(&buf[0]));
}
} // namespace app

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -141,7 +141,7 @@ void draw_color_button(ui::Graphics* g,
if (hot) {
theme->drawRect(
g, gfx::Rect(rc.x, rc.y, rc.w, rc.h-1 - 1*scale),
theme->parts.colorbarBorderHotfg().get());
theme->parts.colorbarSelection().get());
}
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -185,7 +185,7 @@ int init_module_gui()
// Setup the GUI theme for all widgets
gui_theme = new SkinTheme();
gui_theme->setScale(Preferences::instance().general.uiScale());
CurrentTheme::set(gui_theme);
ui::set_theme(gui_theme);
if (maximized)
main_display->maximize();
@ -204,7 +204,7 @@ void exit_module_gui()
delete manager;
// Now we can destroy theme
CurrentTheme::set(NULL);
ui::set_theme(nullptr);
delete gui_theme;
main_display->dispose();
@ -286,41 +286,16 @@ Widget* setup_mini_font(Widget* widget)
}
Widget* setup_mini_look(Widget* widget)
{
return setup_look(widget, MiniLook);
}
Widget* setup_look(Widget* widget, LookType lookType)
{
SkinPropertyPtr skinProp = get_skin_property(widget);
skinProp->setLook(lookType);
skinProp->setLook(MiniLook);
return widget;
}
void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4)
{
SkinPropertyPtr skinProp = get_skin_property(widget);
skinProp->setUpperLeft(b1);
skinProp->setUpperRight(b2);
skinProp->setLowerLeft(b3);
skinProp->setLowerRight(b4);
}
//////////////////////////////////////////////////////////////////////
// Button style (convert radio or check buttons and draw it like
// normal buttons)
CheckBox* check_button_new(const char *text, int b1, int b2, int b3, int b4)
{
CheckBox* widget = new CheckBox(text, kButtonWidget);
widget->setAlign(CENTER | MIDDLE);
setup_mini_look(widget);
setup_bevels(widget, b1, b2, b3, b4);
return widget;
}
void defer_invalid_rect(const gfx::Rect& rc)
{
if (!defered_invalid_timer)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -41,10 +41,6 @@ namespace app {
ui::Widget* setup_mini_font(ui::Widget* widget);
ui::Widget* setup_mini_look(ui::Widget* widget);
ui::Widget* setup_look(ui::Widget* widget, skin::LookType lookType);
void setup_bevels(ui::Widget* widget, int b1, int b2, int b3, int b4);
ui::CheckBox* check_button_new(const char* text, int b1, int b2, int b3, int b4);
// This function can be used to reinvalidate a specific rectangle if
// we weren't able to validate it on a onPaint() event. E.g. Because

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -13,6 +13,7 @@
#include "app/document_undo.h"
#include "app/tools/pick_ink.h"
#include "doc/mask.h"
#include "doc/slice.h"
#include "gfx/region.h"
namespace app {
@ -168,16 +169,42 @@ public:
class SliceInk : public Ink {
AlgoHLine m_proc;
bool m_createSlice;
gfx::Rect m_maxBounds;
public:
SliceInk() {
m_createSlice = false;
}
Ink* clone() override { return new SliceInk(*this); }
bool isSlice() const override { return true; }
bool needsCelCoordinates() const override { return false; }
void prepareInk(ToolLoop* loop) override { }
void prepareInk(ToolLoop* loop) override {
m_proc = get_ink_proc<XorInkProcessing>(loop->sprite()->pixelFormat());
}
void inkHline(int x1, int y, int x2, ToolLoop* loop) override {
// TODO show the selection-preview with a XOR color or something like that
draw_hline(loop->getDstImage(), x1, y, x2, loop->getPrimaryColor());
if (m_createSlice)
m_maxBounds |= gfx::Rect(x1, y, x2-x1+1, 1);
else
(*m_proc)(x1, y, x2, loop);
}
void setFinalStep(ToolLoop* loop, bool state) override {
m_createSlice = state;
if (state) {
m_maxBounds = gfx::Rect(0, 0, 0, 0);
}
else if (loop->getMouseButton() == ToolLoop::Left) {
Slice* slice = new Slice;
SliceKey key(m_maxBounds);
slice->insert(loop->getFrame(), key);
loop->addSlice(slice);
}
}
};
@ -345,7 +372,6 @@ public:
m_maxBounds |= gfx::Rect(x1, y, x2-x1+1, 1);
}
// TODO show the selection-preview with a XOR color or something like that
else {
(*m_proc)(x1, y, x2, loop);
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -26,6 +26,7 @@ namespace doc {
class Mask;
class Remap;
class RgbMap;
class Slice;
class Sprite;
}
@ -117,6 +118,9 @@ namespace app {
virtual Mask* getMask() = 0;
virtual void setMask(Mask* newMask) = 0;
// Adds a new slice (only for slice ink)
virtual void addSlice(doc::Slice* newSlice) = 0;
// Gets mask X,Y origin coordinates
virtual gfx::Point getMaskOrigin() = 0;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -109,7 +109,9 @@ bool ToolLoopManager::releaseButton(const Pointer& pointer)
bool res = m_toolLoop->getController()->releaseButton(m_stroke, spritePoint);
if (!res && (m_toolLoop->getInk()->isSelection() || m_toolLoop->getFilled())) {
if (!res && (m_toolLoop->getInk()->isSelection() ||
m_toolLoop->getInk()->isSlice() ||
m_toolLoop->getFilled())) {
m_toolLoop->getInk()->setFinalStep(m_toolLoop, true);
doLoopStep(true);
m_toolLoop->getInk()->setFinalStep(m_toolLoop, false);

View File

@ -53,9 +53,6 @@ bool AppMenuItem::onProcessMessage(Message* msg)
case kCloseMessage:
// disable the menu (the keyboard shortcuts are processed by "manager_msg_proc")
setEnabled(false);
if (!s_contextParams.empty())
s_contextParams.clear();
break;
default:

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2016 David Capello
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -13,7 +13,6 @@
#include "app/resource_finder.h"
#include "app/ui/browser_view.h"
#include "app/ui/main_window.h"
#include "app/ui/skin/skin_style_property.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/workspace.h"
#include "base/file_handle.h"
@ -429,8 +428,8 @@ private:
void addSeparator() {
auto sep = new Separator("", HORIZONTAL);
sep->setStyle(SkinTheme::instance()->newStyles.separatorInView());
sep->setBorder(gfx::Border(0, font()->height(), 0, font()->height()));
sep->setBgColor(SkinTheme::instance()->colors.textboxFace());
sep->setExpansive(true);
addChild(sep);
}
@ -449,9 +448,7 @@ private:
if (word.size() > 4 &&
std::strncmp(word.c_str(), "http", 4) == 0) {
label = new LinkLabel(word);
label->setProperty(
SkinStylePropertyPtr(
new SkinStyleProperty(SkinTheme::instance()->styles.browserLink())));
label->setStyle(SkinTheme::instance()->newStyles.browserLink());
}
else
label = new Label(word);
@ -478,9 +475,7 @@ private:
void addLink(const std::string& url, const std::string& text) {
auto label = new LinkLabel(url, text);
label->setProperty(
SkinStylePropertyPtr(
new SkinStyleProperty(SkinTheme::instance()->styles.browserLink())));
label->setStyle(SkinTheme::instance()->newStyles.browserLink());
if (url.find(':') == std::string::npos) {
label->setUrl("");
@ -521,8 +516,7 @@ BrowserView::BrowserView()
m_view.attachToView(m_textBox);
m_view.setExpansive(true);
m_view.setProperty(SkinStylePropertyPtr(
new SkinStyleProperty(theme->styles.workspaceView())));
m_view.setStyle(theme->newStyles.workspaceView());
m_textBox->FileChange.connect(
[]{

View File

@ -70,7 +70,7 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
Graphics* g = ev.graphics();
gfx::Rect rc = clientBounds();
gfx::Color fg, bg;
gfx::Color fg;
SkinPartPtr nw;
gfx::Rect boxRc, textRc, iconRc;
gfx::Size iconSize;
@ -98,20 +98,17 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
if (hasCapture()) {
nw = theme->parts.toolbuttonPushed();
fg = theme->colors.buttonSelectedText();
bg = theme->colors.buttonSelectedFace();
}
else {
nw = (hasFocus() ? theme->parts.toolbuttonHotFocused():
theme->parts.toolbuttonHot());
fg = theme->colors.buttonHotText();
bg = theme->colors.buttonHotFace();
}
}
else {
nw = (hasFocus() ? theme->parts.toolbuttonFocused():
theme->parts.toolbuttonLast());
fg = theme->colors.buttonNormalText();
bg = theme->colors.buttonNormalFace();
}
if (!isLastCol)
@ -124,7 +121,7 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
rc.h += 3*guiscale();
}
theme->drawRect(g, rc, nw.get(), bg);
theme->drawRect(g, rc, nw.get());
if (m_icon) {
she::Surface* bmp = m_icon->bitmap(0);
@ -141,8 +138,7 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
if (hasText()) {
g->setFont(font());
g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(),
false);
g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(), 0);
}
}
@ -162,7 +158,7 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
if (isEnabled() && hasText()) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
bool mnemonicPressed = (msg->altPressed() &&
mnemonicCharPressed(keymsg));
isMnemonicPressed(keymsg));
if (mnemonicPressed ||
(hasFocus() && keymsg->scancode() == kKeySpace)) {

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -38,7 +38,6 @@
#include "app/ui/palette_popup.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
#include "app/ui/styled_button.h"
#include "app/ui_context.h"
#include "app/ui_context.h"
#include "app/util/clipboard.h"
@ -82,18 +81,10 @@ enum class PalButton {
using namespace app::skin;
using namespace ui;
class ColorBar::WarningIcon : public StyledButton {
class ColorBar::WarningIcon : public ui::Button {
public:
WarningIcon()
: StyledButton(skin::SkinTheme::instance()->styles.warningBox()) {
}
protected:
void onPaint(ui::PaintEvent& ev) override {
// if (isEnabled())
StyledButton::onPaint(ev);
// else
// ev.graphics()->fillRect(getBgColor(), clientBounds());
WarningIcon() : ui::Button(std::string()) {
setStyle(skin::SkinTheme::instance()->newStyles.warningBox());
}
};
@ -103,24 +94,7 @@ protected:
ColorBar::ScrollableView::ScrollableView()
{
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
int l = theme->parts.editorSelected()->bitmapW()->width();
int t = theme->parts.editorSelected()->bitmapN()->height();
int r = theme->parts.editorSelected()->bitmapE()->width();
int b = theme->parts.editorSelected()->bitmapS()->height();
setBorder(gfx::Border(l, t, r, b));
}
void ColorBar::ScrollableView::onPaint(ui::PaintEvent& ev)
{
ui::Graphics* g = ev.graphics();
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
theme->drawRect(
g, clientBounds(),
(hasFocus() ? theme->parts.editorSelected().get():
theme->parts.editorNormal().get()),
gfx::ColorNone);
setStyle(theme->newStyles.colorbarView());
}
//////////////////////////////////////////////////////////////////////
@ -177,6 +151,7 @@ ColorBar::ColorBar(int align)
m_splitter.setId("palette_spectrum_splitter");
m_splitter.setPosition(80);
m_splitter.setExpansive(true);
m_splitter.setStyle(theme->newStyles.workspaceSplitter());
m_splitter.addChild(&m_palettePlaceholder);
m_splitter.addChild(&m_selectorPlaceholder);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -133,8 +133,6 @@ namespace app {
class ScrollableView : public ui::View {
public:
ScrollableView();
protected:
void onPaint(ui::PaintEvent& ev) override;
};
class WarningIcon;

View File

@ -15,7 +15,6 @@
#include "app/color_utils.h"
#include "app/modules/editors.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/ui/color_bar.h"
#include "app/ui/color_popup.h"
#include "app/ui/editor/editor.h"
@ -52,10 +51,9 @@ ColorButton::ColorButton(const app::Color& color,
, m_dependOnLayer(false)
, m_canPinSelector(canPinSelector)
{
this->setFocusStop(true);
setup_mini_font(this);
setFocusStop(true);
initTheme();
UIContext::instance()->add_observer(this);
}
@ -102,6 +100,12 @@ app::Color ColorButton::getColorByPosition(const gfx::Point& pos)
return m_color;
}
void ColorButton::onInitTheme(InitThemeEvent& ev)
{
ButtonBase::onInitTheme(ev);
setStyle(SkinTheme::instance()->newStyles.colorButton());
}
bool ColorButton::onProcessMessage(Message* msg)
{
switch (msg->type()) {
@ -160,12 +164,15 @@ bool ColorButton::onProcessMessage(Message* msg)
void ColorButton::onSizeHint(SizeHintEvent& ev)
{
ButtonBase::onSizeHint(ev);
gfx::Rect box;
getTextIconInfo(&box);
box.w = 64*guiscale();
ev.setSizeHint(box.w + border().width(),
box.h + border().height());
gfx::Size sz = ev.sizeHint();
sz.w = std::max(sz.w, box.w);
ev.setSizeHint(sz);
}
void ColorButton::onPaint(PaintEvent& ev)
@ -226,7 +233,7 @@ void ColorButton::onPaint(PaintEvent& ev)
gfx::Rect textrc;
getTextIconInfo(NULL, &textrc);
g->drawUIText(text(), textcolor, gfx::ColorNone, textrc.origin());
g->drawUIText(text(), textcolor, gfx::ColorNone, textrc.origin(), 0);
}
void ColorButton::onClick(Event& ev)

View File

@ -15,6 +15,10 @@
#include "obs/signal.h"
#include "ui/button.h"
namespace ui {
class InitThemeEvent;
}
namespace app {
class ColorPopup;
@ -41,6 +45,7 @@ namespace app {
protected:
// Events
void onInitTheme(ui::InitThemeEvent& ev) override;
bool onProcessMessage(ui::Message* msg) override;
void onSizeHint(ui::SizeHintEvent& ev) override;
void onPaint(ui::PaintEvent& ev) override;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -23,7 +23,6 @@
#include "app/transaction.h"
#include "app/ui/palette_view.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/skin/style.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "base/scoped_value.h"
@ -48,7 +47,7 @@ enum {
};
ColorPopup::ColorPopup(bool canPin)
: PopupWindowPin("Color Selector",
: PopupWindowPin(std::string(),
ClickBehavior::CloseOnClickInOtherWindow,
canPin)
, m_vbox(VERTICAL)
@ -80,12 +79,13 @@ ColorPopup::ColorPopup(bool canPin)
m_topBox.addChild(new Separator("", VERTICAL));
m_topBox.addChild(&m_hexColorEntry);
// TODO fix this hack for close button in popup window
// Move close button (decorative widget) inside the m_topBox
{
Widget* closeButton = nullptr;
WidgetsList decorators;
for (auto child : children()) {
if (child->isDecorative()) {
if (child->type() == kWindowCloseButtonWidget) {
closeButton = child;
removeChild(child);
break;
@ -93,7 +93,9 @@ ColorPopup::ColorPopup(bool canPin)
}
if (closeButton) {
m_topBox.addChild(new BoxFiller);
m_topBox.addChild(closeButton);
VBox* vbox = new VBox;
vbox->addChild(closeButton);
m_topBox.addChild(vbox);
}
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -71,7 +71,7 @@ void ColorSpectrum::onPaint(ui::PaintEvent& ev)
theme->drawRect(g, clientBounds(),
theme->parts.editorNormal().get(),
bgColor());
false); // Do not fill the center
gfx::Rect rc = clientChildrenBounds();
if (rc.isEmpty())

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2016 David Capello
// Copyright (C) 2016-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -76,7 +76,7 @@ void ColorTintShadeTone::onPaint(ui::PaintEvent& ev)
theme->drawRect(g, clientBounds(),
theme->parts.editorNormal().get(),
bgColor());
false); // Do not fill the center
gfx::Rect rc = clientChildrenBounds();
if (rc.isEmpty())

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -53,20 +53,14 @@ ColorWheel::ColorWheel()
: m_discrete(Preferences::instance().colorBar.discreteWheel())
, m_colorModel((ColorModel)Preferences::instance().colorBar.wheelModel())
, m_harmony((Harmony)Preferences::instance().colorBar.harmony())
, m_options("", kButtonWidget, kButtonWidget, kCheckWidget)
, m_options("")
, m_harmonyPicked(false)
{
SkinTheme* theme = SkinTheme::instance();
setBorder(gfx::Border(3*ui::guiscale()));
m_options.Click.connect(base::Bind<void>(&ColorWheel::onOptions, this));
m_options.setBgColor(theme->colors.editorFace());
m_options.setIconInterface(
new ButtonIconImpl(theme->parts.palOptions(),
theme->parts.palOptions(),
theme->parts.palOptions(),
CENTER | MIDDLE));
m_options.setStyle(theme->newStyles.colorWheelOptions());
addChild(&m_options);
}
@ -210,7 +204,7 @@ void ColorWheel::onPaint(ui::PaintEvent& ev)
theme->drawRect(g, clientBounds(),
theme->parts.editorNormal().get(),
bgColor());
false); // Do not fill the center
const gfx::Rect& rc = m_clientBounds;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -63,7 +63,7 @@ namespace app {
bool m_discrete;
ColorModel m_colorModel;
Harmony m_harmony;
ui::ButtonBase m_options;
ui::Button m_options;
// Internal flag used to know if after pickColor() we selected an
// harmony.

View File

@ -36,7 +36,6 @@
#include "app/ui/icon_button.h"
#include "app/ui/skin/button_icon_impl.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/skin/style.h"
#include "app/ui_context.h"
#include "base/bind.h"
#include "base/scoped_value.h"
@ -663,9 +662,7 @@ class ContextBar::InkShadesField : public HBox {
bounds.w = w;
}
skin::Style::State state;
if (hasMouseOver()) state += Style::hover();
theme->styles.view()->paint(g, bounds, nullptr, state);
theme->paintWidget(g, this, theme->newStyles.view(), bounds);
bounds.shrink(3*guiscale());
@ -707,10 +704,9 @@ class ContextBar::InkShadesField : public HBox {
if (!hotBounds.isEmpty() && m_click == DragAndDrop) {
hotBounds.enlarge(3*guiscale());
Style::State state = Style::active();
state += Style::hover();
theme->styles.timelineRangeOutline()->paint(
g, hotBounds, NULL, state);
PaintWidgetPartInfo info;
theme->paintWidgetPart(
g, theme->newStyles.shadeSelection(), hotBounds, info);
}
}
else {

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -15,7 +15,6 @@
#include "app/crash/session.h"
#include "app/modules/gui.h"
#include "app/ui/drop_down_button.h"
#include "app/ui/skin/skin_style_property.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/workspace.h"
#include "base/bind.h"
@ -80,7 +79,7 @@ DataRecoveryView::DataRecoveryView(crash::DataRecovery* dataRecovery)
m_listBox.setMultiselect(true);
m_view.setExpansive(true);
m_view.attachToView(&m_listBox);
m_view.setProperty(SkinStylePropertyPtr(new SkinStyleProperty(theme->styles.workspaceView())));
m_view.setStyle(theme->newStyles.workspaceView());
HBox* hbox = new HBox;
hbox->setBorder(gfx::Border(2, 0, 2, 0)*guiscale());
@ -116,7 +115,7 @@ void DataRecoveryView::fillList()
continue;
auto sep = new Separator(session->name(), HORIZONTAL);
sep->setBgColor(SkinTheme::instance()->colors.background());
sep->setStyle(SkinTheme::instance()->newStyles.separatorInView());
sep->setBorder(sep->border() + gfx::Border(0, 8, 0, 8)*guiscale());
m_listBox.addChild(sep);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -15,7 +15,6 @@
#include "app/ui/devconsole_view.h"
#include "app/app_menus.h"
#include "app/ui/skin/skin_style_property.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/workspace.h"
#include "ui/entry.h"
@ -77,11 +76,10 @@ DevConsoleView::DevConsoleView()
m_bottomBox.addChild(&m_label);
m_bottomBox.addChild(m_entry);
m_view.setProperty(SkinStylePropertyPtr(
new SkinStyleProperty(theme->styles.workspaceView())));
m_view.setStyle(theme->newStyles.workspaceView());
m_view.attachToView(&m_textBox);
m_view.setExpansive(true);
m_entry->setExpansive(true);
m_entry->ExecuteCommand.connect(&DevConsoleView::onExecuteCommand, this);
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -28,11 +28,10 @@ DropDownButton::DropDownButton(const char* text)
{
SkinTheme* theme = SkinTheme::instance();
setup_look(m_button, LeftButtonLook);
setup_look(m_dropDown, RightButtonLook);
m_button->setStyle(theme->newStyles.dropDownButton());
m_dropDown->setStyle(theme->newStyles.dropDownExpandButton());
m_button->setExpansive(true);
m_button->setAlign(LEFT | MIDDLE);
m_button->Click.connect(&DropDownButton::onButtonClick, this);
m_dropDown->Click.connect(&DropDownButton::onDropDownButtonClick, this);
@ -40,12 +39,6 @@ DropDownButton::DropDownButton(const char* text)
addChild(m_dropDown);
setChildSpacing(0);
m_dropDown->setIconInterface
(new ButtonIconImpl(theme->parts.comboboxArrowDown(),
theme->parts.comboboxArrowDownSelected(),
theme->parts.comboboxArrowDownDisabled(),
CENTER | MIDDLE));
}
void DropDownButton::onButtonClick(Event& ev)

View File

@ -52,6 +52,7 @@
#include "doc/doc.h"
#include "doc/document_event.h"
#include "doc/mask_boundaries.h"
#include "doc/slice.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/ui.h"
@ -703,7 +704,7 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
g->fillRegion(theme->colors.editorFace(), outside);
}
// Grids
// Grids & slices
{
// Clipping
gfx::Rect cliprc = editorToScreen(rc).offset(-bounds().origin());
@ -743,6 +744,10 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
m_docPref.grid.color(), alpha);
}
}
// Draw slices
if (m_docPref.show.slices())
drawSlices(g);
}
}
@ -954,6 +959,51 @@ void Editor::drawGrid(Graphics* g, const gfx::Rect& spriteBounds, const Rect& gr
g->drawVLine(grid_color, c, y1, spriteBounds.h);
}
void Editor::drawSlices(ui::Graphics* g)
{
if ((m_flags & kShowSlices) == 0)
return;
if (!isVisible() || !m_document)
return;
for (auto slice : m_sprite->slices()) {
auto key = slice->getByFrame(m_frame);
if (!key)
continue;
doc::color_t docColor = slice->userData().color();
gfx::Color color = gfx::rgba(doc::rgba_getr(docColor),
doc::rgba_getg(docColor),
doc::rgba_getb(docColor),
doc::rgba_geta(docColor));
gfx::Rect out =
editorToScreen(key->bounds())
.offset(-bounds().origin());
if (!key->center().isEmpty()) {
gfx::Rect in =
editorToScreen(gfx::Rect(key->center()).offset(key->bounds().origin()))
.offset(-bounds().origin());
auto in_color = gfx::rgba(gfx::getr(color),
gfx::getg(color),
gfx::getb(color),
doc::rgba_geta(docColor)/4);
if (in.y > out.y && in.y < out.y2())
g->drawHLine(in_color, out.x, in.y, out.w);
if (in.y2() > out.y && in.y2() < out.y2())
g->drawHLine(in_color, out.x, in.y2(), out.w);
if (in.x > out.x && in.x < out.x2())
g->drawVLine(in_color, in.x, out.y, out.h);
if (in.x2() > out.x && in.x2() < out.x2())
g->drawVLine(in_color, in.x2(), out.y, out.h);
}
g->drawRect(color, out);
}
}
void Editor::flashCurrentLayer()
{
if (!Preferences::instance().experimental.flashLayer())
@ -1621,6 +1671,63 @@ bool Editor::isInsideSelection()
m_document->mask()->containsPoint(spritePos.x, spritePos.y);
}
EditorHit Editor::calcHit(const gfx::Point& mouseScreenPos)
{
tools::Ink* ink = getCurrentEditorInk();
if (ink) {
// Check if we can transform slices
if (ink->isSlice()) {
if (m_docPref.show.slices()) {
for (auto slice : m_sprite->slices()) {
auto key = slice->getByFrame(m_frame);
if (key) {
gfx::Rect bounds = editorToScreen(key->bounds());
gfx::Rect center = key->center();
if (bounds.contains(mouseScreenPos) &&
!bounds.shrink(5*guiscale()).contains(mouseScreenPos)) {
int border =
(mouseScreenPos.x <= bounds.x ? LEFT: 0) |
(mouseScreenPos.y <= bounds.y ? TOP: 0) |
(mouseScreenPos.x >= bounds.x2() ? RIGHT: 0) |
(mouseScreenPos.y >= bounds.y2() ? BOTTOM: 0);
EditorHit hit(EditorHit::SliceBounds);
hit.setBorder(border);
hit.setSlice(slice);
return hit;
}
else if (!center.isEmpty()) {
center = editorToScreen(
center.offset(key->bounds().origin()));
bool horz1 = gfx::Rect(bounds.x, center.y-2*guiscale(), bounds.w, 5*guiscale()).contains(mouseScreenPos);
bool horz2 = gfx::Rect(bounds.x, center.y2()-2*guiscale(), bounds.w, 5*guiscale()).contains(mouseScreenPos);
bool vert1 = gfx::Rect(center.x-2*guiscale(), bounds.y, 5*guiscale(), bounds.h).contains(mouseScreenPos);
bool vert2 = gfx::Rect(center.x2()-2*guiscale(), bounds.y, 5*guiscale(), bounds.h).contains(mouseScreenPos);
if (horz1 || horz2 || vert1 || vert2) {
int border =
(horz1 ? TOP: 0) |
(horz2 ? BOTTOM: 0) |
(vert1 ? LEFT: 0) |
(vert2 ? RIGHT: 0);
EditorHit hit(EditorHit::SliceCenter);
hit.setBorder(border);
hit.setSlice(slice);
return hit;
}
}
}
}
}
}
}
return EditorHit(EditorHit::None);
}
void Editor::setZoomAndCenterInMouse(const Zoom& zoom,
const gfx::Point& mousePos,
ZoomBehavior zoomBehavior)

View File

@ -16,6 +16,7 @@
#include "app/tools/tool_loop_modifiers.h"
#include "app/ui/color_source.h"
#include "app/ui/editor/brush_preview.h"
#include "app/ui/editor/editor_hit.h"
#include "app/ui/editor/editor_observers.h"
#include "app/ui/editor/editor_state.h"
#include "app/ui/editor/editor_states_history.h"
@ -74,13 +75,15 @@ namespace app {
kShowOutside = 8,
kShowDecorators = 16,
kShowSymmetryLine = 32,
kUseNonactiveLayersOpacityWhenEnabled = 64,
kShowSlices = 64,
kUseNonactiveLayersOpacityWhenEnabled = 128,
kDefaultEditorFlags = (kShowGrid |
kShowMask |
kShowOnionskin |
kShowOutside |
kShowDecorators |
kShowSymmetryLine |
kShowSlices |
kUseNonactiveLayersOpacityWhenEnabled)
};
@ -195,6 +198,10 @@ namespace app {
// Returns true if the cursor is inside the active mask/selection.
bool isInsideSelection();
// Returns the element that will be modified if the mouse is used
// in the given position.
EditorHit calcHit(const gfx::Point& mouseScreenPos);
void setZoomAndCenterInMouse(const render::Zoom& zoom,
const gfx::Point& mousePos, ZoomBehavior zoomBehavior);
@ -271,7 +278,8 @@ namespace app {
void drawMaskSafe();
void drawMask(ui::Graphics* g);
void drawGrid(ui::Graphics* g, const gfx::Rect& spriteBounds, const gfx::Rect& gridBounds,
const app::Color& color, int alpha);
const app::Color& color, int alpha);
void drawSlices(ui::Graphics* g);
void setCursor(const gfx::Point& mouseScreenPos);

View File

@ -0,0 +1,48 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_UI_EDITOR_HIT_H_INCLUDED
#define APP_UI_EDITOR_HIT_H_INCLUDED
#pragma once
namespace doc {
class Slice;
}
namespace app {
// TODO Complete this class to calculate if the mouse hit any Editor
// element/decorator
class EditorHit {
public:
enum Type {
None,
SliceBounds,
SliceCenter,
};
EditorHit(Type type)
: m_type(type)
, m_border(0)
, m_slice(nullptr) {
}
Type type() const { return m_type; }
int border() const { return m_border; }
doc::Slice* slice() const { return m_slice; }
void setBorder(int border) { m_border = border; }
void setSlice(doc::Slice* slice) { m_slice = slice; }
private:
Type m_type;
int m_border;
doc::Slice* m_slice;
};
} // namespace app
#endif // APP_UI_EDITOR_HIT_H_INCLUDED

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -41,13 +41,9 @@ EditorView::EditorView(EditorView::Type type)
, m_type(type)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
int l = theme->parts.editorSelected()->bitmapW()->width();
int t = theme->parts.editorSelected()->bitmapN()->height();
int r = theme->parts.editorSelected()->bitmapE()->width();
int b = theme->parts.editorSelected()->bitmapS()->height();
setBorder(gfx::Border(l, t, r, b));
setBgColor(gfx::rgba(0, 0, 0));
setBgColor(gfx::rgba(0, 0, 0)); // TODO Move this color to theme.xml
setStyle(theme->newStyles.editorView());
setupScrollbars();
m_scrollSettingsConn =
@ -57,30 +53,24 @@ EditorView::EditorView(EditorView::Type type)
void EditorView::onPaint(PaintEvent& ev)
{
Graphics* g = ev.graphics();
SkinTheme* theme = static_cast<SkinTheme*>(this->theme());
bool selected = false;
switch (m_type) {
// Only show the view selected if it is the current editor
case CurrentEditorMode:
selected = (editor()->isActive());
if (editor()->isActive())
enableFlags(SELECTED);
else
disableFlags(SELECTED);
break;
// Always show selected
case AlwaysSelected:
selected = true;
enableFlags(SELECTED);
break;
}
theme->drawRect(
g, clientBounds(),
(selected ?
theme->parts.editorSelected().get():
theme->parts.editorNormal().get()),
bgColor());
View::onPaint(ev);
}
void EditorView::onResize(ResizeEvent& ev)
@ -165,8 +155,10 @@ void EditorView::setupScrollbars()
horizontalBar()->setBarWidth(barsize);
verticalBar()->setBarWidth(barsize);
setup_mini_look(horizontalBar());
setup_mini_look(verticalBar());
horizontalBar()->setStyle(theme->newStyles.miniScrollbar());
verticalBar()->setStyle(theme->newStyles.miniScrollbar());
horizontalBar()->setThumbStyle(theme->newStyles.miniScrollbarThumb());
verticalBar()->setThumbStyle(theme->newStyles.miniScrollbarThumb());
showScrollBars();
}

View File

@ -82,7 +82,6 @@ MovingCelState::MovingCelState(Editor* editor,
, m_celList(collect.celList())
, m_celOffset(0.0, 0.0)
, m_celScale(1.0, 1.0)
, m_canceled(false)
, m_hasReference(false)
, m_scaled(false)
, m_handle(handle)
@ -147,8 +146,7 @@ bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
}
if (modified) {
// If the user didn't cancel the operation...
if (!m_canceled) {
{
ContextWriter writer(m_reader, 1000);
Transaction transaction(writer.context(), "Cel Movement", ModifyDocument);
DocumentApi api = document->getApi(transaction);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -61,7 +61,6 @@ namespace app {
gfx::PointF m_celOffset;
gfx::SizeF m_celMainSize;
gfx::SizeF m_celScale;
bool m_canceled;
bool m_maskVisible;
bool m_hasReference;
bool m_scaled;

View File

@ -0,0 +1,145 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/ui/editor/moving_slice_state.h"
#include "app/cmd/set_slice_key.h"
#include "app/context_access.h"
#include "app/transaction.h"
#include "app/ui/editor/editor.h"
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "doc/slice.h"
#include "ui/message.h"
#include <cmath>
namespace app {
using namespace ui;
MovingSliceState::MovingSliceState(Editor* editor, MouseMessage* msg,
const EditorHit& hit)
: m_hit(hit)
{
m_mouseStart = editor->screenToEditor(msg->position());
auto keyPtr = m_hit.slice()->getByFrame(editor->frame());
ASSERT(keyPtr);
if (keyPtr)
m_keyStart = m_key = *keyPtr;
editor->captureMouse();
}
bool MovingSliceState::onMouseUp(Editor* editor, MouseMessage* msg)
{
{
ContextWriter writer(UIContext::instance(), 1000);
Transaction transaction(writer.context(), "Slice Movement", ModifyDocument);
doc::SliceKey newKey = m_key;
m_hit.slice()->insert(editor->frame(), m_keyStart);
transaction.execute(new cmd::SetSliceKey(m_hit.slice(),
editor->frame(),
newKey));
transaction.commit();
}
editor->backToPreviousState();
editor->releaseMouse();
return true;
}
bool MovingSliceState::onMouseMove(Editor* editor, MouseMessage* msg)
{
gfx::Point newCursorPos = editor->screenToEditor(msg->position());
gfx::Point delta = newCursorPos - m_mouseStart;
m_key = m_keyStart;
gfx::Rect rc =
(m_hit.type() == EditorHit::SliceCenter ? m_key.center():
m_key.bounds());
if (m_hit.border() & LEFT) {
rc.x += delta.x;
rc.w -= delta.x;
if (rc.w < 1) {
rc.x += rc.w-1;
rc.w = 1;
}
}
if (m_hit.border() & TOP) {
rc.y += delta.y;
rc.h -= delta.y;
if (rc.h < 1) {
rc.y += rc.h-1;
rc.h = 1;
}
}
if (m_hit.border() & RIGHT) {
rc.w += delta.x;
if (rc.w < 1)
rc.w = 1;
}
if (m_hit.border() & BOTTOM) {
rc.h += delta.y;
if (rc.h < 1)
rc.h = 1;
}
if (m_hit.type() == EditorHit::SliceCenter)
m_key.setCenter(rc);
else
m_key.setBounds(rc);
// Update the slice key
m_hit.slice()->insert(editor->frame(), m_key);
// Redraw the editor.
editor->invalidate();
// Use StandbyState implementation
return StandbyState::onMouseMove(editor, msg);
}
bool MovingSliceState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
{
switch (m_hit.border()) {
case TOP | LEFT:
editor->showMouseCursor(kSizeNWCursor);
break;
case TOP:
editor->showMouseCursor(kSizeNCursor);
break;
case TOP | RIGHT:
editor->showMouseCursor(kSizeNECursor);
break;
case LEFT:
editor->showMouseCursor(kSizeWCursor);
break;
case RIGHT:
editor->showMouseCursor(kSizeECursor);
break;
case BOTTOM | LEFT:
editor->showMouseCursor(kSizeSWCursor);
break;
case BOTTOM:
editor->showMouseCursor(kSizeSCursor);
break;
case BOTTOM | RIGHT:
editor->showMouseCursor(kSizeSECursor);
break;
}
return true;
}
} // namespace app

View File

@ -0,0 +1,38 @@
// Aseprite
// Copyright (C) 2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
#ifndef APP_UI_EDITOR_MOVING_SLICE_STATE_H_INCLUDED
#define APP_UI_EDITOR_MOVING_SLICE_STATE_H_INCLUDED
#pragma once
#include "app/ui/editor/editor_hit.h"
#include "app/ui/editor/standby_state.h"
#include "doc/slice.h"
namespace app {
class Editor;
class MovingSliceState : public StandbyState {
public:
MovingSliceState(Editor* editor, ui::MouseMessage* msg,
const EditorHit& hit);
bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
bool requireBrushPreview() override { return false; }
private:
EditorHit m_hit;
gfx::Point m_mouseStart;
doc::SliceKey m_keyStart;
doc::SliceKey m_key;
};
} // namespace app
#endif

View File

@ -11,6 +11,7 @@
#include "app/ui/editor/standby_state.h"
#include "app/app.h"
#include "app/app_menus.h"
#include "app/color_picker.h"
#include "app/commands/cmd_eyedropper.h"
#include "app/commands/commands.h"
@ -22,6 +23,7 @@
#include "app/tools/ink.h"
#include "app/tools/pick_ink.h"
#include "app/tools/tool.h"
#include "app/ui/app_menuitem.h"
#include "app/ui/document_view.h"
#include "app/ui/editor/drawing_state.h"
#include "app/ui/editor/editor.h"
@ -29,6 +31,7 @@
#include "app/ui/editor/handle_type.h"
#include "app/ui/editor/moving_cel_state.h"
#include "app/ui/editor/moving_pixels_state.h"
#include "app/ui/editor/moving_slice_state.h"
#include "app/ui/editor/moving_symmetry_state.h"
#include "app/ui/editor/pivot_helpers.h"
#include "app/ui/editor/pixels_movement.h"
@ -46,6 +49,7 @@
#include "base/pi.h"
#include "doc/layer.h"
#include "doc/mask.h"
#include "doc/slice.h"
#include "doc/sprite.h"
#include "fixmath/fixmath.h"
#include "gfx/rect.h"
@ -217,6 +221,29 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
return true;
}
if (clickedInk->isSlice()) {
EditorHit hit = editor->calcHit(msg->position());
switch (hit.type()) {
case EditorHit::SliceBounds:
case EditorHit::SliceCenter:
if (msg->left()) {
MovingSliceState* newState = new MovingSliceState(editor, msg, hit);
editor->setState(EditorStatePtr(newState));
}
else {
Menu* popupMenu = AppMenus::instance()->getSlicePopupMenu();
if (popupMenu) {
Params params;
params.set("id", base::convert_to<std::string>(hit.slice()->id()).c_str());
AppMenuItem::setContextParams(params);
popupMenu->showPopup(msg->position());
AppMenuItem::setContextParams(Params());
}
}
return true;
}
}
// Only if the selected tool or quick tool is selection, we give the
// possibility to transform/move the selection. In other case,
// e.g. when selection is used with right-click mode, the
@ -409,8 +436,41 @@ bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
return true;
}
else if (ink->isSlice()) {
editor->showBrushPreview(mouseScreenPos);
return true;
EditorHit hit = editor->calcHit(mouseScreenPos);
switch (hit.type()) {
case EditorHit::None:
// Do nothing, continue
break;
case EditorHit::SliceBounds:
case EditorHit::SliceCenter:
switch (hit.border()) {
case TOP | LEFT:
editor->showMouseCursor(kSizeNWCursor);
break;
case TOP:
editor->showMouseCursor(kSizeNCursor);
break;
case TOP | RIGHT:
editor->showMouseCursor(kSizeNECursor);
break;
case LEFT:
editor->showMouseCursor(kSizeWCursor);
break;
case RIGHT:
editor->showMouseCursor(kSizeECursor);
break;
case BOTTOM | LEFT:
editor->showMouseCursor(kSizeSWCursor);
break;
case BOTTOM:
editor->showMouseCursor(kSizeSCursor);
break;
case BOTTOM | RIGHT:
editor->showMouseCursor(kSizeSECursor);
break;
}
return true;
}
}
}
@ -490,6 +550,27 @@ bool StandbyState::onUpdateStatusBar(Editor* editor)
buf+std::strlen(buf), " :grid: %d %d", col, row);
}
if (editor->docPref().show.slices()) {
int count = 0;
for (auto slice : editor->document()->sprite()->slices()) {
auto key = slice->getByFrame(editor->frame());
if (key &&
key->bounds().contains(
int(std::floor(spritePos.x)),
int(std::floor(spritePos.y)))) {
if (++count == 3) {
sprintf(
buf+std::strlen(buf), " :slice: ...");
break;
}
sprintf(
buf+std::strlen(buf), " :slice: %s",
slice->name().c_str());
}
}
}
StatusBar::instance()->setStatusText(0, buf);
}
@ -700,6 +781,7 @@ bool StandbyState::Decorator::onSetCursor(tools::Ink* ink, Editor* editor, const
return true;
}
// Move symmetry
gfx::Rect box1, box2;
if (getSymmetryHandles(editor, box1, box2) &&
(box1.contains(mouseScreenPos) ||
@ -746,7 +828,7 @@ void StandbyState::Decorator::postRenderDecorator(EditorPostRender* render)
// Draw transformation handles (if the mask is visible and isn't frozen).
gfx::Rect box1, box2;
if (StandbyState::Decorator::getSymmetryHandles(editor, box1, box2)) {
skin::SkinTheme* theme = static_cast<skin::SkinTheme*>(CurrentTheme::get());
skin::SkinTheme* theme = static_cast<skin::SkinTheme*>(ui::get_theme());
she::Surface* part = theme->parts.transformationHandle()->bitmap(0);
ScreenGraphics g;
g.drawRgbaSurface(part, box1.x, box1.y);
@ -777,7 +859,7 @@ bool StandbyState::Decorator::getSymmetryHandles(Editor* editor, gfx::Rect& box1
symmetry.yAxis());
gfx::RectF spriteBounds = gfx::RectF(editor->sprite()->bounds());
gfx::RectF editorViewport = gfx::RectF(View::getView(editor)->viewportBounds());
skin::SkinTheme* theme = static_cast<skin::SkinTheme*>(CurrentTheme::get());
skin::SkinTheme* theme = static_cast<skin::SkinTheme*>(ui::get_theme());
she::Surface* part = theme->parts.transformationHandle()->bitmap(0);
gfx::PointF pt1, pt2;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -11,6 +11,7 @@
#include "app/ui/editor/tool_loop_impl.h"
#include "app/app.h"
#include "app/cmd/add_slice.h"
#include "app/cmd/set_mask.h"
#include "app/color.h"
#include "app/color_utils.h"
@ -415,6 +416,10 @@ public:
// Show selection edges
m_docPref.show.selectionEdges(true);
}
// Slice ink
else if (getInk()->isSlice()) {
redraw = true;
}
m_transaction.commit();
}
@ -461,6 +466,9 @@ public:
void setMask(Mask* newMask) override {
m_transaction.execute(new cmd::SetMask(m_document, newMask));
}
void addSlice(Slice* newSlice) override {
m_transaction.execute(new cmd::AddSlice(m_sprite, newSlice));
}
gfx::Point getMaskOrigin() override { return m_maskOrigin; }
bool getFilled() override { return m_filled; }
bool getPreviewFilled() override { return m_previewFilled; }
@ -603,6 +611,7 @@ public:
bool useMask() override { return false; }
Mask* getMask() override { return nullptr; }
void setMask(Mask* newMask) override { }
void addSlice(Slice* newSlice) override { }
gfx::Point getMaskOrigin() override { return gfx::Point(0, 0); }
bool getFilled() override { return false; }
bool getPreviewFilled() override { return false; }

View File

@ -53,7 +53,7 @@ static struct HandlesInfo {
HandleType TransformHandles::getHandleAtPoint(Editor* editor, const gfx::Point& pt, const Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
SkinTheme* theme = SkinTheme::instance();
she::Surface* gfx = theme->parts.transformationHandle()->bitmap(0);
fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);
@ -128,7 +128,7 @@ void TransformHandles::drawHandles(Editor* editor, const Transformation& transfo
// Draw the pivot
if (visiblePivot(angle)) {
gfx::Rect pivotBounds = getPivotHandleBounds(editor, transform, corners);
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
SkinTheme* theme = SkinTheme::instance();
she::Surface* part = theme->parts.pivotHandle()->bitmap(0);
g.drawRgbaSurface(part, pivotBounds.x, pivotBounds.y);
@ -137,7 +137,7 @@ void TransformHandles::drawHandles(Editor* editor, const Transformation& transfo
void TransformHandles::invalidateHandles(Editor* editor, const Transformation& transform)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
SkinTheme* theme = SkinTheme::instance();
fixmath::fixed angle = fixmath::ftofix(128.0 * transform.angle() / PI);
Transformation::Corners corners;
@ -174,7 +174,7 @@ gfx::Rect TransformHandles::getPivotHandleBounds(Editor* editor,
const Transformation& transform,
const Transformation::Corners& corners)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
SkinTheme* theme = SkinTheme::instance();
gfx::Size partSize = theme->parts.pivotHandle()->size();
gfx::Point screenPivotPos = editor->editorToScreen(gfx::Point(transform.pivot()));
@ -198,7 +198,7 @@ bool TransformHandles::inHandle(const gfx::Point& pt, int x, int y, int gfx_w, i
void TransformHandles::drawHandle(Graphics* g, int x, int y, fixmath::fixed angle)
{
SkinTheme* theme = static_cast<SkinTheme*>(CurrentTheme::get());
SkinTheme* theme = SkinTheme::instance();
she::Surface* part = theme->parts.transformationHandle()->bitmap(0);
adjustHandle(x, y, part->width(), part->height(), angle);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -313,7 +313,6 @@ FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate
, m_extras(nullptr)
, m_navigationLocked(false)
{
SkinTheme* theme = SkinTheme::instance();
bool withResizeOptions = (delegate && delegate->hasResizeCombobox());
addChild(new ArrowNavigator(this));
@ -327,32 +326,6 @@ FileSelector::FileSelector(FileSelectorType type, FileSelectorDelegate* delegate
goUpButton()->setFocusStop(false);
newFolderButton()->setFocusStop(false);
goBackButton()->setIconInterface(
new ButtonIconImpl(theme->parts.comboboxArrowLeft(),
theme->parts.comboboxArrowLeftSelected(),
theme->parts.comboboxArrowLeftDisabled(),
CENTER | MIDDLE));
goForwardButton()->setIconInterface(
new ButtonIconImpl(theme->parts.comboboxArrowRight(),
theme->parts.comboboxArrowRightSelected(),
theme->parts.comboboxArrowRightDisabled(),
CENTER | MIDDLE));
goUpButton()->setIconInterface(
new ButtonIconImpl(theme->parts.comboboxArrowUp(),
theme->parts.comboboxArrowUpSelected(),
theme->parts.comboboxArrowUpDisabled(),
CENTER | MIDDLE));
newFolderButton()->setIconInterface(
new ButtonIconImpl(theme->parts.newfolder(),
theme->parts.newfolderSelected(),
theme->parts.newfolder(),
CENTER | MIDDLE));
setup_mini_look(goBackButton());
setup_mini_look(goForwardButton());
setup_mini_look(goUpButton());
setup_mini_look(newFolderButton());
m_fileList = new FileList();
m_fileList->setId("fileview");
m_fileName->setAssociatedFileList(m_fileList);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -13,6 +13,7 @@
#include "app/commands/cmd_set_palette.h"
#include "app/commands/commands.h"
#include "app/console.h"
#include "app/font_path.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
#include "app/util/freetype_utils.h"
@ -38,7 +39,6 @@
#include <windows.h>
#endif
#include <queue>
#include <map>
namespace app {
@ -144,43 +144,16 @@ FontPopup::FontPopup()
m_popup->view()->attachToView(&m_listBox);
std::queue<std::string> fontDirs;
#if _WIN32
{
std::vector<wchar_t> buf(MAX_PATH);
HRESULT hr = SHGetFolderPath(NULL, CSIDL_FONTS, NULL,
SHGFP_TYPE_DEFAULT, &buf[0]);
if (hr == S_OK) {
fontDirs.push(base::to_utf8(&buf[0]));
}
}
#elif __APPLE__
{
fontDirs.push("/System/Library/Fonts/");
fontDirs.push("/Library/Fonts");
fontDirs.push("~/Library/Fonts");
}
#else // Unix-like
{
fontDirs.push("/usr/share/fonts");
fontDirs.push("/usr/local/share/fonts");
fontDirs.push("~/.fonts");
}
#endif
std::vector<std::string> fontDirs;
get_font_dirs(fontDirs);
// Create a list of fullpaths to every font found in all font
// directories (fontDirs)
std::vector<std::string> files;
while (!fontDirs.empty()) {
std::string fontDir = fontDirs.front();
fontDirs.pop();
auto fontDirFiles = base::list_files(fontDir);
for (const auto& file : fontDirFiles) {
for (const auto& fontDir : fontDirs) {
for (const auto& file : base::list_files(fontDir)) {
std::string fullpath = base::join_path(fontDir, file);
if (base::is_directory(fullpath))
fontDirs.push(fullpath); // Add subdirectory
else
if (base::is_file(fullpath))
files.push_back(fullpath);
}
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2016 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -19,10 +19,6 @@ namespace doc {
class Sprite;
}
namespace ui {
class Splitter;
}
namespace app {
class FrameTagWindow : protected app::gen::FrameTagProperties {

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