mirror of
https://github.com/aseprite/aseprite.git
synced 2024-09-02 04:59:24 +00:00
Merge branch 'new-workspace'
Conflicts: src/app/commands/cmd_open_file.cpp Fixes: src/app/ui/timeline.cpp
This commit is contained in:
commit
361a3084fd
12
data/gui.xml
12
data/gui.xml
@ -89,9 +89,6 @@
|
||||
<key command="InvertMask" shortcut="Ctrl+Shift+I" mac="Cmd+Shift+I" />
|
||||
<!-- View -->
|
||||
<key command="Refresh" shortcut="F5" />
|
||||
<key command="MakeUniqueEditor" shortcut="Ctrl+1" mac="Cmd+1" />
|
||||
<key command="SplitEditorVertically" shortcut="Ctrl+2" mac="Cmd+2" />
|
||||
<key command="SplitEditorHorizontally" shortcut="Ctrl+3" mac="Cmd+3" />
|
||||
<key command="TogglePreview" shortcut="F7" />
|
||||
<key command="FullscreenPreview" shortcut="F8" />
|
||||
<key command="ShowGrid" shortcut="Shift+G" />
|
||||
@ -566,10 +563,6 @@
|
||||
<item command="SaveMask" text="&Save to MSK file" />
|
||||
</menu>
|
||||
<menu text="&View">
|
||||
<item command="MakeUniqueEditor" text="Make &Unique" />
|
||||
<item command="SplitEditorVertically" text="Split &Vertically" />
|
||||
<item command="SplitEditorHorizontally" text="Split &Horizontally" />
|
||||
<separator />
|
||||
<item command="ShowPixelGrid" text="Show &Pixel Grid" />
|
||||
<item command="ShowGrid" text="Show &Grid" />
|
||||
<item command="SnapToGrid" text="&Snap to Grid" />
|
||||
@ -583,6 +576,7 @@
|
||||
</item>
|
||||
<item command="TogglePreview" text="Previe&w" />
|
||||
<item command="FullscreenPreview" text="&Fullscreen Preview" />
|
||||
<item command="Home" text="&Home" />
|
||||
<separator />
|
||||
<item command="Refresh" text="&Refresh && Reload Skin" />
|
||||
</menu>
|
||||
@ -622,6 +616,10 @@
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
<menu id="tab_popup">
|
||||
<item command="CloseFile" text="&Close" />
|
||||
</menu>
|
||||
|
||||
<menu id="document_tab_popup">
|
||||
<item command="CloseFile" text="&Close" />
|
||||
<separator />
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
<global>
|
||||
<section id="general">
|
||||
<option id="visible_timeline" type="bool" default="false" />
|
||||
<option id="autoshow_timeline" type="bool" default="true" migrate="Options.AutoShowTimeline" />
|
||||
<option id="expand_menubar_on_mouseover" type="bool" default="false" migrate="Options.ExpandMenuBarOnMouseover" />
|
||||
</section>
|
||||
@ -71,6 +72,9 @@
|
||||
<option id="use_native_file_dialog" type="bool" default="false" />
|
||||
<option id="flash_layer" type="bool" default="false" migrate="Options.FlashLayer" />
|
||||
</section>
|
||||
<section id="news">
|
||||
<option id="cache_file" type="std::string" />
|
||||
</section>
|
||||
</global>
|
||||
|
||||
<tool>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@ -3,6 +3,15 @@
|
||||
author="Ilija Melentijevic & David Capello"
|
||||
url="http://ilkke.blogspot.com/">
|
||||
|
||||
<dimensions>
|
||||
<dim id="tabs_width" value="80" />
|
||||
<dim id="tabs_height" value="17" />
|
||||
<dim id="tabs_empty_height" value="5" />
|
||||
<dim id="tabs_close_icon_width" value="14" />
|
||||
<dim id="tabs_close_icon_height" value="12" />
|
||||
<dim id="tabs_icon_width" value="10" />
|
||||
</dimensions>
|
||||
|
||||
<colors>
|
||||
<color id="text" value="#000000" />
|
||||
<color id="disabled" value="#968275" />
|
||||
@ -15,7 +24,8 @@
|
||||
<color id="textbox_text" value="#000000" />
|
||||
<color id="textbox_face" value="#ffffff" />
|
||||
<color id="entry_suffix" value="#c6c6c6" />
|
||||
<color id="link_text" value="#0000ff" />
|
||||
<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" />
|
||||
@ -48,8 +58,8 @@
|
||||
<color id="slider_full_face" value="#7d929e" />
|
||||
<color id="tab_normal_text" value="#000000" />
|
||||
<color id="tab_normal_face" value="#c6c6c6" />
|
||||
<color id="tab_selected_text" value="#ffffff" />
|
||||
<color id="tab_selected_face" value="#7d929e" />
|
||||
<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" />
|
||||
@ -64,6 +74,9 @@
|
||||
<color id="filelist_selected_row_face" value="#ff5555" />
|
||||
<color id="filelist_disabled_row_text" value="#ffc8c8" />
|
||||
<color id="workspace" value="#7d929e" />
|
||||
<color id="workspace_text" value="#655561" />
|
||||
<color id="workspace_link" value="#655561" />
|
||||
<color id="workspace_link_hover" value="#ffff7d" />
|
||||
<color id="timeline_normal" value="#c6c6c6" />
|
||||
<color id="timeline_normal_text" value="#000000" />
|
||||
<color id="timeline_hover" value="#d9d9d9" />
|
||||
@ -214,12 +227,20 @@
|
||||
<part id="toolbutton_last" x="96" y="16" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
|
||||
<part id="toolbutton_pushed" x="112" y="16" w1="3" w2="10" w3="3" h1="3" h2="9" h3="4" />
|
||||
<part id="tab_normal" x="2" y="112" w1="4" w2="5" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_selected" x="16" y="112" w1="4" w2="7" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_bottom_selected" x="16" y="124" w1="4" w2="7" w3="5" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_active" x="16" y="112" w1="4" w2="7" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_bottom_active" x="16" y="124" w1="4" w2="7" w3="5" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_bottom_normal" x="2" y="124" w="12" h="5" />
|
||||
<part id="tab_filler" x="0" y="112" w="2" h="12" />
|
||||
<part id="editor_normal" x="32" y="112" w1="3" w2="10" w3="3" h1="3" h2="10" h3="3" />
|
||||
<part id="editor_selected" x="48" y="112" w1="3" w2="10" w3="3" h1="3" h2="10" h3="3" />
|
||||
<part id="tab_modified_icon_normal" x="32" y="112" w="5" h="5" />
|
||||
<part id="tab_modified_icon_active" x="32" y="117" w="5" h="5" />
|
||||
<part id="tab_close_icon_normal" x="37" y="112" w="5" h="5" />
|
||||
<part id="tab_close_icon_active" x="37" y="117" w="5" h="5" />
|
||||
<part id="tab_icon_bg_clicked" x="42" y="112" w="14" h="12" />
|
||||
<part id="tab_icon_bg_hover" x="56" y="112" w="14" h="12" />
|
||||
<part id="tab_home_icon_normal" x="32" y="240" w="7" h="8" />
|
||||
<part id="tab_home_icon_active" x="40" y="240" w="7" h="8" />
|
||||
<part id="editor_normal" x="40" y="96" w1="3" w2="10" w3="3" h1="3" h2="10" h3="3" />
|
||||
<part id="editor_selected" x="56" y="96" w1="3" w2="10" w3="3" h1="3" h2="10" h3="3" />
|
||||
<part id="colorbar_0" x="0" y="192" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
||||
<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" />
|
||||
@ -307,15 +328,15 @@
|
||||
<part id="timeline_empty_frame_active" x="252" y="60" w="12" h="12" />
|
||||
<part id="timeline_keyframe_normal" x="240" y="72" w="12" h="12" />
|
||||
<part id="timeline_keyframe_active" x="252" y="72" w="12" h="12" />
|
||||
<part id="timeline_fromleft_normal" x="240" y="84" w="12" h="12" />
|
||||
<part id="timeline_fromleft_active" x="252" y="84" w="12" h="12" />
|
||||
<part id="timeline_fromright_normal" x="240" y="96" w="12" h="12" />
|
||||
<part id="timeline_fromright_active" x="252" y="96" w="12" h="12" />
|
||||
<part id="timeline_fromboth_normal" x="240" y="108" w="12" h="12" />
|
||||
<part id="timeline_fromboth_active" x="252" y="108" w="12" h="12" />
|
||||
<part id="timeline_leftlink_active" x="264" y="84" w="12" h="12" />
|
||||
<part id="timeline_bothlinks_active" x="264" y="96" w="12" h="12" />
|
||||
<part id="timeline_rightlink_active" x="264" y="108" w="12" h="12" />
|
||||
<part id="timeline_from_left_normal" x="240" y="84" w="12" h="12" />
|
||||
<part id="timeline_from_left_active" x="252" y="84" w="12" h="12" />
|
||||
<part id="timeline_from_right_normal" x="240" y="96" w="12" h="12" />
|
||||
<part id="timeline_from_right_active" x="252" y="96" w="12" h="12" />
|
||||
<part id="timeline_from_both_normal" x="240" y="108" w="12" h="12" />
|
||||
<part id="timeline_from_both_active" x="252" y="108" w="12" h="12" />
|
||||
<part id="timeline_left_link_active" x="264" y="84" w="12" h="12" />
|
||||
<part id="timeline_both_links_active" x="264" y="96" w="12" h="12" />
|
||||
<part id="timeline_right_link_active" x="264" y="108" w="12" h="12" />
|
||||
<part id="timeline_gear" x="264" y="12" w="12" h="12" />
|
||||
<part id="timeline_gear_active" x="264" y="24" w="12" h="12" />
|
||||
<part id="timeline_onionskin" x="264" y="36" w="12" h="12" />
|
||||
@ -355,6 +376,27 @@
|
||||
|
||||
<stylesheet>
|
||||
|
||||
<!-- label -->
|
||||
<style id="label">
|
||||
<text color="text" />
|
||||
</style>
|
||||
|
||||
<!-- link -->
|
||||
<style id="link">
|
||||
<text color="link_text" />
|
||||
</style>
|
||||
<style id="link:hover">
|
||||
<text color="link_hover" />
|
||||
</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" />
|
||||
@ -485,35 +527,35 @@
|
||||
<icon part="timeline_keyframe_active" />
|
||||
</style>
|
||||
|
||||
<style id="timeline_fromleft">
|
||||
<icon part="timeline_fromleft_normal" />
|
||||
<style id="timeline_from_left">
|
||||
<icon part="timeline_from_left_normal" />
|
||||
</style>
|
||||
<style id="timeline_fromleft:active">
|
||||
<icon part="timeline_fromleft_active" />
|
||||
<style id="timeline_from_left:active">
|
||||
<icon part="timeline_from_left_active" />
|
||||
</style>
|
||||
|
||||
<style id="timeline_fromright">
|
||||
<icon part="timeline_fromright_normal" />
|
||||
<style id="timeline_from_right">
|
||||
<icon part="timeline_from_right_normal" />
|
||||
</style>
|
||||
<style id="timeline_fromright:active">
|
||||
<icon part="timeline_fromright_active" />
|
||||
<style id="timeline_from_right:active">
|
||||
<icon part="timeline_from_right_active" />
|
||||
</style>
|
||||
|
||||
<style id="timeline_fromboth">
|
||||
<icon part="timeline_fromboth_normal" />
|
||||
<style id="timeline_from_both">
|
||||
<icon part="timeline_from_both_normal" />
|
||||
</style>
|
||||
<style id="timeline_fromboth:active">
|
||||
<icon part="timeline_fromboth_active" />
|
||||
<style id="timeline_from_both:active">
|
||||
<icon part="timeline_from_both_active" />
|
||||
</style>
|
||||
|
||||
<style id="timeline_leftlink">
|
||||
<icon part="timeline_leftlink_active" />
|
||||
<style id="timeline_left_link">
|
||||
<icon part="timeline_left_link_active" />
|
||||
</style>
|
||||
<style id="timeline_rightlink">
|
||||
<icon part="timeline_rightlink_active" />
|
||||
<style id="timeline_right_link">
|
||||
<icon part="timeline_right_link_active" />
|
||||
</style>
|
||||
<style id="timeline_bothlinks">
|
||||
<icon part="timeline_bothlinks_active" />
|
||||
<style id="timeline_both_links">
|
||||
<icon part="timeline_both_links_active" />
|
||||
</style>
|
||||
|
||||
<!-- timeline_gear -->
|
||||
@ -602,6 +644,156 @@
|
||||
<background color="hot_face" />
|
||||
</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>
|
||||
|
||||
<!-- 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" wordwrap="true" />
|
||||
</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>
|
||||
|
29
data/widgets/home_view.xml
Normal file
29
data/widgets/home_view.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2001-2015 by David Capello -->
|
||||
<gui>
|
||||
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
|
||||
<hbox noborders="true">
|
||||
<image file="icons/ase48.png" align="center" />
|
||||
<vbox border="4" childspacing="4">
|
||||
<link id="new_file" text="New File..." style="workspace_link" />
|
||||
<link id="open_file" text="Open File..." style="workspace_link" />
|
||||
</vbox>
|
||||
<boxfiller />
|
||||
<vbox border="4">
|
||||
<link id="check_update" text="" style="workspace_link" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
<hbox noborders="true" expansive="true" homogeneous="true" childspacing="2">
|
||||
<vbox noborders="true" childspacing="2">
|
||||
<label text="Recent files:" style="workspace_label" />
|
||||
<view id="files_view" expansive="true" style="workspace_view" />
|
||||
<label text="Recent folders:" style="workspace_label" />
|
||||
<view id="folders_view" expansive="true" style="workspace_view" />
|
||||
</vbox>
|
||||
<vbox noborders="true" childspacing="2">
|
||||
<label text="News:" style="workspace_label" />
|
||||
<view id="news_view" expansive="true" style="workspace_view" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</gui>
|
@ -1,26 +1,28 @@
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2001-2014 by David Capello -->
|
||||
<!-- Copyright (C) 2001-2015 by David Capello -->
|
||||
<gui>
|
||||
<vbox noborders="true" id="main_box">
|
||||
<hbox noborders="true" id="menubar" />
|
||||
<hbox noborders="true" id="tabsbar" />
|
||||
<splitter id="colorbarsplitter"
|
||||
horizontal="true" expansive="true"
|
||||
by="pixel">
|
||||
<vbox noborders="true" id="colorbar" />
|
||||
<vbox noborders="true" expansive="true">
|
||||
<vbox noborders="true" id="contextbar" />
|
||||
<hbox noborders="true" expansive="true">
|
||||
<splitter id="timelinesplitter"
|
||||
vertical="true" expansive="true"
|
||||
by="percetage" position="100">
|
||||
<hbox noborders="true" id="workspace" expansive="true" />
|
||||
<vbox noborders="true" id="timeline" expansive="true" />
|
||||
</splitter>
|
||||
<vbox noborders="true" id="toolbar" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</splitter>
|
||||
<hbox noborders="true" id="statusbar" />
|
||||
</vbox>
|
||||
<window id="main_window" noborders="true" desktop="true">
|
||||
<vbox noborders="true" expansive="true">
|
||||
<hbox noborders="true" id="menu_bar_placeholder" />
|
||||
<hbox noborders="true" id="tabs_placeholder" />
|
||||
<splitter id="color_bar_splitter"
|
||||
horizontal="true" expansive="true"
|
||||
by="pixel">
|
||||
<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">
|
||||
<hbox noborders="true" id="workspace_placeholder" expansive="true" />
|
||||
<vbox noborders="true" id="timeline_placeholder" expansive="true" />
|
||||
</splitter>
|
||||
<vbox noborders="true" id="tool_bar_placeholder" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</splitter>
|
||||
<hbox noborders="true" id="status_bar_placeholder" />
|
||||
</vbox>
|
||||
</window>
|
||||
</gui>
|
||||
|
@ -47,7 +47,7 @@ AL_FUNC(void, register_trace_handler, (AL_METHOD(int, handler, (AL_CONST char *m
|
||||
|
||||
#ifndef TRACE
|
||||
#define TRACE 1 ? (void) 0 : al_trace
|
||||
#endif TRACE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,9 +1,7 @@
|
||||
# Aseprite
|
||||
# Copyright (C) 2001-2015 David Capello
|
||||
|
||||
######################################################################
|
||||
# Generate source files from widget XML files
|
||||
|
||||
# Generate a ui::Widget for each widget in a XML file
|
||||
file(GLOB widget_files ${CMAKE_SOURCE_DIR}/data/widgets/*.xml)
|
||||
foreach(widget_file ${widget_files})
|
||||
get_filename_component(widget_name ${widget_file} NAME_WE)
|
||||
@ -19,7 +17,7 @@ foreach(widget_file ${widget_files})
|
||||
list(APPEND generated_files ${output_fn})
|
||||
endforeach()
|
||||
|
||||
# pref.h and pref.cpp
|
||||
# Generate preference types from data/pref.xml
|
||||
set(pref_xml ${CMAKE_SOURCE_DIR}/data/pref.xml)
|
||||
|
||||
set(output_fn ${CMAKE_CURRENT_BINARY_DIR}/generated_pref_types.h)
|
||||
@ -40,6 +38,17 @@ add_custom_command(
|
||||
DEPENDS gen)
|
||||
list(APPEND generated_files ${output_fn})
|
||||
|
||||
# Generate generated_skin.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}/generated_skin.h)
|
||||
add_custom_command(
|
||||
OUTPUT ${output_fn}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/gen --input ${skin_xml} --skin > ${output_fn}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
MAIN_DEPENDENCY ${skin_xml}
|
||||
DEPENDS gen)
|
||||
list(APPEND generated_files ${output_fn})
|
||||
|
||||
# Directory where generated files by "gen" utility will stay.
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
@ -148,6 +157,7 @@ add_library(app-lib
|
||||
commands/cmd_goto_layer.cpp
|
||||
commands/cmd_goto_tab.cpp
|
||||
commands/cmd_grid.cpp
|
||||
commands/cmd_home.cpp
|
||||
commands/cmd_import_sprite_sheet.cpp
|
||||
commands/cmd_invert_mask.cpp
|
||||
commands/cmd_keyboard_shortcuts.cpp
|
||||
@ -190,7 +200,6 @@ add_library(app-lib
|
||||
commands/cmd_scroll.cpp
|
||||
commands/cmd_set_loop_section.cpp
|
||||
commands/cmd_set_palette.cpp
|
||||
commands/cmd_sprite_editor.cpp
|
||||
commands/cmd_sprite_properties.cpp
|
||||
commands/cmd_sprite_size.cpp
|
||||
commands/cmd_switch_colors.cpp
|
||||
@ -257,6 +266,7 @@ add_library(app-lib
|
||||
pref/preferences.cpp
|
||||
project.cpp
|
||||
recent_files.cpp
|
||||
res/http_loader.cpp
|
||||
res/palettes_loader_delegate.cpp
|
||||
res/resources_loader.cpp
|
||||
resource_finder.cpp
|
||||
@ -303,32 +313,34 @@ add_library(app-lib
|
||||
ui/file_list.cpp
|
||||
ui/file_selector.cpp
|
||||
ui/hex_color_entry.cpp
|
||||
ui/home_view.cpp
|
||||
ui/keyboard_shortcuts.cpp
|
||||
ui/main_menu_bar.cpp
|
||||
ui/main_window.cpp
|
||||
ui/news_listbox.cpp
|
||||
ui/notifications.cpp
|
||||
ui/palette_popup.cpp
|
||||
ui/palette_view.cpp
|
||||
ui/palettes_listbox.cpp
|
||||
ui/popup_window_pin.cpp
|
||||
ui/preview_editor.cpp
|
||||
ui/recent_listbox.cpp
|
||||
ui/resources_listbox.cpp
|
||||
ui/select_accelerator.cpp
|
||||
ui/skin/button_icon_impl.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/start_view.cpp
|
||||
ui/status_bar.cpp
|
||||
ui/styled_button.cpp
|
||||
ui/tabs.cpp
|
||||
ui/timeline.cpp
|
||||
ui/toolbar.cpp
|
||||
ui/workspace.cpp
|
||||
ui/workspace_part.cpp
|
||||
ui_context.cpp
|
||||
util/autocrop.cpp
|
||||
util/boundary.cpp
|
||||
|
@ -451,7 +451,8 @@ void App::run()
|
||||
if (isGui()) {
|
||||
#ifdef ENABLE_UPDATER
|
||||
// Launch the thread to check for updates.
|
||||
app::CheckUpdateThreadLauncher checkUpdate;
|
||||
app::CheckUpdateThreadLauncher checkUpdate(
|
||||
m_mainWindow->getCheckUpdateDelegate());
|
||||
checkUpdate.launch();
|
||||
#endif
|
||||
|
||||
@ -617,7 +618,7 @@ void app_refresh_screen()
|
||||
void app_rebuild_documents_tabs()
|
||||
{
|
||||
if (App::instance()->isGui())
|
||||
App::instance()->getMainWindow()->getTabsBar()->updateTabsText();
|
||||
App::instance()->getMainWindow()->getTabsBar()->updateTabs();
|
||||
}
|
||||
|
||||
PixelFormat app_get_current_pixel_format()
|
||||
|
@ -57,6 +57,9 @@ AppMenus* AppMenus::instance()
|
||||
AppMenus::AppMenus()
|
||||
: m_recentListMenuitem(NULL)
|
||||
{
|
||||
m_recentFilesConn =
|
||||
App::instance()->getRecentFiles()->Changed.connect(
|
||||
Bind(&AppMenus::rebuildRecentList, this));
|
||||
}
|
||||
|
||||
void AppMenus::reload()
|
||||
@ -78,6 +81,7 @@ void AppMenus::reload()
|
||||
|
||||
PRINTF("Main menu loaded.\n");
|
||||
|
||||
m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup"));
|
||||
m_documentTabPopupMenu.reset(loadMenuById(handle, "document_tab_popup"));
|
||||
m_layerPopupMenu.reset(loadMenuById(handle, "layer_popup"));
|
||||
m_framePopupMenu.reset(loadMenuById(handle, "frame_popup"));
|
||||
|
@ -39,6 +39,7 @@ namespace app {
|
||||
|
||||
Menu* getRootMenu() { return m_rootMenu; }
|
||||
MenuItem* getRecentListMenuitem() { return m_recentListMenuitem; }
|
||||
Menu* getTabPopupMenu() { return m_tabPopupMenu; }
|
||||
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu; }
|
||||
Menu* getLayerPopupMenu() { return m_layerPopupMenu; }
|
||||
Menu* getFramePopupMenu() { return m_framePopupMenu; }
|
||||
@ -56,11 +57,13 @@ namespace app {
|
||||
|
||||
base::UniquePtr<Menu> m_rootMenu;
|
||||
MenuItem* m_recentListMenuitem;
|
||||
base::UniquePtr<Menu> m_tabPopupMenu;
|
||||
base::UniquePtr<Menu> m_documentTabPopupMenu;
|
||||
base::UniquePtr<Menu> m_layerPopupMenu;
|
||||
base::UniquePtr<Menu> m_framePopupMenu;
|
||||
base::UniquePtr<Menu> m_celPopupMenu;
|
||||
base::UniquePtr<Menu> m_celMovementPopupMenu;
|
||||
ScopedConnection m_recentFilesConn;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -13,9 +13,10 @@
|
||||
|
||||
#include "app/check_update.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/check_update_delegate.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/launcher.h"
|
||||
|
||||
#include <ctime>
|
||||
@ -74,8 +75,9 @@ private:
|
||||
updater::CheckUpdateResponse m_response;
|
||||
};
|
||||
|
||||
CheckUpdateThreadLauncher::CheckUpdateThreadLauncher()
|
||||
: m_doCheck(true)
|
||||
CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate)
|
||||
: m_delegate(delegate)
|
||||
, m_doCheck(true)
|
||||
, m_received(false)
|
||||
, m_inits(get_config_int("Updater", "Inits", 0))
|
||||
, m_exits(get_config_int("Updater", "Exits", 0))
|
||||
@ -87,14 +89,14 @@ CheckUpdateThreadLauncher::CheckUpdateThreadLauncher()
|
||||
, m_timer(kMonitoringPeriod, NULL)
|
||||
{
|
||||
// Get how many days we have to wait for the next "check for update"
|
||||
int waitDays = get_config_int("Updater", "WaitDays", 0);
|
||||
if (waitDays > 0) {
|
||||
double waitDays = get_config_double("Updater", "WaitDays", 0.0);
|
||||
if (waitDays > 0.0) {
|
||||
// Get the date of the last "check for updates"
|
||||
time_t lastCheck = (time_t)get_config_int("Updater", "LastCheck", 0);
|
||||
time_t now = std::time(NULL);
|
||||
|
||||
// Verify if we are in the "WaitDays" period...
|
||||
if (now < lastCheck+60*60*24*waitDays &&
|
||||
if (now < lastCheck+int(double(60*60*24*waitDays)) &&
|
||||
now > lastCheck) { // <- Avoid broken clocks
|
||||
// So we do not check for updates.
|
||||
m_doCheck = false;
|
||||
@ -133,6 +135,8 @@ void CheckUpdateThreadLauncher::launch()
|
||||
if (m_uuid.empty())
|
||||
m_uuid = get_config_string("Updater", "Uuid", "");
|
||||
|
||||
m_delegate->onCheckingUpdates();
|
||||
|
||||
m_bgJob.reset(new CheckUpdateBackgroundJob);
|
||||
m_thread.reset(new base::thread(Bind<void>(&CheckUpdateThreadLauncher::checkForUpdates, this)));
|
||||
|
||||
@ -158,12 +162,14 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
|
||||
switch (m_response.getUpdateType()) {
|
||||
|
||||
case updater::CheckUpdateResponse::NoUpdate:
|
||||
// Nothing to do, we are up-to-date
|
||||
m_delegate->onUpToDate();
|
||||
break;
|
||||
|
||||
case updater::CheckUpdateResponse::Critical:
|
||||
case updater::CheckUpdateResponse::Major:
|
||||
App::instance()->showNotification(this);
|
||||
m_delegate->onNewUpdate(
|
||||
m_response.getUrl(),
|
||||
base::convert_to<std::string>(m_response.getLatestVersion()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -175,7 +181,7 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
|
||||
|
||||
// Set the date of the last "check for updates" and the "WaitDays" parameter.
|
||||
set_config_int("Updater", "LastCheck", (int)std::time(NULL));
|
||||
set_config_int("Updater", "WaitDays", m_response.getWaitDays());
|
||||
set_config_double("Updater", "WaitDays", m_response.getWaitDays());
|
||||
|
||||
// Save the config file right now
|
||||
flush_config_file();
|
||||
@ -204,17 +210,6 @@ void CheckUpdateThreadLauncher::checkForUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
std::string CheckUpdateThreadLauncher::notificationText()
|
||||
{
|
||||
return "New Version Available!";
|
||||
}
|
||||
|
||||
void CheckUpdateThreadLauncher::notificationClick()
|
||||
{
|
||||
if (!m_response.getUrl().empty())
|
||||
base::launcher::open_url(m_response.getUrl());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ENABLE_UPDATER
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
|
||||
#include "app/notification_delegate.h"
|
||||
#include "base/thread.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "ui/timer.h"
|
||||
@ -19,11 +18,12 @@
|
||||
|
||||
namespace app {
|
||||
|
||||
class CheckUpdateDelegate;
|
||||
class CheckUpdateBackgroundJob;
|
||||
|
||||
class CheckUpdateThreadLauncher : public INotificationDelegate {
|
||||
class CheckUpdateThreadLauncher {
|
||||
public:
|
||||
CheckUpdateThreadLauncher();
|
||||
CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate);
|
||||
~CheckUpdateThreadLauncher();
|
||||
|
||||
void launch();
|
||||
@ -35,13 +35,11 @@ namespace app {
|
||||
return m_response;
|
||||
}
|
||||
|
||||
virtual std::string notificationText() override;
|
||||
virtual void notificationClick() override;
|
||||
|
||||
private:
|
||||
void onMonitoringTick();
|
||||
void checkForUpdates();
|
||||
|
||||
CheckUpdateDelegate* m_delegate;
|
||||
updater::Uuid m_uuid;
|
||||
base::UniquePtr<base::thread> m_thread;
|
||||
base::UniquePtr<CheckUpdateBackgroundJob> m_bgJob;
|
||||
|
30
src/app/check_update_delegate.h
Normal file
30
src/app/check_update_delegate.h
Normal file
@ -0,0 +1,30 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_CHECK_UPDATE_DELEGATE_H_INCLUDED
|
||||
#define APP_CHECK_UPDATE_DELEGATE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
|
||||
class CheckUpdateDelegate {
|
||||
public:
|
||||
virtual ~CheckUpdateDelegate() { }
|
||||
virtual void onCheckingUpdates() = 0;
|
||||
virtual void onUpToDate() = 0;
|
||||
virtual void onNewUpdate(const std::string& url, const std::string& version) = 0;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif // ENABLE_UPDATER
|
||||
|
||||
#endif // APP_CHECK_UPDATE_DELEGATE_H_INCLUDED
|
@ -29,53 +29,30 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
static bool close_active_document(Context* context);
|
||||
|
||||
class CloseFileCommand : public Command {
|
||||
public:
|
||||
CloseFileCommand()
|
||||
: Command("CloseFile",
|
||||
"Close File",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
CmdUIOnlyFlag) {
|
||||
}
|
||||
|
||||
Command* clone() const override { return new CloseFileCommand(*this); }
|
||||
|
||||
protected:
|
||||
|
||||
bool onEnabled(Context* context)
|
||||
{
|
||||
const ContextReader reader(context);
|
||||
const Sprite* sprite(reader.sprite());
|
||||
return sprite != NULL;
|
||||
}
|
||||
|
||||
void onExecute(Context* context)
|
||||
{
|
||||
bool onEnabled(Context* context) override {
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
|
||||
if (workspace->activeView() == NULL)
|
||||
return;
|
||||
|
||||
if (DocumentView* docView =
|
||||
dynamic_cast<DocumentView*>(workspace->activeView())) {
|
||||
Document* document = docView->getDocument();
|
||||
if (static_cast<UIContext*>(context)->countViewsOf(document) == 1) {
|
||||
// If we have only one view for this document, close the file.
|
||||
close_active_document(context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the active view.
|
||||
WorkspaceView* view = workspace->activeView();
|
||||
workspace->removeView(view);
|
||||
delete view;
|
||||
return (view != nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
static char* read_authors_txt(const char *filename);
|
||||
void onExecute(Context* context) override {
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
WorkspaceView* view = workspace->activeView();
|
||||
if (view)
|
||||
workspace->closeView(view);
|
||||
}
|
||||
};
|
||||
|
||||
class CloseAllFilesCommand : public Command {
|
||||
@ -83,96 +60,31 @@ public:
|
||||
CloseAllFilesCommand()
|
||||
: Command("CloseAllFiles",
|
||||
"Close All Files",
|
||||
CmdRecordableFlag)
|
||||
{
|
||||
CmdRecordableFlag) {
|
||||
}
|
||||
|
||||
Command* clone() const override { return new CloseAllFilesCommand(*this); }
|
||||
|
||||
protected:
|
||||
|
||||
bool onEnabled(Context* context)
|
||||
{
|
||||
return !context->documents().empty();
|
||||
}
|
||||
void onExecute(Context* context) override {
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
|
||||
void onExecute(Context* context)
|
||||
{
|
||||
while (true) {
|
||||
if (context->activeDocument() != NULL) {
|
||||
if (!close_active_document(context))
|
||||
break;
|
||||
}
|
||||
else
|
||||
std::vector<DocumentView*> docViews;
|
||||
for (auto view : *workspace) {
|
||||
DocumentView* docView = dynamic_cast<DocumentView*>(view);
|
||||
if (docView)
|
||||
docViews.push_back(docView);
|
||||
}
|
||||
|
||||
for (auto docView : docViews) {
|
||||
if (!workspace->closeView(docView))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Closes the active document, asking to the user to save it if it is
|
||||
// modified.
|
||||
static bool close_active_document(Context* context)
|
||||
{
|
||||
Document* closedDocument = NULL;
|
||||
bool save_it;
|
||||
bool try_again = true;
|
||||
|
||||
while (try_again) {
|
||||
// This flag indicates if we have to sabe the sprite before to destroy it
|
||||
save_it = false;
|
||||
{
|
||||
// The sprite is locked as reader temporaly
|
||||
const ContextReader reader(context);
|
||||
const Document* document = reader.document();
|
||||
closedDocument = const_cast<Document*>(document);
|
||||
|
||||
// see if the sprite has changes
|
||||
while (document->isModified()) {
|
||||
// ask what want to do the user with the changes in the sprite
|
||||
int ret = Alert::show("Warning<<Saving changes in:<<%s||&Save||Do&n't Save||&Cancel",
|
||||
document->name().c_str());
|
||||
|
||||
if (ret == 1) {
|
||||
// "save": save the changes
|
||||
save_it = true;
|
||||
break;
|
||||
}
|
||||
else if (ret != 2) {
|
||||
// "cancel" or "ESC" */
|
||||
return false; // we back doing nothing
|
||||
}
|
||||
else {
|
||||
// "discard"
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Does we need to save the sprite?
|
||||
if (save_it) {
|
||||
Command* save_command =
|
||||
CommandsModule::instance()->getCommandByName(CommandId::SaveFile);
|
||||
context->executeCommand(save_command);
|
||||
|
||||
try_again = true;
|
||||
}
|
||||
else
|
||||
try_again = false;
|
||||
}
|
||||
|
||||
// Destroy the sprite (locking it as writer)
|
||||
{
|
||||
DocumentDestroyer document(context, closedDocument);
|
||||
StatusBar::instance()
|
||||
->setStatusText(0, "Sprite '%s' closed.",
|
||||
document->name().c_str());
|
||||
document.destroyDocument();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Command* CommandFactory::createCloseFileCommand()
|
||||
{
|
||||
return new CloseFileCommand;
|
||||
|
@ -11,15 +11,7 @@
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context.h"
|
||||
#include "app/document.h"
|
||||
#include "app/ui/devconsole_view.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "ui/box.h"
|
||||
#include "ui/button.h"
|
||||
#include "ui/combobox.h"
|
||||
#include "ui/window.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -32,8 +24,6 @@ public:
|
||||
|
||||
protected:
|
||||
void onExecute(Context* context);
|
||||
|
||||
DevConsoleView* m_devConsole;
|
||||
};
|
||||
|
||||
DeveloperConsoleCommand::DeveloperConsoleCommand()
|
||||
@ -41,24 +31,15 @@ DeveloperConsoleCommand::DeveloperConsoleCommand()
|
||||
"Developer Console",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
m_devConsole = NULL;
|
||||
}
|
||||
|
||||
DeveloperConsoleCommand::~DeveloperConsoleCommand()
|
||||
{
|
||||
delete m_devConsole;
|
||||
}
|
||||
|
||||
void DeveloperConsoleCommand::onExecute(Context* context)
|
||||
{
|
||||
if (!m_devConsole) {
|
||||
m_devConsole = new DevConsoleView();
|
||||
|
||||
App::instance()->getMainWindow()->getWorkspace()->addView(m_devConsole);
|
||||
}
|
||||
|
||||
App::instance()->getMainWindow()->getTabsBar()->selectTab(m_devConsole);
|
||||
App::instance()->getMainWindow()->getWorkspace()->setActiveView(m_devConsole);
|
||||
App::instance()->getMainWindow()->showDevConsole();
|
||||
}
|
||||
|
||||
Command* CommandFactory::createDeveloperConsoleCommand()
|
||||
|
@ -63,7 +63,7 @@ namespace {
|
||||
int nframes = sprite->totalFrames();
|
||||
int framew = sprite->width();
|
||||
int frameh = sprite->height();
|
||||
Fit result(framew*nframes, frameh, nframes, INT_MAX);
|
||||
Fit result(framew*nframes, frameh, nframes, std::numeric_limits<int>::max());
|
||||
int w, h;
|
||||
|
||||
for (w=2; w < framew; w*=2)
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "she/surface.h"
|
||||
#include "she/system.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define PREVIEW_TILED 1
|
||||
#define PREVIEW_FIT_ON_SCREEN 2
|
||||
|
||||
@ -120,10 +122,10 @@ protected:
|
||||
|
||||
// Change frame
|
||||
if (command != NULL &&
|
||||
(strcmp(command->short_name(), CommandId::GotoFirstFrame) == 0 ||
|
||||
strcmp(command->short_name(), CommandId::GotoPreviousFrame) == 0 ||
|
||||
strcmp(command->short_name(), CommandId::GotoNextFrame) == 0 ||
|
||||
strcmp(command->short_name(), CommandId::GotoLastFrame) == 0)) {
|
||||
(std::strcmp(command->short_name(), CommandId::GotoFirstFrame) == 0 ||
|
||||
std::strcmp(command->short_name(), CommandId::GotoPreviousFrame) == 0 ||
|
||||
std::strcmp(command->short_name(), CommandId::GotoNextFrame) == 0 ||
|
||||
std::strcmp(command->short_name(), CommandId::GotoLastFrame) == 0)) {
|
||||
m_context->executeCommand(command);
|
||||
invalidate();
|
||||
m_render.reset(NULL); // Re-render
|
||||
@ -131,7 +133,7 @@ protected:
|
||||
#if 0
|
||||
// Play the animation
|
||||
else if (command != NULL &&
|
||||
strcmp(command->short_name(), CommandId::PlayAnimation) == 0) {
|
||||
std::strcmp(command->short_name(), CommandId::PlayAnimation) == 0) {
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
|
50
src/app/commands/cmd_home.cpp
Normal file
50
src/app/commands/cmd_home.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/ui/main_window.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
class HomeCommand : public Command {
|
||||
public:
|
||||
HomeCommand();
|
||||
~HomeCommand();
|
||||
|
||||
protected:
|
||||
void onExecute(Context* context);
|
||||
};
|
||||
|
||||
HomeCommand::HomeCommand()
|
||||
: Command("Home",
|
||||
"Home",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
}
|
||||
|
||||
HomeCommand::~HomeCommand()
|
||||
{
|
||||
}
|
||||
|
||||
void HomeCommand::onExecute(Context* context)
|
||||
{
|
||||
App::instance()->getMainWindow()->showHome();
|
||||
}
|
||||
|
||||
Command* CommandFactory::createHomeCommand()
|
||||
{
|
||||
return new HomeCommand;
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -140,12 +140,12 @@ private:
|
||||
gfx::Color fg, bg;
|
||||
|
||||
if (isSelected()) {
|
||||
fg = theme->getColor(ThemeColor::ListItemSelectedText);
|
||||
bg = theme->getColor(ThemeColor::ListItemSelectedFace);
|
||||
fg = theme->colors.listitemSelectedText();
|
||||
bg = theme->colors.listitemSelectedFace();
|
||||
}
|
||||
else {
|
||||
fg = theme->getColor(ThemeColor::ListItemNormalText);
|
||||
bg = theme->getColor(ThemeColor::ListItemNormalFace);
|
||||
fg = theme->colors.listitemNormalText();
|
||||
bg = theme->colors.listitemNormalFace();
|
||||
}
|
||||
|
||||
g->fillRect(bg, bounds);
|
||||
|
@ -17,14 +17,15 @@
|
||||
#include "app/find_widget.h"
|
||||
#include "app/load_widget.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/transaction.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -126,8 +127,8 @@ static int get_max_layer_num(Layer* layer)
|
||||
{
|
||||
int max = 0;
|
||||
|
||||
if (strncmp(layer->name().c_str(), "Layer ", 6) == 0)
|
||||
max = strtol(layer->name().c_str()+6, NULL, 10);
|
||||
if (std::strncmp(layer->name().c_str(), "Layer ", 6) == 0)
|
||||
max = std::strtol(layer->name().c_str()+6, NULL, 10);
|
||||
|
||||
if (layer->isFolder()) {
|
||||
LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/path.h"
|
||||
#include "base/thread.h"
|
||||
#include "base/unique_ptr.h"
|
||||
#include "doc/sprite.h"
|
||||
@ -43,6 +44,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::string m_filename;
|
||||
std::string m_folder;
|
||||
};
|
||||
|
||||
class OpenFileJob : public Job, public IFileOpProgress
|
||||
@ -93,12 +95,12 @@ OpenFileCommand::OpenFileCommand()
|
||||
"Open Sprite",
|
||||
CmdRecordableFlag)
|
||||
{
|
||||
m_filename = "";
|
||||
}
|
||||
|
||||
void OpenFileCommand::onLoadParams(Params* params)
|
||||
{
|
||||
m_filename = params->get("filename");
|
||||
m_folder = params->get("folder"); // Initial folder
|
||||
}
|
||||
|
||||
void OpenFileCommand::onExecute(Context* context)
|
||||
@ -109,7 +111,13 @@ void OpenFileCommand::onExecute(Context* context)
|
||||
if (context->isUiAvailable() && m_filename.empty()) {
|
||||
char exts[4096];
|
||||
get_readable_extensions(exts, sizeof(exts));
|
||||
m_filename = app::show_file_selector("Open", "", exts,
|
||||
|
||||
// Add backslash as show_file_selector() expected a filename as
|
||||
// initial path (and the file part is removed from the path).
|
||||
if (!m_folder.empty() && !base::is_path_separator(m_folder[m_folder.size()-1]))
|
||||
m_folder.push_back(base::path_separator);
|
||||
|
||||
m_filename = app::show_file_selector("Open", m_folder, exts,
|
||||
FileSelectorType::Open);
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ public:
|
||||
|
||||
private:
|
||||
void onChangeSection() {
|
||||
ListItem* item = sectionListbox()->getSelectedChild();
|
||||
ListItem* item = static_cast<ListItem*>(sectionListbox()->getSelectedChild());
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
|
@ -1,104 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "ui/base.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class MakeUniqueEditorCommand : public Command {
|
||||
public:
|
||||
MakeUniqueEditorCommand();
|
||||
Command* clone() const override { return new MakeUniqueEditorCommand(*this); }
|
||||
|
||||
protected:
|
||||
void onExecute(Context* context);
|
||||
};
|
||||
|
||||
MakeUniqueEditorCommand::MakeUniqueEditorCommand()
|
||||
: Command("MakeUniqueEditor",
|
||||
"Make Unique Editor",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void MakeUniqueEditorCommand::onExecute(Context* context)
|
||||
{
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
if (workspace->activeView() != NULL)
|
||||
workspace->makeUnique(workspace->activeView());
|
||||
}
|
||||
|
||||
class SplitEditorHorizontallyCommand : public Command {
|
||||
public:
|
||||
SplitEditorHorizontallyCommand();
|
||||
Command* clone() const override { return new SplitEditorHorizontallyCommand(*this); }
|
||||
|
||||
protected:
|
||||
void onExecute(Context* context);
|
||||
};
|
||||
|
||||
SplitEditorHorizontallyCommand::SplitEditorHorizontallyCommand()
|
||||
: Command("SplitEditorHorizontally",
|
||||
"Split Editor Horizontally",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void SplitEditorHorizontallyCommand::onExecute(Context* context)
|
||||
{
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
if (workspace->activeView() != NULL)
|
||||
workspace->splitView(workspace->activeView(), JI_HORIZONTAL);
|
||||
}
|
||||
|
||||
class SplitEditorVerticallyCommand : public Command {
|
||||
public:
|
||||
SplitEditorVerticallyCommand();
|
||||
Command* clone() const override { return new SplitEditorVerticallyCommand(*this); }
|
||||
|
||||
protected:
|
||||
void onExecute(Context* context);
|
||||
};
|
||||
|
||||
SplitEditorVerticallyCommand::SplitEditorVerticallyCommand()
|
||||
: Command("SplitEditorVertically",
|
||||
"Split Editor Vertically",
|
||||
CmdUIOnlyFlag)
|
||||
{
|
||||
}
|
||||
|
||||
void SplitEditorVerticallyCommand::onExecute(Context* context)
|
||||
{
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
if (workspace->activeView() != NULL)
|
||||
workspace->splitView(workspace->activeView(), JI_VERTICAL);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createMakeUniqueEditorCommand()
|
||||
{
|
||||
return new MakeUniqueEditorCommand;
|
||||
}
|
||||
|
||||
Command* CommandFactory::createSplitEditorHorizontallyCommand()
|
||||
{
|
||||
return new SplitEditorHorizontallyCommand;
|
||||
}
|
||||
|
||||
Command* CommandFactory::createSplitEditorVerticallyCommand()
|
||||
{
|
||||
return new SplitEditorVerticallyCommand;
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -49,6 +49,7 @@ FOR_EACH_COMMAND(GotoPreviousFrame)
|
||||
FOR_EACH_COMMAND(GotoPreviousLayer)
|
||||
FOR_EACH_COMMAND(GotoPreviousTab)
|
||||
FOR_EACH_COMMAND(GridSettings)
|
||||
FOR_EACH_COMMAND(Home)
|
||||
FOR_EACH_COMMAND(ImportSpriteSheet)
|
||||
FOR_EACH_COMMAND(InvertColor)
|
||||
FOR_EACH_COMMAND(InvertMask)
|
||||
@ -59,7 +60,6 @@ FOR_EACH_COMMAND(LayerProperties)
|
||||
FOR_EACH_COMMAND(LayerVisibility)
|
||||
FOR_EACH_COMMAND(LoadMask)
|
||||
FOR_EACH_COMMAND(LoadPalette)
|
||||
FOR_EACH_COMMAND(MakeUniqueEditor)
|
||||
FOR_EACH_COMMAND(MaskAll)
|
||||
FOR_EACH_COMMAND(MaskByColor)
|
||||
FOR_EACH_COMMAND(MaskContent)
|
||||
@ -100,8 +100,6 @@ FOR_EACH_COMMAND(ShowGrid)
|
||||
FOR_EACH_COMMAND(ShowOnionSkin)
|
||||
FOR_EACH_COMMAND(ShowPixelGrid)
|
||||
FOR_EACH_COMMAND(SnapToGrid)
|
||||
FOR_EACH_COMMAND(SplitEditorHorizontally)
|
||||
FOR_EACH_COMMAND(SplitEditorVertically)
|
||||
FOR_EACH_COMMAND(SpriteProperties)
|
||||
FOR_EACH_COMMAND(SpriteSize)
|
||||
FOR_EACH_COMMAND(SwitchColors)
|
||||
|
@ -124,7 +124,7 @@ private:
|
||||
|
||||
void onMatrixChange()
|
||||
{
|
||||
ListItem* selected = m_stockListBox->getSelectedChild();
|
||||
Widget* selected = m_stockListBox->getSelectedChild();
|
||||
SharedPtr<ConvolutionMatrix> matrix = m_stock.getByName(selected->getText().c_str());
|
||||
Target newTarget = matrix->getDefaultTarget();
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include "app/recent_files.h"
|
||||
|
||||
#include "app/app_menus.h"
|
||||
#include "app/ini_file.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/path.h"
|
||||
@ -90,7 +89,7 @@ void RecentFiles::addRecentFile(const char* filename)
|
||||
m_files.addItem(filename);
|
||||
m_paths.addItem(base::get_file_path(filename));
|
||||
|
||||
AppMenus::instance()->rebuildRecentList();
|
||||
Changed();
|
||||
}
|
||||
|
||||
void RecentFiles::removeRecentFile(const char* filename)
|
||||
@ -98,7 +97,7 @@ void RecentFiles::removeRecentFile(const char* filename)
|
||||
m_files.removeItem(filename);
|
||||
m_paths.removeItem(base::get_file_path(filename));
|
||||
|
||||
AppMenus::instance()->rebuildRecentList();
|
||||
Changed();
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/recent_items.h"
|
||||
#include "base/signal.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -35,6 +36,8 @@ namespace app {
|
||||
void addRecentFile(const char* filename);
|
||||
void removeRecentFile(const char* filename);
|
||||
|
||||
Signal0<void> Changed;
|
||||
|
||||
private:
|
||||
List m_files;
|
||||
List m_paths;
|
||||
|
79
src/app/res/http_loader.cpp
Normal file
79
src/app/res/http_loader.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/res/http_loader.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/replace_string.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/path.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "net/http_request.h"
|
||||
#include "net/http_response.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace app {
|
||||
|
||||
HttpLoader::HttpLoader(const std::string& url)
|
||||
: m_url(url)
|
||||
, m_done(false)
|
||||
, m_cancel(false)
|
||||
, m_thread(Bind<void>(&HttpLoader::threadHttpRequest, this))
|
||||
{
|
||||
}
|
||||
|
||||
HttpLoader::~HttpLoader()
|
||||
{
|
||||
m_thread.join();
|
||||
}
|
||||
|
||||
void HttpLoader::cancel()
|
||||
{
|
||||
m_cancel = true;
|
||||
}
|
||||
|
||||
void HttpLoader::threadHttpRequest()
|
||||
{
|
||||
try {
|
||||
base::ScopedValue<bool> scoped(m_done, false, true);
|
||||
|
||||
PRINTF("Sending http request to %s...\n", m_url.c_str());
|
||||
|
||||
std::string dir = base::join_path(getenv("TEMP"), PACKAGE);
|
||||
base::make_all_directories(dir);
|
||||
|
||||
std::string fn = m_url;
|
||||
base::replace_string(fn, ":", "-");
|
||||
base::replace_string(fn, "/", "-");
|
||||
base::replace_string(fn, "?", "-");
|
||||
base::replace_string(fn, "&", "-");
|
||||
fn = base::join_path(dir, fn);
|
||||
|
||||
std::ofstream output(fn);
|
||||
net::HttpRequest http(m_url);
|
||||
net::HttpResponse response(&output);
|
||||
http.send(response);
|
||||
|
||||
if (response.status() == 200)
|
||||
m_filename = fn;
|
||||
|
||||
PRINTF("Response: %d\n", response.status());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
PRINTF("Unexpected exception sending http request: '%s'\n", e.what());
|
||||
}
|
||||
catch (...) {
|
||||
PRINTF("Unexpected unknown exception sending http request\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
38
src/app/res/http_loader.h
Normal file
38
src/app/res/http_loader.h
Normal file
@ -0,0 +1,38 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_RES_HTTP_LOADER_H_INCLUDED
|
||||
#define APP_RES_HTTP_LOADER_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/thread.h"
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
|
||||
class HttpLoader {
|
||||
public:
|
||||
HttpLoader(const std::string& url);
|
||||
~HttpLoader();
|
||||
|
||||
void cancel();
|
||||
bool isDone() const { return m_done; }
|
||||
std::string filename() const { return m_filename; }
|
||||
|
||||
private:
|
||||
void threadHttpRequest();
|
||||
|
||||
std::string m_url;
|
||||
bool m_done;
|
||||
bool m_cancel;
|
||||
base::thread m_thread;
|
||||
std::string m_filename;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -43,11 +43,6 @@ void ResourcesLoader::cancel()
|
||||
m_cancel = true;
|
||||
}
|
||||
|
||||
bool ResourcesLoader::done()
|
||||
{
|
||||
return m_done;
|
||||
}
|
||||
|
||||
bool ResourcesLoader::next(base::UniquePtr<Resource>& resource)
|
||||
{
|
||||
Resource* rawResource;
|
||||
|
@ -24,7 +24,6 @@ namespace app {
|
||||
~ResourcesLoader();
|
||||
|
||||
void cancel();
|
||||
bool done();
|
||||
bool isDone() const { return m_done; }
|
||||
|
||||
bool next(base::UniquePtr<Resource>& resource);
|
||||
|
@ -71,11 +71,11 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
if (isSelected() || hasMouseOver()) {
|
||||
nw = PART_TOOLBUTTON_HOT_NW;
|
||||
face = theme->getColor(ThemeColor::ButtonHotFace);
|
||||
face = theme->colors.buttonHotFace();
|
||||
}
|
||||
else {
|
||||
nw = PART_TOOLBUTTON_LAST_NW;
|
||||
face = theme->getColor(ThemeColor::ButtonNormalFace);
|
||||
face = theme->colors.buttonNormalFace();
|
||||
}
|
||||
|
||||
Grid::Info info = buttonSet()->getChildInfo(this);
|
||||
|
@ -112,8 +112,8 @@ ColorBar::ColorBar(int align)
|
||||
setFgColor(get_config_color("ColorBar", "FG", getFgColor()));
|
||||
|
||||
// Change color-bar background color (not ColorBar::setBgColor)
|
||||
Widget::setBgColor(((SkinTheme*)getTheme())->getColor(ThemeColor::TabSelectedFace));
|
||||
m_paletteView.setBgColor(((SkinTheme*)getTheme())->getColor(ThemeColor::TabSelectedFace));
|
||||
Widget::setBgColor(((SkinTheme*)getTheme())->colors.tabActiveFace());
|
||||
m_paletteView.setBgColor(((SkinTheme*)getTheme())->colors.tabActiveFace());
|
||||
|
||||
// Change labels foreground color
|
||||
setup_mini_font(m_paletteButton.mainButton());
|
||||
|
@ -168,7 +168,7 @@ void ColorButton::onPaint(PaintEvent& ev)
|
||||
|
||||
gfx::Color bg = getBgColor();
|
||||
if (gfx::is_transparent(bg))
|
||||
bg = theme->getColor(ThemeColor::Face);
|
||||
bg = theme->colors.face();
|
||||
g->fillRect(bg, rc);
|
||||
|
||||
app::Color color;
|
||||
|
@ -45,7 +45,8 @@ using namespace doc;
|
||||
|
||||
class ColorSelector::WarningIcon : public StyledButton {
|
||||
public:
|
||||
WarningIcon() : StyledButton("warning_box") {
|
||||
WarningIcon()
|
||||
: StyledButton(skin::SkinTheme::instance()->styles.warningBox()) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -734,7 +734,7 @@ ContextBar::ContextBar()
|
||||
border_width.b = 2*guiscale();
|
||||
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->getColor(ThemeColor::Workspace));
|
||||
setBgColor(theme->colors.workspace());
|
||||
|
||||
addChild(m_selectionOptionsBox = new HBox());
|
||||
m_selectionOptionsBox->addChild(m_dropPixels = new DropPixelsField());
|
||||
|
@ -11,14 +11,20 @@
|
||||
|
||||
#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"
|
||||
#include "ui/message.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/textbox.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
using namespace app::skin;
|
||||
|
||||
class DevConsoleView::CommmandEntry : public Entry {
|
||||
public:
|
||||
@ -59,16 +65,20 @@ DevConsoleView::DevConsoleView()
|
||||
, m_label(">")
|
||||
, m_entry(new CommmandEntry)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
|
||||
addChild(&m_view);
|
||||
addChild(&m_bottomBox);
|
||||
|
||||
m_bottomBox.addChild(&m_label);
|
||||
m_bottomBox.addChild(m_entry);
|
||||
|
||||
m_view.setProperty(SkinStylePropertyPtr(
|
||||
new SkinStyleProperty(theme->styles.workspaceView())));
|
||||
|
||||
m_view.attachToView(&m_textBox);
|
||||
m_view.setExpansive(true);
|
||||
m_entry->setExpansive(true);
|
||||
|
||||
m_entry->ExecuteCommand.connect(&DevConsoleView::onExecuteCommand, this);
|
||||
}
|
||||
|
||||
@ -83,6 +93,11 @@ std::string DevConsoleView::getTabText()
|
||||
return "Console";
|
||||
}
|
||||
|
||||
TabIcon DevConsoleView::getTabIcon()
|
||||
{
|
||||
return TabIcon::NONE;
|
||||
}
|
||||
|
||||
WorkspaceView* DevConsoleView::cloneWorkspaceView()
|
||||
{
|
||||
return new DevConsoleView();
|
||||
@ -97,6 +112,21 @@ void DevConsoleView::onClonedFrom(WorkspaceView* from)
|
||||
{
|
||||
}
|
||||
|
||||
bool DevConsoleView::onCloseView(Workspace* workspace)
|
||||
{
|
||||
workspace->removeView(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DevConsoleView::onTabPopup(Workspace* workspace)
|
||||
{
|
||||
Menu* menu = AppMenus::instance()->getTabPopupMenu();
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
menu->showPopup(ui::get_mouse_position());
|
||||
}
|
||||
|
||||
bool DevConsoleView::onProcessMessage(Message* msg)
|
||||
{
|
||||
return Box::onProcessMessage(msg);
|
||||
|
@ -26,12 +26,15 @@ namespace app {
|
||||
|
||||
// TabView implementation
|
||||
std::string getTabText() override;
|
||||
TabIcon getTabIcon() override;
|
||||
|
||||
// WorkspaceView implementation
|
||||
ui::Widget* getContentWidget() override { return this; }
|
||||
WorkspaceView* cloneWorkspaceView() override;
|
||||
void onWorkspaceViewSelected() override;
|
||||
void onClonedFrom(WorkspaceView* from) override;
|
||||
bool onCloseView(Workspace* workspace) override;
|
||||
void onTabPopup(Workspace* workspace) override;
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
|
@ -12,6 +12,9 @@
|
||||
#include "app/ui/document_view.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/app_menus.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/document_access.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
@ -20,12 +23,16 @@
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/preview_editor.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/path.h"
|
||||
#include "doc/document_event.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/accelerator.h"
|
||||
#include "ui/alert.h"
|
||||
#include "ui/menu.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/view.h"
|
||||
@ -191,13 +198,12 @@ void DocumentView::getDocumentLocation(DocumentLocation* location) const
|
||||
|
||||
std::string DocumentView::getTabText()
|
||||
{
|
||||
std::string str = m_document->name();
|
||||
return m_document->name();
|
||||
}
|
||||
|
||||
// Add an asterisk if the document is modified.
|
||||
if (m_document->isModified())
|
||||
str += "*";
|
||||
|
||||
return str;
|
||||
TabIcon DocumentView::getTabIcon()
|
||||
{
|
||||
return TabIcon::NONE;
|
||||
}
|
||||
|
||||
WorkspaceView* DocumentView::cloneWorkspaceView()
|
||||
@ -223,6 +229,81 @@ void DocumentView::onClonedFrom(WorkspaceView* from)
|
||||
->setViewScroll(View::getView(srcEditor)->getViewScroll());
|
||||
}
|
||||
|
||||
bool DocumentView::onCloseView(Workspace* workspace)
|
||||
{
|
||||
UIContext* ctx = UIContext::instance();
|
||||
bool save_it;
|
||||
bool try_again = true;
|
||||
|
||||
while (try_again) {
|
||||
// This flag indicates if we have to sabe the sprite before to destroy it
|
||||
save_it = false;
|
||||
{
|
||||
// see if the sprite has changes
|
||||
while (m_document->isModified()) {
|
||||
// ask what want to do the user with the changes in the sprite
|
||||
int ret = Alert::show("Warning<<Saving changes in:<<%s||&Save||Do&n't Save||&Cancel",
|
||||
m_document->name().c_str());
|
||||
|
||||
if (ret == 1) {
|
||||
// "save": save the changes
|
||||
save_it = true;
|
||||
break;
|
||||
}
|
||||
else if (ret != 2) {
|
||||
// "cancel" or "ESC" */
|
||||
return false; // we back doing nothing
|
||||
}
|
||||
else {
|
||||
// "discard"
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Does we need to save the sprite?
|
||||
if (save_it) {
|
||||
ctx->setActiveView(this);
|
||||
ctx->updateFlags();
|
||||
|
||||
Command* save_command =
|
||||
CommandsModule::instance()->getCommandByName(CommandId::SaveFile);
|
||||
ctx->executeCommand(save_command);
|
||||
|
||||
try_again = true;
|
||||
}
|
||||
else
|
||||
try_again = false;
|
||||
}
|
||||
|
||||
// Destroy the sprite (locking it as writer)
|
||||
DocumentDestroyer destroyer(
|
||||
static_cast<app::Context*>(m_document->context()), m_document);
|
||||
|
||||
StatusBar::instance()
|
||||
->setStatusText(0, "Sprite '%s' closed.",
|
||||
m_document->name().c_str());
|
||||
|
||||
destroyer.destroyDocument();
|
||||
|
||||
// At this point the view is already destroyed
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DocumentView::onTabPopup(Workspace* workspace)
|
||||
{
|
||||
Menu* menu = AppMenus::instance()->getDocumentTabPopupMenu();
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
UIContext* ctx = UIContext::instance();
|
||||
ctx->setActiveView(this);
|
||||
ctx->updateFlags();
|
||||
|
||||
menu->showPopup(ui::get_mouse_position());
|
||||
}
|
||||
|
||||
bool DocumentView::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
|
@ -42,12 +42,15 @@ namespace app {
|
||||
|
||||
// TabView implementation
|
||||
std::string getTabText() override;
|
||||
TabIcon getTabIcon() override;
|
||||
|
||||
// WorkspaceView implementation
|
||||
ui::Widget* getContentWidget() override { return this; }
|
||||
WorkspaceView* cloneWorkspaceView() override;
|
||||
void onWorkspaceViewSelected() override;
|
||||
void onClonedFrom(WorkspaceView* from) override;
|
||||
bool onCloseView(Workspace* workspace) override;
|
||||
void onTabPopup(Workspace* workspace) override;
|
||||
|
||||
// DocumentObserver implementation
|
||||
void onGeneralUpdate(doc::DocumentEvent& ev) override;
|
||||
|
@ -508,7 +508,7 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
|
||||
// sprite).
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
if (m_flags & kShowOutside) {
|
||||
g->fillRegion(theme->getColor(ThemeColor::EditorFace), outside);
|
||||
g->fillRegion(theme->colors.editorFace(), outside);
|
||||
}
|
||||
|
||||
// Grids
|
||||
@ -556,9 +556,9 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
|
||||
if (m_flags & kShowOutside) {
|
||||
// Draw the borders that enclose the sprite.
|
||||
enclosingRect.enlarge(1);
|
||||
g->drawRect(theme->getColor(ThemeColor::EditorSpriteBorder), enclosingRect);
|
||||
g->drawRect(theme->colors.editorSpriteBorder(), enclosingRect);
|
||||
g->drawHLine(
|
||||
theme->getColor(ThemeColor::EditorSpriteBottomBorder),
|
||||
theme->colors.editorSpriteBottomBorder(),
|
||||
enclosingRect.x, enclosingRect.y+enclosingRect.h, enclosingRect.w);
|
||||
}
|
||||
|
||||
@ -1310,7 +1310,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
// Editor without sprite
|
||||
if (!m_sprite) {
|
||||
g->fillRect(theme->getColor(ThemeColor::EditorFace), rc);
|
||||
g->fillRect(theme->colors.editorFace(), rc);
|
||||
}
|
||||
// Editor with sprite
|
||||
else {
|
||||
@ -1338,7 +1338,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
|
||||
catch (const LockedDocumentException&) {
|
||||
// The sprite is locked to be read, so we can draw an opaque
|
||||
// background only.
|
||||
g->fillRect(theme->getColor(ThemeColor::EditorFace), rc);
|
||||
g->fillRect(theme->colors.editorFace(), rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "ui/system.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
@ -343,14 +345,14 @@ bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg)
|
||||
if (KeyboardShortcuts::instance()
|
||||
->getCommandFromKeyMessage(msg, &command, ¶ms)) {
|
||||
// We accept zoom commands.
|
||||
if (strcmp(command->short_name(), CommandId::Zoom) == 0) {
|
||||
if (std::strcmp(command->short_name(), CommandId::Zoom) == 0) {
|
||||
UIContext::instance()->executeCommand(command, params);
|
||||
return true;
|
||||
}
|
||||
// Intercept the "Cut" or "Copy" command to handle them locally
|
||||
// with the current m_pixelsMovement data.
|
||||
else if (strcmp(command->short_name(), CommandId::Cut) == 0 ||
|
||||
strcmp(command->short_name(), CommandId::Copy) == 0) {
|
||||
else if (std::strcmp(command->short_name(), CommandId::Cut) == 0 ||
|
||||
std::strcmp(command->short_name(), CommandId::Copy) == 0) {
|
||||
// Copy the floating image to the clipboard.
|
||||
{
|
||||
Document* document = editor->document();
|
||||
@ -362,7 +364,7 @@ bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg)
|
||||
}
|
||||
|
||||
// In case of "Cut" command.
|
||||
if (strcmp(command->short_name(), CommandId::Cut) == 0) {
|
||||
if (std::strcmp(command->short_name(), CommandId::Cut) == 0) {
|
||||
// Discard the dragged image.
|
||||
m_pixelsMovement->discardImage();
|
||||
m_discarded = true;
|
||||
@ -376,7 +378,7 @@ bool MovingPixelsState::onKeyDown(Editor* editor, KeyMessage* msg)
|
||||
}
|
||||
// Flip Horizontally/Vertically commands are handled manually to
|
||||
// avoid dropping the floating region of pixels.
|
||||
else if (strcmp(command->short_name(), CommandId::Flip) == 0) {
|
||||
else if (std::strcmp(command->short_name(), CommandId::Flip) == 0) {
|
||||
if (FlipCommand* flipCommand = dynamic_cast<FlipCommand*>(command)) {
|
||||
flipCommand->loadParams(params);
|
||||
m_pixelsMovement->flipImage(flipCommand->getFlipType());
|
||||
@ -443,8 +445,8 @@ void MovingPixelsState::onBeforeCommandExecution(Command* command)
|
||||
if (moveMaskCmd->getTarget() == MoveMaskCommand::Content)
|
||||
return;
|
||||
}
|
||||
else if ((strcmp(command->short_name(), CommandId::Zoom) == 0) ||
|
||||
(strcmp(command->short_name(), CommandId::Scroll) == 0)) {
|
||||
else if ((std::strcmp(command->short_name(), CommandId::Zoom) == 0) ||
|
||||
(std::strcmp(command->short_name(), CommandId::Scroll) == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ void FileList::onPaint(ui::PaintEvent& ev)
|
||||
she::Surface* thumbnail = NULL;
|
||||
int thumbnail_y = 0;
|
||||
|
||||
g->fillRect(theme->getColor(ThemeColor::Background), bounds);
|
||||
g->fillRect(theme->colors.background(), bounds);
|
||||
|
||||
// rows
|
||||
for (FileItemList::iterator
|
||||
@ -321,18 +321,18 @@ void FileList::onPaint(ui::PaintEvent& ev)
|
||||
gfx::Size itemSize = getFileItemSize(fi);
|
||||
|
||||
if (fi == m_selected) {
|
||||
fgcolor = theme->getColor(ThemeColor::FileListSelectedRowText);
|
||||
bgcolor = theme->getColor(ThemeColor::FileListSelectedRowFace);
|
||||
fgcolor = theme->colors.filelistSelectedRowText();
|
||||
bgcolor = theme->colors.filelistSelectedRowFace();
|
||||
}
|
||||
else {
|
||||
bgcolor = evenRow ? theme->getColor(ThemeColor::FileListEvenRowFace):
|
||||
theme->getColor(ThemeColor::FileListOddRowFace);
|
||||
bgcolor = evenRow ? theme->colors.filelistEvenRowFace():
|
||||
theme->colors.filelistOddRowFace();
|
||||
|
||||
if (fi->isFolder() && !fi->isBrowsable())
|
||||
fgcolor = theme->getColor(ThemeColor::FileListDisabledRowText);
|
||||
fgcolor = theme->colors.filelistDisabledRowText();
|
||||
else
|
||||
fgcolor = evenRow ? theme->getColor(ThemeColor::FileListEvenRowText):
|
||||
theme->getColor(ThemeColor::FileListOddRowText);
|
||||
fgcolor = evenRow ? theme->colors.filelistEvenRowText():
|
||||
theme->colors.filelistOddRowText();
|
||||
}
|
||||
|
||||
x = bounds.x+2*guiscale();
|
||||
|
148
src/app/ui/home_view.cpp
Normal file
148
src/app/ui/home_view.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/home_view.h"
|
||||
|
||||
#include "app/app_menus.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/ui/news_listbox.h"
|
||||
#include "app/ui/recent_listbox.h"
|
||||
#include "app/ui/skin/skin_style_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/exception.h"
|
||||
#include "ui/label.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/textbox.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
using namespace app::skin;
|
||||
|
||||
HomeView::HomeView()
|
||||
: m_files(new RecentFilesListBox)
|
||||
, m_folders(new RecentFoldersListBox)
|
||||
, m_news(new NewsListBox)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->colors.workspace());
|
||||
|
||||
child_spacing = 8 * guiscale();
|
||||
|
||||
newFile()->Click.connect(Bind(&HomeView::onNewFile, this));
|
||||
openFile()->Click.connect(Bind(&HomeView::onOpenFile, this));
|
||||
|
||||
filesView()->attachToView(m_files);
|
||||
foldersView()->attachToView(m_folders);
|
||||
newsView()->attachToView(m_news);
|
||||
|
||||
checkUpdate()->setVisible(false);
|
||||
}
|
||||
|
||||
HomeView::~HomeView()
|
||||
{
|
||||
}
|
||||
|
||||
std::string HomeView::getTabText()
|
||||
{
|
||||
return "Home";
|
||||
}
|
||||
|
||||
TabIcon HomeView::getTabIcon()
|
||||
{
|
||||
return TabIcon::HOME;
|
||||
}
|
||||
|
||||
WorkspaceView* HomeView::cloneWorkspaceView()
|
||||
{
|
||||
return NULL; // This view cannot be cloned
|
||||
}
|
||||
|
||||
void HomeView::onClonedFrom(WorkspaceView* from)
|
||||
{
|
||||
ASSERT(false); // Never called
|
||||
}
|
||||
|
||||
bool HomeView::onCloseView(Workspace* workspace)
|
||||
{
|
||||
workspace->removeView(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HomeView::onTabPopup(Workspace* workspace)
|
||||
{
|
||||
Menu* menu = AppMenus::instance()->getTabPopupMenu();
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
menu->showPopup(ui::get_mouse_position());
|
||||
}
|
||||
|
||||
void HomeView::onWorkspaceViewSelected()
|
||||
{
|
||||
}
|
||||
|
||||
void HomeView::onNewFile()
|
||||
{
|
||||
Command* command = CommandsModule::instance()->getCommandByName(CommandId::NewFile);
|
||||
Params params;
|
||||
UIContext::instance()->executeCommand(command, ¶ms);
|
||||
}
|
||||
|
||||
void HomeView::onOpenFile()
|
||||
{
|
||||
Command* command = CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
|
||||
Params params;
|
||||
UIContext::instance()->executeCommand(command, ¶ms);
|
||||
}
|
||||
|
||||
void HomeView::onCheckingUpdates()
|
||||
{
|
||||
checkUpdate()->setText("Checking Updates...");
|
||||
checkUpdate()->setVisible(true);
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
void HomeView::onUpToDate()
|
||||
{
|
||||
checkUpdate()->setText(PACKAGE " is up to date");
|
||||
checkUpdate()->setVisible(true);
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
void HomeView::onNewUpdate(const std::string& url, const std::string& version)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
|
||||
checkUpdate()->setText("New " PACKAGE " v" + version + " available!");
|
||||
checkUpdate()->setUrl(url);
|
||||
checkUpdate()->setProperty(
|
||||
SkinStylePropertyPtr(new SkinStyleProperty(theme->styles.workspaceUpdateLink())));
|
||||
|
||||
// TODO this should be in a skin.xml's <style>
|
||||
gfx::Size iconSize = theme->styles.workspaceUpdateLink()->preferredSize(
|
||||
nullptr, Style::State());
|
||||
checkUpdate()->setBorder(gfx::Border(6*guiscale())+gfx::Border(
|
||||
0, 0, iconSize.w, 0));
|
||||
|
||||
checkUpdate()->setVisible(true);
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
} // namespace app
|
71
src/app/ui/home_view.h
Normal file
71
src/app/ui/home_view.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_HOME_VIEW_H_INCLUDED
|
||||
#define APP_UI_HOME_VIEW_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/check_update_delegate.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "ui/box.h"
|
||||
|
||||
#include "generated_home_view.h"
|
||||
|
||||
namespace ui {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
class NewsListBox;
|
||||
class RecentFilesListBox;
|
||||
class RecentFoldersListBox;
|
||||
|
||||
class HomeView : public app::gen::HomeView
|
||||
, public TabView
|
||||
, public WorkspaceView
|
||||
#ifdef ENABLE_UPDATER
|
||||
, public CheckUpdateDelegate
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
HomeView();
|
||||
~HomeView();
|
||||
|
||||
// TabView implementation
|
||||
std::string getTabText() override;
|
||||
TabIcon getTabIcon() override;
|
||||
|
||||
// WorkspaceView implementation
|
||||
ui::Widget* getContentWidget() override { return this; }
|
||||
WorkspaceView* cloneWorkspaceView() override;
|
||||
void onClonedFrom(WorkspaceView* from) override;
|
||||
bool onCloseView(Workspace* workspace) override;
|
||||
void onTabPopup(Workspace* workspace) override;
|
||||
void onWorkspaceViewSelected() override;
|
||||
|
||||
protected:
|
||||
#ifdef ENABLE_UPDATER
|
||||
// CheckUpdateDelegate impl
|
||||
void onCheckingUpdates() override;
|
||||
void onUpToDate() override;
|
||||
void onNewUpdate(const std::string& url, const std::string& version) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void onNewFile();
|
||||
void onOpenFile();
|
||||
|
||||
RecentFilesListBox* m_files;
|
||||
RecentFoldersListBox* m_folders;
|
||||
NewsListBox* m_news;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -21,15 +21,16 @@
|
||||
#include "app/settings/settings.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "app/ui/devconsole_view.h"
|
||||
#include "app/ui/document_view.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/editor/editor_view.h"
|
||||
#include "app/ui/home_view.h"
|
||||
#include "app/ui/main_menu_bar.h"
|
||||
#include "app/ui/notifications.h"
|
||||
#include "app/ui/preview_editor.h"
|
||||
#include "app/ui/skin/skin_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/start_view.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/timeline.h"
|
||||
@ -46,42 +47,24 @@ namespace app {
|
||||
using namespace ui;
|
||||
|
||||
MainWindow::MainWindow()
|
||||
: Window(DesktopWindow)
|
||||
, m_lastSplitterPos(0.0)
|
||||
, m_lastTimelineSplitterPos(75.0)
|
||||
, m_mode(NormalMode)
|
||||
, m_startView(NULL)
|
||||
: m_mode(NormalMode)
|
||||
, m_homeView(nullptr)
|
||||
, m_devConsoleView(nullptr)
|
||||
{
|
||||
setId("main_window");
|
||||
|
||||
// Load all menus by first time.
|
||||
AppMenus::instance()->reload();
|
||||
|
||||
Widget* mainBox = app::load_widget<Widget>("main_window.xml", "main_box");
|
||||
addChild(mainBox);
|
||||
|
||||
Widget* box_menubar = findChild("menubar");
|
||||
Widget* box_contextbar = findChild("contextbar");
|
||||
Widget* box_colorbar = findChild("colorbar");
|
||||
Widget* box_toolbar = findChild("toolbar");
|
||||
Widget* box_statusbar = findChild("statusbar");
|
||||
Widget* box_tabsbar = findChild("tabsbar");
|
||||
Widget* box_workspace = findChild("workspace");
|
||||
Widget* box_timeline = findChild("timeline");
|
||||
|
||||
m_menuBar = new MainMenuBar();
|
||||
m_notifications = new Notifications();
|
||||
m_contextBar = new ContextBar();
|
||||
m_statusBar = new StatusBar();
|
||||
m_colorBar = new ColorBar(box_colorbar->getAlign());
|
||||
m_colorBar = new ColorBar(colorBarPlaceholder()->getAlign());
|
||||
m_toolBar = new ToolBar();
|
||||
m_tabsBar = new Tabs(this);
|
||||
m_workspace = new Workspace();
|
||||
m_workspace->ActiveViewChanged.connect(&MainWindow::onActiveViewChange, this);
|
||||
m_previewEditor = new PreviewEditorWindow();
|
||||
m_timeline = new Timeline();
|
||||
m_colorBarSplitter = findChildT<Splitter>("colorbarsplitter");
|
||||
m_timelineSplitter = findChildT<Splitter>("timelinesplitter");
|
||||
|
||||
// configure all widgets to expansives
|
||||
m_menuBar->setExpansive(true);
|
||||
@ -99,20 +82,19 @@ MainWindow::MainWindow()
|
||||
m_menuBar->setMenu(AppMenus::instance()->getRootMenu());
|
||||
|
||||
// Add the widgets in the boxes
|
||||
if (box_menubar) {
|
||||
box_menubar->addChild(m_menuBar);
|
||||
box_menubar->addChild(m_notifications);
|
||||
}
|
||||
if (box_contextbar) box_contextbar->addChild(m_contextBar);
|
||||
if (box_colorbar) box_colorbar->addChild(m_colorBar);
|
||||
if (box_toolbar) box_toolbar->addChild(m_toolBar);
|
||||
if (box_statusbar) box_statusbar->addChild(m_statusBar);
|
||||
if (box_tabsbar) box_tabsbar->addChild(m_tabsBar);
|
||||
if (box_workspace) box_workspace->addChild(m_workspace);
|
||||
if (box_timeline) box_timeline->addChild(m_timeline);
|
||||
menuBarPlaceholder()->addChild(m_menuBar);
|
||||
menuBarPlaceholder()->addChild(m_notifications);
|
||||
contextBarPlaceholder()->addChild(m_contextBar);
|
||||
colorBarPlaceholder()->addChild(m_colorBar);
|
||||
toolBarPlaceholder()->addChild(m_toolBar);
|
||||
statusBarPlaceholder()->addChild(m_statusBar);
|
||||
tabsPlaceholder()->addChild(m_tabsBar);
|
||||
workspacePlaceholder()->addChild(m_workspace);
|
||||
timelinePlaceholder()->addChild(m_timeline);
|
||||
|
||||
// Default layout of widgets
|
||||
m_colorBarSplitter->setPosition(m_colorBar->getPreferredSize().w);
|
||||
// Default splitter positions
|
||||
colorBarSplitter()->setPosition(m_colorBar->getPreferredSize().w);
|
||||
timelineSplitter()->setPosition(75);
|
||||
|
||||
// Prepare the window
|
||||
remapWindow();
|
||||
@ -122,9 +104,15 @@ MainWindow::MainWindow()
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
if (m_startView) {
|
||||
m_workspace->removeView(m_startView);
|
||||
delete m_startView;
|
||||
if (m_devConsoleView) {
|
||||
if (m_devConsoleView->getParent())
|
||||
m_workspace->removeView(m_devConsoleView);
|
||||
delete m_devConsoleView;
|
||||
}
|
||||
if (m_homeView) {
|
||||
if (m_homeView->getParent())
|
||||
m_workspace->removeView(m_homeView);
|
||||
delete m_homeView;
|
||||
}
|
||||
delete m_contextBar;
|
||||
delete m_previewEditor;
|
||||
@ -139,6 +127,25 @@ MainWindow::~MainWindow()
|
||||
m_menuBar->setMenu(NULL);
|
||||
}
|
||||
|
||||
DocumentView* MainWindow::getDocView()
|
||||
{
|
||||
return dynamic_cast<DocumentView*>(m_workspace->activeView());
|
||||
}
|
||||
|
||||
HomeView* MainWindow::getHomeView()
|
||||
{
|
||||
if (!m_homeView)
|
||||
m_homeView = new HomeView;
|
||||
return m_homeView;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
CheckUpdateDelegate* MainWindow::getCheckUpdateDelegate()
|
||||
{
|
||||
return getHomeView();
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::reloadMenus()
|
||||
{
|
||||
m_menuBar->reload();
|
||||
@ -154,56 +161,45 @@ void MainWindow::showNotification(INotificationDelegate* del)
|
||||
m_notifications->getParent()->layout();
|
||||
}
|
||||
|
||||
void MainWindow::showHome()
|
||||
{
|
||||
if (!getHomeView()->getParent()) {
|
||||
m_workspace->addView(m_homeView);
|
||||
m_tabsBar->selectTab(m_homeView);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::showDevConsole()
|
||||
{
|
||||
if (!m_devConsoleView)
|
||||
m_devConsoleView = new DevConsoleView;
|
||||
|
||||
if (!m_devConsoleView->getParent()) {
|
||||
m_workspace->addView(m_devConsoleView);
|
||||
m_tabsBar->selectTab(m_devConsoleView);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setMode(Mode mode)
|
||||
{
|
||||
// Check if we already are in the given mode.
|
||||
if (m_mode == mode)
|
||||
return;
|
||||
|
||||
if (mode == NormalMode) {
|
||||
if (m_colorBarSplitter->getPosition() == 0.0)
|
||||
m_colorBarSplitter->setPosition(m_lastSplitterPos);
|
||||
}
|
||||
// If current mode is "normal", we save the splitter position of the
|
||||
// color bar in "m_lastSplitterPos" before we hide it.
|
||||
else if (m_mode == NormalMode) {
|
||||
m_lastSplitterPos = m_colorBarSplitter->getPosition();
|
||||
m_colorBarSplitter->setPosition(0.0);
|
||||
}
|
||||
|
||||
m_menuBar->setVisible(mode == NormalMode);
|
||||
m_tabsBar->setVisible(mode == NormalMode);
|
||||
m_toolBar->setVisible(mode == NormalMode);
|
||||
m_statusBar->setVisible(mode == NormalMode);
|
||||
m_contextBar->setVisible(
|
||||
mode == NormalMode ||
|
||||
mode == ContextBarAndTimelineMode);
|
||||
setTimelineVisibility(
|
||||
mode == NormalMode ||
|
||||
mode == ContextBarAndTimelineMode);
|
||||
|
||||
m_mode = mode;
|
||||
layout();
|
||||
configureWorkspaceLayout();
|
||||
}
|
||||
|
||||
bool MainWindow::getTimelineVisibility() const
|
||||
{
|
||||
return m_timelineSplitter->getPosition() < 100.0;
|
||||
return App::instance()->preferences().general.visibleTimeline();
|
||||
}
|
||||
|
||||
void MainWindow::setTimelineVisibility(bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
if (m_timelineSplitter->getPosition() >= 100.0)
|
||||
m_timelineSplitter->setPosition(m_lastTimelineSplitterPos);
|
||||
}
|
||||
else {
|
||||
if (m_timelineSplitter->getPosition() < 100.0) {
|
||||
m_lastTimelineSplitterPos = m_timelineSplitter->getPosition();
|
||||
m_timelineSplitter->setPosition(100.0);
|
||||
}
|
||||
}
|
||||
layout();
|
||||
App::instance()->preferences().general.visibleTimeline(visible);
|
||||
|
||||
configureWorkspaceLayout();
|
||||
}
|
||||
|
||||
void MainWindow::popTimeline()
|
||||
@ -219,13 +215,8 @@ void MainWindow::popTimeline()
|
||||
|
||||
bool MainWindow::onProcessMessage(ui::Message* msg)
|
||||
{
|
||||
#if 0 // TODO Enable start view
|
||||
if (msg->type() == kOpenMessage) {
|
||||
m_startView = new StartView;
|
||||
m_workspace->addView(m_startView);
|
||||
m_tabsBar->selectTab(m_startView);
|
||||
}
|
||||
#endif
|
||||
if (msg->type() == kOpenMessage)
|
||||
showHome();
|
||||
|
||||
return Window::onProcessMessage(msg);
|
||||
}
|
||||
@ -233,11 +224,6 @@ bool MainWindow::onProcessMessage(ui::Message* msg)
|
||||
void MainWindow::onSaveLayout(SaveLayoutEvent& ev)
|
||||
{
|
||||
Window::onSaveLayout(ev);
|
||||
|
||||
// Restore splitter position if we are in advanced mode, so we save
|
||||
// the original splitter position in the layout.
|
||||
if (m_colorBarSplitter->getPosition() == 0.0)
|
||||
m_colorBarSplitter->setPosition(m_lastSplitterPos);
|
||||
}
|
||||
|
||||
// When the active view is changed from methods like
|
||||
@ -245,58 +231,41 @@ void MainWindow::onSaveLayout(SaveLayoutEvent& ev)
|
||||
// inform to the UIContext that the current view has changed.
|
||||
void MainWindow::onActiveViewChange()
|
||||
{
|
||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(m_workspace->activeView())) {
|
||||
if (DocumentView* docView = getDocView())
|
||||
UIContext::instance()->setActiveView(docView);
|
||||
else
|
||||
UIContext::instance()->setActiveView(nullptr);
|
||||
|
||||
m_contextBar->updateFromTool(UIContext::instance()
|
||||
->settings()->getCurrentTool());
|
||||
|
||||
if (m_mode != EditorOnlyMode)
|
||||
m_contextBar->setVisible(true);
|
||||
}
|
||||
else {
|
||||
UIContext::instance()->setActiveView(NULL);
|
||||
|
||||
if (m_mode != EditorOnlyMode)
|
||||
m_contextBar->setVisible(false);
|
||||
}
|
||||
layout();
|
||||
configureWorkspaceLayout();
|
||||
}
|
||||
|
||||
void MainWindow::clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons)
|
||||
void MainWindow::onSelectTab(Tabs* tabs, TabView* tabView)
|
||||
{
|
||||
if (!tabView)
|
||||
return;
|
||||
|
||||
WorkspaceView* workspaceView = dynamic_cast<WorkspaceView*>(tabView);
|
||||
if (m_workspace->activeView() != workspaceView)
|
||||
m_workspace->setActiveView(workspaceView);
|
||||
|
||||
DocumentView* docView = dynamic_cast<DocumentView*>(workspaceView);
|
||||
if (!docView)
|
||||
return;
|
||||
|
||||
UIContext* context = UIContext::instance();
|
||||
context->setActiveView(docView);
|
||||
context->updateFlags();
|
||||
|
||||
// Right-button: popup-menu
|
||||
if (buttons & kButtonRight) {
|
||||
Menu* popup_menu = AppMenus::instance()->getDocumentTabPopupMenu();
|
||||
if (popup_menu != NULL) {
|
||||
popup_menu->showPopup(ui::get_mouse_position());
|
||||
}
|
||||
}
|
||||
// Middle-button: close the sprite
|
||||
else if (buttons & kButtonMiddle) {
|
||||
Command* close_file_cmd =
|
||||
CommandsModule::instance()->getCommandByName(CommandId::CloseFile);
|
||||
|
||||
context->executeCommand(close_file_cmd, NULL);
|
||||
}
|
||||
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||
if (m_workspace->activeView() != view)
|
||||
m_workspace->setActiveView(view);
|
||||
}
|
||||
|
||||
void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
|
||||
void MainWindow::onCloseTab(Tabs* tabs, TabView* tabView)
|
||||
{
|
||||
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||
ASSERT(view);
|
||||
if (view)
|
||||
m_workspace->closeView(view);
|
||||
}
|
||||
|
||||
void MainWindow::onContextMenuTab(Tabs* tabs, TabView* tabView)
|
||||
{
|
||||
WorkspaceView* view = dynamic_cast<WorkspaceView*>(tabView);
|
||||
ASSERT(view);
|
||||
if (view)
|
||||
view->onTabPopup(m_workspace);
|
||||
}
|
||||
|
||||
void MainWindow::onMouseOverTab(Tabs* tabs, TabView* tabView)
|
||||
{
|
||||
// Note: tabView can be NULL
|
||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
||||
@ -309,4 +278,43 @@ void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::onIsModified(Tabs* tabs, TabView* tabView)
|
||||
{
|
||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(tabView)) {
|
||||
Document* document = docView->getDocument();
|
||||
return document->isModified();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::configureWorkspaceLayout()
|
||||
{
|
||||
bool normal = (m_mode == NormalMode);
|
||||
bool isDoc = (getDocView() != nullptr);
|
||||
|
||||
m_menuBar->setVisible(normal);
|
||||
m_tabsBar->setVisible(normal);
|
||||
colorBarPlaceholder()->setVisible(normal && isDoc);
|
||||
m_toolBar->setVisible(normal && isDoc);
|
||||
m_statusBar->setVisible(normal);
|
||||
m_contextBar->setVisible(
|
||||
isDoc &&
|
||||
(m_mode == NormalMode ||
|
||||
m_mode == ContextBarAndTimelineMode));
|
||||
timelinePlaceholder()->setVisible(
|
||||
isDoc &&
|
||||
(m_mode == NormalMode ||
|
||||
m_mode == ContextBarAndTimelineMode) &&
|
||||
App::instance()->preferences().general.visibleTimeline());
|
||||
|
||||
if (m_contextBar->isVisible()) {
|
||||
m_contextBar->updateFromTool(
|
||||
UIContext::instance()->settings()->getCurrentTool());
|
||||
}
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -12,25 +12,33 @@
|
||||
#include "app/ui/tabs.h"
|
||||
#include "ui/window.h"
|
||||
|
||||
#include "generated_main_window.h"
|
||||
|
||||
namespace ui {
|
||||
class Splitter;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
#ifdef ENABLE_UPDATER
|
||||
class CheckUpdateDelegate;
|
||||
#endif
|
||||
|
||||
class ColorBar;
|
||||
class ContextBar;
|
||||
class DevConsoleView;
|
||||
class DocumentView;
|
||||
class HomeView;
|
||||
class INotificationDelegate;
|
||||
class MainMenuBar;
|
||||
class PreviewEditorWindow;
|
||||
class Notifications;
|
||||
class StartView;
|
||||
class PreviewEditorWindow;
|
||||
class StatusBar;
|
||||
class Tabs;
|
||||
class Timeline;
|
||||
class Workspace;
|
||||
|
||||
class MainWindow : public ui::Window
|
||||
class MainWindow : public app::gen::MainWindow
|
||||
, public TabsDelegate {
|
||||
public:
|
||||
enum Mode {
|
||||
@ -48,10 +56,15 @@ namespace app {
|
||||
Timeline* getTimeline() { return m_timeline; }
|
||||
Workspace* getWorkspace() { return m_workspace; }
|
||||
PreviewEditorWindow* getPreviewEditor() { return m_previewEditor; }
|
||||
#ifdef ENABLE_UPDATER
|
||||
CheckUpdateDelegate* getCheckUpdateDelegate();
|
||||
#endif
|
||||
|
||||
void start();
|
||||
void reloadMenus();
|
||||
void showNotification(INotificationDelegate* del);
|
||||
void showHome();
|
||||
void showDevConsole();
|
||||
|
||||
Mode getMode() const { return m_mode; }
|
||||
void setMode(Mode mode);
|
||||
@ -61,8 +74,11 @@ namespace app {
|
||||
void popTimeline();
|
||||
|
||||
// TabsDelegate implementation.
|
||||
void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons);
|
||||
void mouseOverTab(Tabs* tabs, TabView* tabView);
|
||||
void onSelectTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onCloseTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onContextMenuTab(Tabs* tabs, TabView* tabView) override;
|
||||
void onMouseOverTab(Tabs* tabs, TabView* tabView) override;
|
||||
bool onIsModified(Tabs* tabs, TabView* tabView) override;
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
@ -70,21 +86,22 @@ namespace app {
|
||||
void onActiveViewChange();
|
||||
|
||||
private:
|
||||
DocumentView* getDocView();
|
||||
HomeView* getHomeView();
|
||||
void configureWorkspaceLayout();
|
||||
|
||||
MainMenuBar* m_menuBar;
|
||||
ContextBar* m_contextBar;
|
||||
StatusBar* m_statusBar;
|
||||
ColorBar* m_colorBar;
|
||||
ui::Splitter* m_colorBarSplitter;
|
||||
ui::Splitter* m_timelineSplitter;
|
||||
ui::Widget* m_toolBar;
|
||||
Tabs* m_tabsBar;
|
||||
double m_lastSplitterPos;
|
||||
double m_lastTimelineSplitterPos;
|
||||
Mode m_mode;
|
||||
Timeline* m_timeline;
|
||||
Workspace* m_workspace;
|
||||
PreviewEditorWindow* m_previewEditor;
|
||||
StartView* m_startView;
|
||||
HomeView* m_homeView;
|
||||
DevConsoleView* m_devConsoleView;
|
||||
Notifications* m_notifications;
|
||||
};
|
||||
|
||||
|
309
src/app/ui/news_listbox.cpp
Normal file
309
src/app/ui/news_listbox.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/news_listbox.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/res/http_loader.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/skin/style.h"
|
||||
#include "app/xml_document.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/string.h"
|
||||
#include "base/time.h"
|
||||
#include "ui/link_label.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/preferred_size_event.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
#include "tinyxml.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
using namespace app::skin;
|
||||
|
||||
namespace {
|
||||
|
||||
std::string convert_html_entity(const std::string& e)
|
||||
{
|
||||
if (e.size() >= 3 && e[0] == '#' && std::isdigit(e[1])) {
|
||||
long unicodeChar;
|
||||
if (e[2] == 'x')
|
||||
unicodeChar = std::strtol(e.c_str()+1, nullptr, 16);
|
||||
else
|
||||
unicodeChar = std::strtol(e.c_str()+1, nullptr, 10);
|
||||
|
||||
if (unicodeChar == 0x2018) return "\x60";
|
||||
if (unicodeChar == 0x2019) return "'";
|
||||
else {
|
||||
std::wstring wstr(1, (wchar_t)unicodeChar);
|
||||
return base::to_utf8(wstr);
|
||||
}
|
||||
}
|
||||
else if (e == "lt") return "<";
|
||||
else if (e == "gt") return ">";
|
||||
else if (e == "amp") return "&";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string parse_html(const std::string& str)
|
||||
{
|
||||
bool paraOpen = true;
|
||||
std::string result;
|
||||
size_t i = 0;
|
||||
while (i < str.size()) {
|
||||
// Ignore content between <...> symbols
|
||||
if (str[i] == '<') {
|
||||
size_t j = ++i;
|
||||
while (i < str.size() && str[i] != '>')
|
||||
++i;
|
||||
|
||||
if (i < str.size()) {
|
||||
ASSERT(str[i] == '>');
|
||||
|
||||
std::string tag = str.substr(j, i - j);
|
||||
if (tag == "li") {
|
||||
if (!paraOpen)
|
||||
result.push_back('\n');
|
||||
result.push_back((char)0xc2);
|
||||
result.push_back((char)0xb7); // middle dot
|
||||
result.push_back(' ');
|
||||
paraOpen = false;
|
||||
}
|
||||
else if (tag == "p" || tag == "ul") {
|
||||
if (!paraOpen)
|
||||
result.push_back('\n');
|
||||
paraOpen = true;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else if (str[i] == '&') {
|
||||
size_t j = ++i;
|
||||
while (i < str.size() && str[i] != ';')
|
||||
++i;
|
||||
|
||||
if (i < str.size()) {
|
||||
ASSERT(str[i] == ';');
|
||||
std::string entity = str.substr(j, i - j);
|
||||
result += convert_html_entity(entity);
|
||||
++i;
|
||||
}
|
||||
|
||||
paraOpen = false;
|
||||
}
|
||||
else {
|
||||
result.push_back(str[i++]);
|
||||
paraOpen = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NewsItem : public LinkLabel {
|
||||
public:
|
||||
NewsItem(const std::string& link,
|
||||
const std::string& title,
|
||||
const std::string& desc)
|
||||
: LinkLabel(link, title)
|
||||
, m_desc(desc) {
|
||||
}
|
||||
|
||||
protected:
|
||||
void onPreferredSize(PreferredSizeEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
Style* style = theme->styles.newsItem();
|
||||
Style* styleDetail = theme->styles.newsItemDetail();
|
||||
Style::State state;
|
||||
gfx::Size sz1 = style->preferredSize(getText().c_str(), state);
|
||||
gfx::Size sz2, sz2fourlines;
|
||||
|
||||
if (!m_desc.empty()) {
|
||||
View* view = View::getView(getParent());
|
||||
sz2 = styleDetail->preferredSize(m_desc.c_str(), state,
|
||||
(view ? view->getViewportBounds().w: 0));
|
||||
sz2fourlines = styleDetail->preferredSize("\n\n\n", state);
|
||||
}
|
||||
|
||||
ev.setPreferredSize(gfx::Size(0, MIN(sz1.h+sz2fourlines.h, sz1.h+sz2.h)));
|
||||
}
|
||||
|
||||
void onPaint(PaintEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
Graphics* g = ev.getGraphics();
|
||||
gfx::Rect bounds = getClientBounds();
|
||||
Style* style = theme->styles.newsItem();
|
||||
Style* styleDetail = theme->styles.newsItemDetail();
|
||||
|
||||
Style::State state;
|
||||
if (hasMouse() && !getManager()->getCapture()) state += Style::hover();
|
||||
if (isSelected()) state += Style::active();
|
||||
if (getParent()->hasCapture()) state += Style::clicked();
|
||||
|
||||
gfx::Size textSize = style->preferredSize(getText().c_str(), state);
|
||||
gfx::Rect textBounds(bounds.x, bounds.y, bounds.w, textSize.h);
|
||||
gfx::Rect detailsBounds(
|
||||
bounds.x, bounds.y+textSize.h,
|
||||
bounds.w, bounds.h-textSize.h);
|
||||
|
||||
style->paint(g, textBounds, getText().c_str(), state);
|
||||
styleDetail->paint(g, detailsBounds, m_desc.c_str(), state);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_desc;
|
||||
};
|
||||
|
||||
class ProblemsItem : public NewsItem {
|
||||
public:
|
||||
ProblemsItem() : NewsItem("", "Problems loading news. Retry.", "") {
|
||||
}
|
||||
|
||||
protected:
|
||||
void onClick() override {
|
||||
static_cast<NewsListBox*>(getParent())->reload();
|
||||
}
|
||||
};
|
||||
|
||||
NewsListBox::NewsListBox()
|
||||
: m_loader(nullptr)
|
||||
, m_timer(250, this)
|
||||
{
|
||||
m_timer.Tick.connect(&NewsListBox::onTick, this);
|
||||
|
||||
std::string cache = App::instance()->preferences().news.cacheFile();
|
||||
if (!cache.empty() && base::is_file(cache) && validCache(cache))
|
||||
parseFile(cache);
|
||||
else
|
||||
reload();
|
||||
}
|
||||
|
||||
NewsListBox::~NewsListBox()
|
||||
{
|
||||
if (m_timer.isRunning())
|
||||
m_timer.stop();
|
||||
|
||||
delete m_loader;
|
||||
m_loader = nullptr;
|
||||
}
|
||||
|
||||
void NewsListBox::reload()
|
||||
{
|
||||
if (m_loader || m_timer.isRunning())
|
||||
return;
|
||||
|
||||
while (getLastChild())
|
||||
removeChild(getLastChild());
|
||||
|
||||
View* view = View::getView(this);
|
||||
if (view)
|
||||
view->updateView();
|
||||
|
||||
m_loader = new HttpLoader(WEBSITE_NEWS_RSS);
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void NewsListBox::onTick()
|
||||
{
|
||||
if (!m_loader || !m_loader->isDone())
|
||||
return;
|
||||
|
||||
std::string fn = m_loader->filename();
|
||||
|
||||
delete m_loader;
|
||||
m_loader = nullptr;
|
||||
m_timer.stop();
|
||||
|
||||
if (fn.empty()) {
|
||||
addChild(new ProblemsItem());
|
||||
View::getView(this)->updateView();
|
||||
return;
|
||||
}
|
||||
|
||||
parseFile(fn);
|
||||
}
|
||||
|
||||
void NewsListBox::parseFile(const std::string& filename)
|
||||
{
|
||||
View* view = View::getView(this);
|
||||
|
||||
XmlDocumentRef doc;
|
||||
try {
|
||||
doc = open_xml(filename);
|
||||
}
|
||||
catch (...) {
|
||||
addChild(new ProblemsItem());
|
||||
if (view)
|
||||
view->updateView();
|
||||
return;
|
||||
}
|
||||
|
||||
TiXmlHandle handle(doc);
|
||||
TiXmlElement* itemXml = handle
|
||||
.FirstChild("rss")
|
||||
.FirstChild("channel")
|
||||
.FirstChild("item").ToElement();
|
||||
|
||||
int count = 0;
|
||||
|
||||
while (itemXml) {
|
||||
TiXmlElement* titleXml = itemXml->FirstChildElement("title");
|
||||
TiXmlElement* descXml = itemXml->FirstChildElement("description");
|
||||
TiXmlElement* linkXml = itemXml->FirstChildElement("link");
|
||||
TiXmlElement* guidXml = itemXml->FirstChildElement("guid");
|
||||
TiXmlElement* pubDateXml = itemXml->FirstChildElement("pubDate");
|
||||
|
||||
std::string link = linkXml->GetText();
|
||||
std::string title = titleXml->GetText();
|
||||
std::string desc = parse_html(descXml->GetText());
|
||||
|
||||
addChild(new NewsItem(link, title, desc));
|
||||
|
||||
itemXml = itemXml->NextSiblingElement();
|
||||
if (++count == 4)
|
||||
break;
|
||||
}
|
||||
|
||||
TiXmlElement* linkXml = handle
|
||||
.FirstChild("rss")
|
||||
.FirstChild("channel")
|
||||
.FirstChild("link").ToElement();
|
||||
if (linkXml)
|
||||
addChild(new NewsItem(linkXml->GetText(), "More...", ""));
|
||||
|
||||
if (view)
|
||||
view->updateView();
|
||||
|
||||
// Save as cached news
|
||||
App::instance()->preferences().news.cacheFile(filename);
|
||||
}
|
||||
|
||||
bool NewsListBox::validCache(const std::string& filename)
|
||||
{
|
||||
base::Time
|
||||
now = base::current_time(),
|
||||
time = base::get_modification_time(filename);
|
||||
|
||||
now.dateOnly();
|
||||
time.dateOnly();
|
||||
|
||||
return (now == time);
|
||||
}
|
||||
|
||||
} // namespace app
|
39
src/app/ui/news_listbox.h
Normal file
39
src/app/ui/news_listbox.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_NEWS_LISTBOX_H_INCLUDED
|
||||
#define APP_UI_NEWS_LISTBOX_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "ui/listbox.h"
|
||||
#include "ui/timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace app {
|
||||
|
||||
class HttpLoader;
|
||||
|
||||
class NewsListBox : public ui::ListBox {
|
||||
public:
|
||||
NewsListBox();
|
||||
~NewsListBox();
|
||||
|
||||
void reload();
|
||||
|
||||
private:
|
||||
void onTick();
|
||||
void parseFile(const std::string& filename);
|
||||
bool validCache(const std::string& filename);
|
||||
|
||||
ui::Timer m_timer;
|
||||
HttpLoader* m_loader;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -23,8 +23,6 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
static const char* kFlag = "flag";
|
||||
|
||||
class NotificationItem : public MenuItem {
|
||||
public:
|
||||
NotificationItem(INotificationDelegate* del)
|
||||
@ -44,7 +42,7 @@ private:
|
||||
|
||||
Notifications::Notifications()
|
||||
: Button("")
|
||||
, m_flagStyle(skin::get_style(kFlag))
|
||||
, m_flagStyle(skin::SkinTheme::instance()->styles.flag())
|
||||
, m_withNotifications(false)
|
||||
{
|
||||
}
|
||||
|
157
src/app/ui/recent_listbox.cpp
Normal file
157
src/app/ui/recent_listbox.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/recent_listbox.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/recent_files.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/path.h"
|
||||
#include "ui/graphics.h"
|
||||
#include "ui/listitem.h"
|
||||
#include "ui/link_label.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/preferred_size_event.h"
|
||||
#include "ui/system.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
using namespace skin;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// RecentFileItem
|
||||
|
||||
class RecentFileItem : public LinkLabel {
|
||||
public:
|
||||
RecentFileItem(const std::string& file)
|
||||
: LinkLabel(file) {
|
||||
}
|
||||
|
||||
protected:
|
||||
void onPreferredSize(PreferredSizeEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
Style* style = theme->styles.recentFile();
|
||||
Style* styleDetail = theme->styles.recentFileDetail();
|
||||
Style::State state;
|
||||
gfx::Size sz1 = style->preferredSize(name().c_str(), state);
|
||||
gfx::Size sz2 = styleDetail->preferredSize(path().c_str(), state);
|
||||
ev.setPreferredSize(gfx::Size(sz1.w+sz2.w, MAX(sz1.h, sz2.h)));
|
||||
}
|
||||
|
||||
void onPaint(PaintEvent& ev) override {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
Graphics* g = ev.getGraphics();
|
||||
gfx::Rect bounds = getClientBounds();
|
||||
Style* style = theme->styles.recentFile();
|
||||
Style* styleDetail = theme->styles.recentFileDetail();
|
||||
|
||||
Style::State state;
|
||||
if (hasMouse() && !getManager()->getCapture()) state += Style::hover();
|
||||
if (isSelected()) state += Style::active();
|
||||
if (getParent()->hasCapture()) state += Style::clicked();
|
||||
|
||||
std::string name = this->name();
|
||||
style->paint(g, bounds, name.c_str(), state);
|
||||
|
||||
gfx::Size textSize = style->preferredSize(name.c_str(), state);
|
||||
gfx::Rect detailsBounds(
|
||||
bounds.x+textSize.w, bounds.y,
|
||||
bounds.w-textSize.w, bounds.h);
|
||||
styleDetail->paint(g, detailsBounds, path().c_str(), state);
|
||||
}
|
||||
|
||||
void onClick() override {
|
||||
static_cast<RecentListBox*>(getParent())->onClick(getText());
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name() const { return base::get_file_name(getText()); }
|
||||
std::string path() const { return base::get_file_path(getText()); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// RecentListBox
|
||||
|
||||
RecentListBox::RecentListBox()
|
||||
{
|
||||
m_recentFilesConn =
|
||||
App::instance()->getRecentFiles()->Changed.connect(
|
||||
Bind(&RecentListBox::rebuildList, this));
|
||||
}
|
||||
|
||||
void RecentListBox::rebuildList()
|
||||
{
|
||||
while (getLastChild())
|
||||
removeChild(getLastChild());
|
||||
|
||||
onRebuildList();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// RecentFilesListBox
|
||||
|
||||
RecentFilesListBox::RecentFilesListBox()
|
||||
{
|
||||
onRebuildList();
|
||||
}
|
||||
|
||||
void RecentFilesListBox::onRebuildList()
|
||||
{
|
||||
RecentFiles* recent = App::instance()->getRecentFiles();
|
||||
|
||||
auto it = recent->files_begin();
|
||||
auto end = recent->files_end();
|
||||
for (; it != end; ++it)
|
||||
addChild(new RecentFileItem(it->c_str()));
|
||||
}
|
||||
|
||||
void RecentFilesListBox::onClick(const std::string& path)
|
||||
{
|
||||
Command* command = CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
|
||||
Params params;
|
||||
params.set("filename", path.c_str());
|
||||
UIContext::instance()->executeCommand(command, ¶ms);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// RecentFoldersListBox
|
||||
|
||||
RecentFoldersListBox::RecentFoldersListBox()
|
||||
{
|
||||
onRebuildList();
|
||||
}
|
||||
|
||||
void RecentFoldersListBox::onRebuildList()
|
||||
{
|
||||
RecentFiles* recent = App::instance()->getRecentFiles();
|
||||
|
||||
auto it = recent->paths_begin();
|
||||
auto end = recent->paths_end();
|
||||
for (; it != end; ++it)
|
||||
addChild(new RecentFileItem(it->c_str()));
|
||||
}
|
||||
|
||||
void RecentFoldersListBox::onClick(const std::string& path)
|
||||
{
|
||||
Command* command = CommandsModule::instance()->getCommandByName(CommandId::OpenFile);
|
||||
Params params;
|
||||
params.set("folder", path.c_str());
|
||||
UIContext::instance()->executeCommand(command, ¶ms);
|
||||
}
|
||||
|
||||
} // namespace app
|
53
src/app/ui/recent_listbox.h
Normal file
53
src/app/ui/recent_listbox.h
Normal file
@ -0,0 +1,53 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_RECENT_LISTBOX_H_INCLUDED
|
||||
#define APP_UI_RECENT_LISTBOX_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "ui/listbox.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class RecentFileItem;
|
||||
|
||||
class RecentListBox : public ui::ListBox {
|
||||
friend class RecentFileItem;
|
||||
public:
|
||||
RecentListBox();
|
||||
|
||||
protected:
|
||||
virtual void onRebuildList() = 0;
|
||||
virtual void onClick(const std::string& path) = 0;
|
||||
|
||||
private:
|
||||
void rebuildList();
|
||||
|
||||
ScopedConnection m_recentFilesConn;
|
||||
};
|
||||
|
||||
class RecentFilesListBox : public RecentListBox {
|
||||
public:
|
||||
RecentFilesListBox();
|
||||
|
||||
protected:
|
||||
void onRebuildList() override;
|
||||
void onClick(const std::string& path) override;
|
||||
};
|
||||
|
||||
class RecentFoldersListBox : public RecentListBox {
|
||||
public:
|
||||
RecentFoldersListBox();
|
||||
|
||||
protected:
|
||||
void onRebuildList() override;
|
||||
void onClick(const std::string& path) override;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -55,12 +55,12 @@ protected:
|
||||
gfx::Color bgcolor, fgcolor;
|
||||
|
||||
if (isSelected()) {
|
||||
bgcolor = theme->getColor(ThemeColor::ListItemSelectedFace);
|
||||
fgcolor = theme->getColor(ThemeColor::ListItemSelectedText);
|
||||
bgcolor = theme->colors.listitemSelectedFace();
|
||||
fgcolor = theme->colors.listitemSelectedText();
|
||||
}
|
||||
else {
|
||||
bgcolor = theme->getColor(ThemeColor::ListItemNormalFace);
|
||||
fgcolor = theme->getColor(ThemeColor::ListItemNormalText);
|
||||
bgcolor = theme->colors.listitemNormalFace();
|
||||
fgcolor = theme->colors.listitemNormalText();
|
||||
}
|
||||
|
||||
g->fillRect(bgcolor, bounds);
|
||||
|
25
src/app/ui/skin/background_repeat.h
Normal file
25
src/app/ui/skin/background_repeat.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_SKIN_BACKGROUND_REPEAT_H_INCLUDED
|
||||
#define APP_UI_SKIN_BACKGROUND_REPEAT_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
namespace app {
|
||||
namespace skin {
|
||||
|
||||
enum class BackgroundRepeat {
|
||||
REPEAT,
|
||||
REPEAT_X,
|
||||
REPEAT_Y,
|
||||
NO_REPEAT
|
||||
};
|
||||
|
||||
} // namespace skin
|
||||
} // namespace app
|
||||
|
||||
#endif // APP_UI_SKIN_BACKGROUND_REPEAT_H_INCLUDED
|
@ -9,9 +9,10 @@
|
||||
#define APP_UI_SKIN_SKIN_PART_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "base/shared_ptr.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace she {
|
||||
class Surface;
|
||||
}
|
||||
@ -26,14 +27,14 @@ namespace app {
|
||||
SkinPart();
|
||||
~SkinPart();
|
||||
|
||||
size_t size() const { return m_bitmaps.size(); }
|
||||
std::size_t size() const { return m_bitmaps.size(); }
|
||||
|
||||
void clear();
|
||||
|
||||
// It doesn't destroy the previous bitmap in the given "index".
|
||||
void setBitmap(size_t index, she::Surface* bitmap);
|
||||
void setBitmap(std::size_t index, she::Surface* bitmap);
|
||||
|
||||
she::Surface* getBitmap(size_t index) const {
|
||||
she::Surface* getBitmap(std::size_t index) const {
|
||||
return (index < m_bitmaps.size() ? m_bitmaps[index]: NULL);
|
||||
}
|
||||
|
||||
|
@ -100,14 +100,6 @@ namespace app {
|
||||
SKIN_PART_NESW(PART_TOOLBUTTON_LAST),
|
||||
SKIN_PART_NESW(PART_TOOLBUTTON_PUSHED),
|
||||
|
||||
SKIN_PART_NESW(PART_TAB_NORMAL),
|
||||
SKIN_PART_NESW(PART_TAB_SELECTED),
|
||||
SKIN_PART_NESW(PART_TAB_BOTTOM_SELECTED),
|
||||
|
||||
PART_TAB_BOTTOM_NORMAL,
|
||||
|
||||
PART_TAB_FILLER,
|
||||
|
||||
SKIN_PART_NESW(PART_EDITOR_NORMAL),
|
||||
SKIN_PART_NESW(PART_EDITOR_SELECTED),
|
||||
|
||||
|
31
src/app/ui/skin/skin_style_property.cpp
Normal file
31
src/app/ui/skin/skin_style_property.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/skin/skin_style_property.h"
|
||||
|
||||
namespace app {
|
||||
namespace skin {
|
||||
|
||||
const char* SkinStyleProperty::Name = "SkinStyleProperty";
|
||||
|
||||
SkinStyleProperty::SkinStyleProperty(Style* style)
|
||||
: Property(Name)
|
||||
, m_style(style)
|
||||
{
|
||||
}
|
||||
|
||||
Style* SkinStyleProperty::getStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
} // namespace skin
|
||||
} // namespace app
|
37
src/app/ui/skin/skin_style_property.h
Normal file
37
src/app/ui/skin/skin_style_property.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_SKIN_SKIN_STYLE_PROPERTY_H_INCLUDED
|
||||
#define APP_UI_SKIN_SKIN_STYLE_PROPERTY_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/skin/skin_property.h"
|
||||
#include "app/ui/skin/style.h"
|
||||
#include "base/shared_ptr.h"
|
||||
|
||||
namespace app {
|
||||
namespace skin {
|
||||
class Style;
|
||||
|
||||
class SkinStyleProperty : public ui::Property {
|
||||
public:
|
||||
static const char* Name;
|
||||
|
||||
SkinStyleProperty(Style* style);
|
||||
|
||||
skin::Style* getStyle() const;
|
||||
|
||||
private:
|
||||
skin::Style* m_style;
|
||||
};
|
||||
|
||||
typedef SharedPtr<SkinStyleProperty> SkinStylePropertyPtr;
|
||||
|
||||
} // namespace skin
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -17,6 +17,7 @@
|
||||
#include "app/ui/skin/button_icon_impl.h"
|
||||
#include "app/ui/skin/skin_property.h"
|
||||
#include "app/ui/skin/skin_slider_property.h"
|
||||
#include "app/ui/skin/skin_style_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/skin/style.h"
|
||||
#include "app/ui/skin/style_sheet.h"
|
||||
@ -49,13 +50,9 @@ using namespace gfx;
|
||||
using namespace ui;
|
||||
|
||||
static std::map<std::string, int> sheet_mapping;
|
||||
static std::map<std::string, ThemeColor::Type> color_mapping;
|
||||
|
||||
const char* SkinTheme::kThemeCloseButtonId = "theme_close_button";
|
||||
|
||||
const char* kWindowFaceColorId = "window_face";
|
||||
const char* kSeparatorLabelColorId = "separator_label";
|
||||
|
||||
// Controls the "X" button in a window to close it.
|
||||
class WindowCloseButton : public Button {
|
||||
public:
|
||||
@ -138,9 +135,14 @@ static const char* cursor_names[kCursorTypes] = {
|
||||
"magnifier" // kMagnifierCursor
|
||||
};
|
||||
|
||||
// static
|
||||
SkinTheme* SkinTheme::instance()
|
||||
{
|
||||
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme());
|
||||
}
|
||||
|
||||
SkinTheme::SkinTheme()
|
||||
: m_cursors(ui::kCursorTypes, NULL)
|
||||
, m_colors(ThemeColor::MaxColors)
|
||||
{
|
||||
this->name = "Skin Theme";
|
||||
m_selected_skin = get_config_string("Skin", "Selected", "default");
|
||||
@ -210,11 +212,6 @@ SkinTheme::SkinTheme()
|
||||
sheet_mapping["toolbutton_hot"] = PART_TOOLBUTTON_HOT_NW;
|
||||
sheet_mapping["toolbutton_last"] = PART_TOOLBUTTON_LAST_NW;
|
||||
sheet_mapping["toolbutton_pushed"] = PART_TOOLBUTTON_PUSHED_NW;
|
||||
sheet_mapping["tab_normal"] = PART_TAB_NORMAL_NW;
|
||||
sheet_mapping["tab_selected"] = PART_TAB_SELECTED_NW;
|
||||
sheet_mapping["tab_bottom_selected"] = PART_TAB_BOTTOM_SELECTED_NW;
|
||||
sheet_mapping["tab_bottom_normal"] = PART_TAB_BOTTOM_NORMAL;
|
||||
sheet_mapping["tab_filler"] = PART_TAB_FILLER;
|
||||
sheet_mapping["editor_normal"] = PART_EDITOR_NORMAL_NW;
|
||||
sheet_mapping["editor_selected"] = PART_EDITOR_SELECTED_NW;
|
||||
sheet_mapping["colorbar_0"] = PART_COLORBAR_0_NW;
|
||||
@ -290,62 +287,6 @@ SkinTheme::SkinTheme()
|
||||
sheet_mapping["freehand_algo_dots"] = PART_FREEHAND_ALGO_DOTS;
|
||||
sheet_mapping["freehand_algo_dots_selected"] = PART_FREEHAND_ALGO_DOTS_SELECTED;
|
||||
|
||||
color_mapping["text"] = ThemeColor::Text;
|
||||
color_mapping["disabled"] = ThemeColor::Disabled;
|
||||
color_mapping["face"] = ThemeColor::Face;
|
||||
color_mapping["hot_face"] = ThemeColor::HotFace;
|
||||
color_mapping["selected"] = ThemeColor::Selected;
|
||||
color_mapping["background"] = ThemeColor::Background;
|
||||
color_mapping["textbox_text"] = ThemeColor::TextBoxText;
|
||||
color_mapping["textbox_face"] = ThemeColor::TextBoxFace;
|
||||
color_mapping["entry_suffix"] = ThemeColor::EntrySuffix;
|
||||
color_mapping["link_text"] = ThemeColor::LinkText;
|
||||
color_mapping["button_normal_text"] = ThemeColor::ButtonNormalText;
|
||||
color_mapping["button_normal_face"] = ThemeColor::ButtonNormalFace;
|
||||
color_mapping["button_hot_text"] = ThemeColor::ButtonHotText;
|
||||
color_mapping["button_hot_face"] = ThemeColor::ButtonHotFace;
|
||||
color_mapping["button_selected_text"] = ThemeColor::ButtonSelectedText;
|
||||
color_mapping["button_selected_face"] = ThemeColor::ButtonSelectedFace;
|
||||
color_mapping["check_hot_face"] = ThemeColor::CheckHotFace;
|
||||
color_mapping["check_focus_face"] = ThemeColor::CheckFocusFace;
|
||||
color_mapping["radio_hot_face"] = ThemeColor::RadioHotFace;
|
||||
color_mapping["radio_focus_face"] = ThemeColor::RadioFocusFace;
|
||||
color_mapping["menuitem_normal_text"] = ThemeColor::MenuItemNormalText;
|
||||
color_mapping["menuitem_normal_face"] = ThemeColor::MenuItemNormalFace;
|
||||
color_mapping["menuitem_hot_text"] = ThemeColor::MenuItemHotText;
|
||||
color_mapping["menuitem_hot_face"] = ThemeColor::MenuItemHotFace;
|
||||
color_mapping["menuitem_highlight_text"] = ThemeColor::MenuItemHighlightText;
|
||||
color_mapping["menuitem_highlight_face"] = ThemeColor::MenuItemHighlightFace;
|
||||
color_mapping["editor_face"] = ThemeColor::EditorFace;
|
||||
color_mapping["editor_sprite_border"] = ThemeColor::EditorSpriteBorder;
|
||||
color_mapping["editor_sprite_bottom_border"] = ThemeColor::EditorSpriteBottomBorder;
|
||||
color_mapping["listitem_normal_text"] = ThemeColor::ListItemNormalText;
|
||||
color_mapping["listitem_normal_face"] = ThemeColor::ListItemNormalFace;
|
||||
color_mapping["listitem_selected_text"] = ThemeColor::ListItemSelectedText;
|
||||
color_mapping["listitem_selected_face"] = ThemeColor::ListItemSelectedFace;
|
||||
color_mapping["slider_empty_text"] = ThemeColor::SliderEmptyText;
|
||||
color_mapping["slider_empty_face"] = ThemeColor::SliderEmptyFace;
|
||||
color_mapping["slider_full_text"] = ThemeColor::SliderFullText;
|
||||
color_mapping["slider_full_face"] = ThemeColor::SliderFullFace;
|
||||
color_mapping["tab_normal_text"] = ThemeColor::TabNormalText;
|
||||
color_mapping["tab_normal_face"] = ThemeColor::TabNormalFace;
|
||||
color_mapping["tab_selected_text"] = ThemeColor::TabSelectedText;
|
||||
color_mapping["tab_selected_face"] = ThemeColor::TabSelectedFace;
|
||||
color_mapping["splitter_normal_face"] = ThemeColor::SplitterNormalFace;
|
||||
color_mapping["scrollbar_bg_face"] = ThemeColor::ScrollBarBgFace;
|
||||
color_mapping["scrollbar_thumb_face"] = ThemeColor::ScrollBarThumbFace;
|
||||
color_mapping["popup_window_border"] = ThemeColor::PopupWindowBorder;
|
||||
color_mapping["tooltip_text"] = ThemeColor::TooltipText;
|
||||
color_mapping["tooltip_face"] = ThemeColor::TooltipFace;
|
||||
color_mapping["filelist_even_row_text"] = ThemeColor::FileListEvenRowText;
|
||||
color_mapping["filelist_even_row_face"] = ThemeColor::FileListEvenRowFace;
|
||||
color_mapping["filelist_odd_row_text"] = ThemeColor::FileListOddRowText;
|
||||
color_mapping["filelist_odd_row_face"] = ThemeColor::FileListOddRowFace;
|
||||
color_mapping["filelist_selected_row_text"] = ThemeColor::FileListSelectedRowText;
|
||||
color_mapping["filelist_selected_row_face"] = ThemeColor::FileListSelectedRowFace;
|
||||
color_mapping["filelist_disabled_row_text"] = ThemeColor::FileListDisabledRowText;
|
||||
color_mapping["workspace"] = ThemeColor::Workspace;
|
||||
|
||||
reload_skin();
|
||||
}
|
||||
|
||||
@ -366,7 +307,6 @@ SkinTheme::~SkinTheme()
|
||||
m_part.clear();
|
||||
m_parts_by_id.clear();
|
||||
sheet_mapping.clear();
|
||||
color_mapping.clear();
|
||||
|
||||
// Destroy the minifont
|
||||
if (m_minifont)
|
||||
@ -433,6 +373,23 @@ void SkinTheme::onRegenerate()
|
||||
XmlDocumentRef doc = open_xml(rf.filename());
|
||||
TiXmlHandle handle(doc);
|
||||
|
||||
// Load dimension
|
||||
{
|
||||
TiXmlElement* xmlDim = handle
|
||||
.FirstChild("skin")
|
||||
.FirstChild("dimensions")
|
||||
.FirstChild("dim").ToElement();
|
||||
while (xmlDim) {
|
||||
std::string id = xmlDim->Attribute("id");
|
||||
uint32_t value = strtol(xmlDim->Attribute("value"), NULL, 10);
|
||||
|
||||
PRINTF("Loading dimension '%s'...\n", id.c_str());
|
||||
|
||||
m_dimensions_by_id[id] = value;
|
||||
xmlDim = xmlDim->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
// Load colors
|
||||
{
|
||||
TiXmlElement* xmlColor = handle
|
||||
@ -450,12 +407,6 @@ void SkinTheme::onRegenerate()
|
||||
PRINTF("Loading color '%s'...\n", id.c_str());
|
||||
|
||||
m_colors_by_id[id] = color;
|
||||
|
||||
std::map<std::string, ThemeColor::Type>::iterator it = color_mapping.find(id);
|
||||
if (it != color_mapping.end()) {
|
||||
m_colors[it->second] = color;
|
||||
}
|
||||
|
||||
xmlColor = xmlColor->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
@ -612,6 +563,7 @@ void SkinTheme::onRegenerate()
|
||||
int align = 0;
|
||||
const char* halign = xmlRule->Attribute("align");
|
||||
const char* valign = xmlRule->Attribute("valign");
|
||||
const char* wordwrap = xmlRule->Attribute("wordwrap");
|
||||
if (halign) {
|
||||
if (strcmp(halign, "left") == 0) align |= JI_LEFT;
|
||||
else if (strcmp(halign, "right") == 0) align |= JI_RIGHT;
|
||||
@ -622,28 +574,39 @@ void SkinTheme::onRegenerate()
|
||||
else if (strcmp(valign, "bottom") == 0) align |= JI_BOTTOM;
|
||||
else if (strcmp(valign, "middle") == 0) align |= JI_MIDDLE;
|
||||
}
|
||||
if (wordwrap && strcmp(wordwrap, "true") == 0)
|
||||
align |= JI_WORDWRAP;
|
||||
|
||||
if (ruleName == "background") {
|
||||
const char* repeat_id = xmlRule->Attribute("repeat");
|
||||
|
||||
if (color_id) (*style)[StyleSheet::backgroundColorRule()] = css::Value(color_id);
|
||||
if (part_id) (*style)[StyleSheet::backgroundPartRule()] = css::Value(part_id);
|
||||
if (repeat_id) (*style)[StyleSheet::backgroundRepeatRule()] = css::Value(repeat_id);
|
||||
}
|
||||
else if (ruleName == "icon") {
|
||||
if (align) (*style)[StyleSheet::iconAlignRule()] = css::Value(align);
|
||||
if (part_id) (*style)[StyleSheet::iconPartRule()] = css::Value(part_id);
|
||||
|
||||
const char* x = xmlRule->Attribute("x");
|
||||
const char* y = xmlRule->Attribute("y");
|
||||
|
||||
if (x) (*style)[StyleSheet::iconXRule()] = css::Value(strtol(x, NULL, 10));
|
||||
if (y) (*style)[StyleSheet::iconYRule()] = css::Value(strtol(y, NULL, 10));
|
||||
}
|
||||
else if (ruleName == "text") {
|
||||
if (color_id) (*style)[StyleSheet::textColorRule()] = css::Value(color_id);
|
||||
if (align) (*style)[StyleSheet::textAlignRule()] = css::Value(align);
|
||||
|
||||
const char* padding_left = xmlRule->Attribute("padding-left");
|
||||
const char* padding_top = xmlRule->Attribute("padding-top");
|
||||
const char* padding_right = xmlRule->Attribute("padding-right");
|
||||
const char* padding_bottom = xmlRule->Attribute("padding-bottom");
|
||||
const char* l = xmlRule->Attribute("padding-left");
|
||||
const char* t = xmlRule->Attribute("padding-top");
|
||||
const char* r = xmlRule->Attribute("padding-right");
|
||||
const char* b = xmlRule->Attribute("padding-bottom");
|
||||
|
||||
if (padding_left) (*style)[StyleSheet::paddingLeftRule()] = css::Value(strtol(padding_left, NULL, 10));
|
||||
if (padding_top) (*style)[StyleSheet::paddingTopRule()] = css::Value(strtol(padding_top, NULL, 10));
|
||||
if (padding_right) (*style)[StyleSheet::paddingRightRule()] = css::Value(strtol(padding_right, NULL, 10));
|
||||
if (padding_bottom) (*style)[StyleSheet::paddingBottomRule()] = css::Value(strtol(padding_bottom, NULL, 10));
|
||||
if (l) (*style)[StyleSheet::paddingLeftRule()] = css::Value(strtol(l, NULL, 10));
|
||||
if (t) (*style)[StyleSheet::paddingTopRule()] = css::Value(strtol(t, NULL, 10));
|
||||
if (r) (*style)[StyleSheet::paddingRightRule()] = css::Value(strtol(r, NULL, 10));
|
||||
if (b) (*style)[StyleSheet::paddingBottomRule()] = css::Value(strtol(b, NULL, 10));
|
||||
}
|
||||
|
||||
xmlRule = xmlRule->NextSiblingElement();
|
||||
@ -652,6 +615,8 @@ void SkinTheme::onRegenerate()
|
||||
xmlStyle = xmlStyle->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
SkinFile<SkinTheme>::updateInternals();
|
||||
}
|
||||
|
||||
she::Surface* SkinTheme::sliceSheet(she::Surface* sur, const gfx::Rect& bounds)
|
||||
@ -745,7 +710,6 @@ void SkinTheme::initWidget(Widget* widget)
|
||||
|
||||
case kLabelWidget:
|
||||
BORDER(1 * scale);
|
||||
static_cast<Label*>(widget)->setTextColor(getColor(ThemeColor::Text));
|
||||
break;
|
||||
|
||||
case kListBoxWidget:
|
||||
@ -855,7 +819,7 @@ void SkinTheme::initWidget(Widget* widget)
|
||||
m_part[PART_SUNKEN_NORMAL_E]->width()-1*scale,
|
||||
m_part[PART_SUNKEN_NORMAL_S]->height()-1*scale);
|
||||
widget->child_spacing = 0;
|
||||
widget->setBgColor(getColorById(kWindowFaceColorId));
|
||||
widget->setBgColor(colors.windowFace());
|
||||
break;
|
||||
|
||||
case kViewScrollbarWidget:
|
||||
@ -887,7 +851,7 @@ void SkinTheme::initWidget(Widget* widget)
|
||||
BORDER(0);
|
||||
}
|
||||
widget->child_spacing = 4 * scale; // TODO this hard-coded 4 should be configurable in skin.xml
|
||||
widget->setBgColor(getColorById(kWindowFaceColorId));
|
||||
widget->setBgColor(colors.windowFace());
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -920,7 +884,7 @@ void SkinTheme::paintDesktop(PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
|
||||
g->fillRect(getColor(ThemeColor::Disabled), g->getClipBounds());
|
||||
g->fillRect(colors.disabled(), g->getClipBounds());
|
||||
}
|
||||
|
||||
void SkinTheme::paintBox(PaintEvent& ev)
|
||||
@ -954,8 +918,8 @@ void SkinTheme::paintButton(PaintEvent& ev)
|
||||
|
||||
// Selected
|
||||
if (widget->isSelected()) {
|
||||
fg = getColor(ThemeColor::ButtonSelectedText);
|
||||
bg = getColor(ThemeColor::ButtonSelectedFace);
|
||||
fg = colors.buttonSelectedText();
|
||||
bg = colors.buttonSelectedFace();
|
||||
part_nw = (look == MiniLook ? PART_TOOLBUTTON_NORMAL_NW:
|
||||
look == LeftButtonLook ? PART_DROP_DOWN_BUTTON_LEFT_SELECTED_NW:
|
||||
look == RightButtonLook ? PART_DROP_DOWN_BUTTON_RIGHT_SELECTED_NW:
|
||||
@ -963,8 +927,8 @@ void SkinTheme::paintButton(PaintEvent& ev)
|
||||
}
|
||||
// With mouse
|
||||
else if (widget->isEnabled() && widget->hasMouseOver()) {
|
||||
fg = getColor(ThemeColor::ButtonHotText);
|
||||
bg = getColor(ThemeColor::ButtonHotFace);
|
||||
fg = colors.buttonHotText();
|
||||
bg = colors.buttonHotFace();
|
||||
part_nw = (look == MiniLook ? PART_TOOLBUTTON_HOT_NW:
|
||||
look == LeftButtonLook ? PART_DROP_DOWN_BUTTON_LEFT_HOT_NW:
|
||||
look == RightButtonLook ? PART_DROP_DOWN_BUTTON_RIGHT_HOT_NW:
|
||||
@ -972,8 +936,8 @@ void SkinTheme::paintButton(PaintEvent& ev)
|
||||
}
|
||||
// Without mouse
|
||||
else {
|
||||
fg = getColor(ThemeColor::ButtonNormalText);
|
||||
bg = getColor(ThemeColor::ButtonNormalFace);
|
||||
fg = colors.buttonNormalText();
|
||||
bg = colors.buttonNormalFace();
|
||||
|
||||
if (widget->hasFocus())
|
||||
part_nw = (look == MiniLook ? PART_TOOLBUTTON_HOT_NW:
|
||||
@ -1033,9 +997,9 @@ void SkinTheme::paintCheckBox(PaintEvent& ev)
|
||||
// Mouse
|
||||
if (widget->isEnabled()) {
|
||||
if (widget->hasMouseOver())
|
||||
g->fillRect(bg = getColor(ThemeColor::CheckHotFace), bounds);
|
||||
g->fillRect(bg = colors.checkHotFace(), bounds);
|
||||
else if (widget->hasFocus())
|
||||
g->fillRect(bg = getColor(ThemeColor::CheckFocusFace), bounds);
|
||||
g->fillRect(bg = colors.checkFocusFace(), bounds);
|
||||
}
|
||||
|
||||
// Text
|
||||
@ -1081,7 +1045,7 @@ void SkinTheme::paintEntry(PaintEvent& ev)
|
||||
if (skinPropery != NULL)
|
||||
isMiniLook = (skinPropery->getLook() == MiniLook);
|
||||
|
||||
gfx::Color bg = getColor(ThemeColor::Background);
|
||||
gfx::Color bg = colors.background();
|
||||
draw_bounds_nw(g, bounds,
|
||||
(widget->hasFocus() ?
|
||||
(isMiniLook ? PART_SUNKEN_MINI_FOCUSED_NW: PART_SUNKEN_FOCUSED_NW):
|
||||
@ -1100,21 +1064,21 @@ void SkinTheme::paintEntry(PaintEvent& ev)
|
||||
|
||||
// Normal text
|
||||
bg = ColorNone;
|
||||
gfx::Color fg = getColor(ThemeColor::Text);
|
||||
gfx::Color fg = colors.text();
|
||||
|
||||
// Selected
|
||||
if ((c >= selbeg) && (c <= selend)) {
|
||||
if (widget->hasFocus())
|
||||
bg = getColor(ThemeColor::Selected);
|
||||
bg = colors.selected();
|
||||
else
|
||||
bg = getColor(ThemeColor::Disabled);
|
||||
fg = getColor(ThemeColor::Background);
|
||||
bg = colors.disabled();
|
||||
fg = colors.background();
|
||||
}
|
||||
|
||||
// Disabled
|
||||
if (!widget->isEnabled()) {
|
||||
bg = ColorNone;
|
||||
fg = getColor(ThemeColor::Disabled);
|
||||
fg = colors.disabled();
|
||||
}
|
||||
|
||||
// Suffix
|
||||
@ -1123,7 +1087,7 @@ void SkinTheme::paintEntry(PaintEvent& ev)
|
||||
break;
|
||||
|
||||
bg = ColorNone;
|
||||
fg = getColor(ThemeColor::EntrySuffix);
|
||||
fg = colors.entrySuffix();
|
||||
}
|
||||
|
||||
w = g->measureChar(ch).w;
|
||||
@ -1151,43 +1115,48 @@ void SkinTheme::paintLabel(PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
Label* widget = static_cast<Label*>(ev.getSource());
|
||||
Style* style = styles.label();
|
||||
gfx::Color bg = BGCOLOR;
|
||||
gfx::Color fg = widget->getTextColor();
|
||||
Rect text, rc = widget->getClientBounds();
|
||||
|
||||
SkinStylePropertyPtr styleProp = widget->getProperty(SkinStyleProperty::Name);
|
||||
if (styleProp)
|
||||
style = styleProp->getStyle();
|
||||
|
||||
if (!is_transparent(bg))
|
||||
g->fillRect(bg, rc);
|
||||
|
||||
rc.shrink(widget->getBorder());
|
||||
|
||||
widget->getTextIconInfo(NULL, &text);
|
||||
g->drawUIString(widget->getText(), fg, ColorNone, text.getOrigin());
|
||||
style->paint(g, text, widget->getText().c_str(), Style::State());
|
||||
}
|
||||
|
||||
void SkinTheme::paintLinkLabel(PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
Widget* widget = static_cast<Widget*>(ev.getSource());
|
||||
Style* style = styles.link();
|
||||
gfx::Rect bounds = widget->getClientBounds();
|
||||
gfx::Color fg = getColor(ThemeColor::LinkText);
|
||||
gfx::Color bg = BGCOLOR;
|
||||
|
||||
g->fillRect(bg, bounds);
|
||||
drawTextString(g, NULL, fg, ColorNone, widget, bounds, 0);
|
||||
SkinStylePropertyPtr styleProp = widget->getProperty(SkinStyleProperty::Name);
|
||||
if (styleProp)
|
||||
style = styleProp->getStyle();
|
||||
|
||||
// Underline style
|
||||
if (widget->hasMouseOver()) {
|
||||
int w = widget->getTextWidth();
|
||||
for (int v=0; v<guiscale(); ++v)
|
||||
g->drawHLine(fg, bounds.x, bounds.y2()-1-v, w);
|
||||
}
|
||||
Style::State state;
|
||||
if (widget->hasMouseOver()) state += Style::hover();
|
||||
if (widget->isSelected()) state += Style::clicked();
|
||||
|
||||
g->fillRect(bg, bounds);
|
||||
style->paint(g, bounds, widget->getText().c_str(), state);
|
||||
}
|
||||
|
||||
void SkinTheme::paintListBox(PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
|
||||
g->fillRect(getColor(ThemeColor::Background), g->getClipBounds());
|
||||
g->fillRect(colors.background(), g->getClipBounds());
|
||||
}
|
||||
|
||||
void SkinTheme::paintListItem(ui::PaintEvent& ev)
|
||||
@ -1198,16 +1167,16 @@ void SkinTheme::paintListItem(ui::PaintEvent& ev)
|
||||
gfx::Color fg, bg;
|
||||
|
||||
if (!widget->isEnabled()) {
|
||||
bg = getColor(ThemeColor::Face);
|
||||
fg = getColor(ThemeColor::Disabled);
|
||||
bg = colors.face();
|
||||
fg = colors.disabled();
|
||||
}
|
||||
else if (widget->isSelected()) {
|
||||
fg = getColor(ThemeColor::ListItemSelectedText);
|
||||
bg = getColor(ThemeColor::ListItemSelectedFace);
|
||||
fg = colors.listitemSelectedText();
|
||||
bg = colors.listitemSelectedFace();
|
||||
}
|
||||
else {
|
||||
fg = getColor(ThemeColor::ListItemNormalText);
|
||||
bg = getColor(ThemeColor::ListItemNormalFace);
|
||||
fg = colors.listitemNormalText();
|
||||
bg = colors.listitemNormalFace();
|
||||
}
|
||||
|
||||
g->fillRect(bg, bounds);
|
||||
@ -1244,20 +1213,20 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev)
|
||||
// Colors
|
||||
if (!widget->isEnabled()) {
|
||||
fg = ColorNone;
|
||||
bg = getColor(ThemeColor::MenuItemNormalFace);
|
||||
bg = colors.menuitemNormalFace();
|
||||
}
|
||||
else {
|
||||
if (widget->isHighlighted()) {
|
||||
fg = getColor(ThemeColor::MenuItemHighlightText);
|
||||
bg = getColor(ThemeColor::MenuItemHighlightFace);
|
||||
fg = colors.menuitemHighlightText();
|
||||
bg = colors.menuitemHighlightFace();
|
||||
}
|
||||
else if (widget->hasMouse()) {
|
||||
fg = getColor(ThemeColor::MenuItemHotText);
|
||||
bg = getColor(ThemeColor::MenuItemHotFace);
|
||||
fg = colors.menuitemHotText();
|
||||
bg = colors.menuitemHotFace();
|
||||
}
|
||||
else {
|
||||
fg = getColor(ThemeColor::MenuItemNormalText);
|
||||
bg = getColor(ThemeColor::MenuItemNormalFace);
|
||||
fg = colors.menuitemNormalText();
|
||||
bg = colors.menuitemNormalFace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1301,12 +1270,12 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev)
|
||||
// Disabled
|
||||
else {
|
||||
for (c=0; c<3*scale; c++)
|
||||
g->drawVLine(getColor(ThemeColor::Background),
|
||||
g->drawVLine(colors.background(),
|
||||
bounds.x2()-3*scale-c+1,
|
||||
bounds.y+bounds.h/2-c+1, 2*c+1);
|
||||
|
||||
for (c=0; c<3*scale; c++)
|
||||
g->drawVLine(getColor(ThemeColor::Disabled),
|
||||
g->drawVLine(colors.disabled(),
|
||||
bounds.x2()-3*scale-c,
|
||||
bounds.y+bounds.h/2-c, 2*c+1);
|
||||
}
|
||||
@ -1333,7 +1302,7 @@ void SkinTheme::paintSplitter(PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
|
||||
g->fillRect(getColor(ThemeColor::SplitterNormalFace), g->getClipBounds());
|
||||
g->fillRect(colors.splitterNormalFace(), g->getClipBounds());
|
||||
}
|
||||
|
||||
void SkinTheme::paintRadioButton(PaintEvent& ev)
|
||||
@ -1356,9 +1325,9 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
|
||||
// Mouse
|
||||
if (widget->isEnabled()) {
|
||||
if (widget->hasMouseOver())
|
||||
g->fillRect(bg = getColor(ThemeColor::RadioHotFace), bounds);
|
||||
g->fillRect(bg = colors.radioHotFace(), bounds);
|
||||
else if (widget->hasFocus())
|
||||
g->fillRect(bg = getColor(ThemeColor::RadioFocusFace), bounds);
|
||||
g->fillRect(bg = colors.radioFocusFace(), bounds);
|
||||
}
|
||||
|
||||
// Text
|
||||
@ -1400,7 +1369,7 @@ void SkinTheme::paintSeparator(ui::PaintEvent& ev)
|
||||
bounds.y2() - widget->border_width.b/2 + h));
|
||||
|
||||
drawTextString(g, NULL,
|
||||
getColorById(kSeparatorLabelColorId), BGCOLOR,
|
||||
colors.separatorLabel(), BGCOLOR,
|
||||
widget, r, 0);
|
||||
}
|
||||
}
|
||||
@ -1489,14 +1458,14 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
||||
}
|
||||
|
||||
if (value == min)
|
||||
draw_bounds_nw(g, rc, empty_part_nw, getColor(ThemeColor::SliderEmptyFace));
|
||||
draw_bounds_nw(g, rc, empty_part_nw, colors.sliderEmptyFace());
|
||||
else if (value == max)
|
||||
draw_bounds_nw(g, rc, full_part_nw, getColor(ThemeColor::SliderFullFace));
|
||||
draw_bounds_nw(g, rc, full_part_nw, colors.sliderFullFace());
|
||||
else
|
||||
draw_bounds_nw2(g, rc, x,
|
||||
full_part_nw, empty_part_nw,
|
||||
getColor(ThemeColor::SliderFullFace),
|
||||
getColor(ThemeColor::SliderEmptyFace));
|
||||
full_part_nw, empty_part_nw,
|
||||
colors.sliderFullFace(),
|
||||
colors.sliderEmptyFace());
|
||||
|
||||
// Draw text
|
||||
std::string old_text = widget->getText();
|
||||
@ -1511,7 +1480,7 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
||||
IntersectClip clip(g, Rect(rc.x, rc.y, x-rc.x, rc.h));
|
||||
if (clip) {
|
||||
drawTextString(g, NULL,
|
||||
getColor(ThemeColor::SliderFullText), ColorNone,
|
||||
colors.sliderFullText(), ColorNone,
|
||||
widget, rc, 0);
|
||||
}
|
||||
}
|
||||
@ -1520,7 +1489,7 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
||||
IntersectClip clip(g, Rect(x+1, rc.y, rc.w-(x-rc.x+1), rc.h));
|
||||
if (clip) {
|
||||
drawTextString(g, NULL,
|
||||
getColor(ThemeColor::SliderEmptyText),
|
||||
colors.sliderEmptyText(),
|
||||
ColorNone, widget, rc, 0);
|
||||
}
|
||||
}
|
||||
@ -1545,7 +1514,7 @@ void SkinTheme::paintComboBoxEntry(ui::PaintEvent& ev)
|
||||
// Outside borders
|
||||
g->fillRect(BGCOLOR, bounds);
|
||||
|
||||
gfx::Color fg, bg = getColor(ThemeColor::Background);
|
||||
gfx::Color fg, bg = colors.background();
|
||||
|
||||
draw_bounds_nw(g, bounds,
|
||||
widget->hasFocus() ?
|
||||
@ -1564,21 +1533,21 @@ void SkinTheme::paintComboBoxEntry(ui::PaintEvent& ev)
|
||||
|
||||
// Normal text
|
||||
bg = ColorNone;
|
||||
fg = getColor(ThemeColor::Text);
|
||||
fg = colors.text();
|
||||
|
||||
// Selected
|
||||
if ((c >= selbeg) && (c <= selend)) {
|
||||
if (widget->hasFocus())
|
||||
bg = getColor(ThemeColor::Selected);
|
||||
bg = colors.selected();
|
||||
else
|
||||
bg = getColor(ThemeColor::Disabled);
|
||||
fg = getColor(ThemeColor::Background);
|
||||
bg = colors.disabled();
|
||||
fg = colors.background();
|
||||
}
|
||||
|
||||
// Disabled
|
||||
if (!widget->isEnabled()) {
|
||||
bg = ColorNone;
|
||||
fg = getColor(ThemeColor::Disabled);
|
||||
fg = colors.disabled();
|
||||
}
|
||||
|
||||
w = g->measureChar(ch).w;
|
||||
@ -1611,17 +1580,17 @@ void SkinTheme::paintComboBoxButton(PaintEvent& ev)
|
||||
gfx::Color bg;
|
||||
|
||||
if (widget->isSelected()) {
|
||||
bg = getColor(ThemeColor::ButtonSelectedFace);
|
||||
bg = colors.buttonSelectedFace();
|
||||
part_nw = PART_TOOLBUTTON_PUSHED_NW;
|
||||
}
|
||||
// With mouse
|
||||
else if (widget->isEnabled() && widget->hasMouseOver()) {
|
||||
bg = getColor(ThemeColor::ButtonHotFace);
|
||||
bg = colors.buttonHotFace();
|
||||
part_nw = PART_TOOLBUTTON_HOT_NW;
|
||||
}
|
||||
// Without mouse
|
||||
else {
|
||||
bg = getColor(ThemeColor::ButtonNormalFace);
|
||||
bg = colors.buttonNormalFace();
|
||||
part_nw = PART_TOOLBUTTON_LAST_NW;
|
||||
}
|
||||
|
||||
@ -1649,8 +1618,8 @@ void SkinTheme::paintTextBox(ui::PaintEvent& ev)
|
||||
Widget* widget = static_cast<Widget*>(ev.getSource());
|
||||
|
||||
drawTextBox(g, widget, NULL, NULL,
|
||||
getColor(ThemeColor::TextBoxFace),
|
||||
getColor(ThemeColor::TextBoxText));
|
||||
colors.textboxFace(),
|
||||
colors.textboxText());
|
||||
}
|
||||
|
||||
void SkinTheme::paintView(PaintEvent& ev)
|
||||
@ -1659,15 +1628,19 @@ void SkinTheme::paintView(PaintEvent& ev)
|
||||
View* widget = static_cast<View*>(ev.getSource());
|
||||
gfx::Rect bounds = widget->getClientBounds();
|
||||
gfx::Color bg = BGCOLOR;
|
||||
Style* style = styles.view();
|
||||
|
||||
SkinStylePropertyPtr styleProp = widget->getProperty(SkinStyleProperty::Name);
|
||||
if (styleProp)
|
||||
style = styleProp->getStyle();
|
||||
|
||||
Style::State state;
|
||||
if (widget->hasMouseOver()) state += Style::hover();
|
||||
|
||||
if (!is_transparent(bg))
|
||||
g->fillRect(bg, bounds);
|
||||
|
||||
draw_bounds_nw(g, bounds,
|
||||
(widget->hasFocus() ?
|
||||
PART_SUNKEN_FOCUSED_NW:
|
||||
PART_SUNKEN_NORMAL_NW),
|
||||
BGCOLOR);
|
||||
style->paint(g, bounds, nullptr, state);
|
||||
}
|
||||
|
||||
void SkinTheme::paintViewScrollbar(PaintEvent& ev)
|
||||
@ -1681,8 +1654,13 @@ void SkinTheme::paintViewScrollbar(PaintEvent& ev)
|
||||
if (skinPropery != NULL)
|
||||
isMiniLook = (skinPropery->getLook() == MiniLook);
|
||||
|
||||
skin::Style* bgStyle = get_style(isMiniLook ? "mini_scrollbar": "scrollbar");
|
||||
skin::Style* thumbStyle = get_style(isMiniLook ? "mini_scrollbar_thumb": "scrollbar_thumb");
|
||||
skin::Style* bgStyle = (isMiniLook ?
|
||||
styles.miniScrollbar():
|
||||
styles.scrollbar());
|
||||
|
||||
skin::Style* thumbStyle = (isMiniLook ?
|
||||
styles.miniScrollbarThumb():
|
||||
styles.scrollbarThumb());
|
||||
|
||||
widget->getScrollBarThemeInfo(&pos, &len);
|
||||
|
||||
@ -1724,20 +1702,20 @@ void SkinTheme::paintWindow(PaintEvent& ev)
|
||||
if (!window->isDesktop()) {
|
||||
// window frame
|
||||
if (window->hasText()) {
|
||||
get_style("window")->paint(g, pos, NULL, Style::State());
|
||||
get_style("window_title")->paint(g,
|
||||
styles.window()->paint(g, pos, NULL, Style::State());
|
||||
styles.windowTitle()->paint(g,
|
||||
gfx::Rect(cpos.x, pos.y+5*guiscale(), cpos.w, // TODO this hard-coded 5 should be configurable in skin.xml
|
||||
window->getTextHeight()),
|
||||
window->getText().c_str(), Style::State());
|
||||
}
|
||||
// menubox
|
||||
else {
|
||||
get_style("menubox")->paint(g, pos, NULL, Style::State());
|
||||
styles.menubox()->paint(g, pos, NULL, Style::State());
|
||||
}
|
||||
}
|
||||
// desktop
|
||||
else {
|
||||
get_style("desktop")->paint(g, pos, NULL, Style::State());
|
||||
styles.desktop()->paint(g, pos, NULL, Style::State());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1749,12 +1727,12 @@ void SkinTheme::paintPopupWindow(PaintEvent& ev)
|
||||
gfx::Rect pos = window->getClientBounds();
|
||||
|
||||
if (!is_transparent(BGCOLOR))
|
||||
get_style("menubox")->paint(g, pos, NULL, Style::State());
|
||||
styles.menubox()->paint(g, pos, NULL, Style::State());
|
||||
|
||||
pos.shrink(window->getBorder());
|
||||
|
||||
g->drawAlignedUIString(window->getText(),
|
||||
getColor(ThemeColor::Text),
|
||||
colors.text(),
|
||||
window->getBgColor(), pos,
|
||||
window->getAlign());
|
||||
}
|
||||
@ -1781,8 +1759,8 @@ void SkinTheme::paintTooltip(PaintEvent& ev)
|
||||
ui::TipWindow* widget = static_cast<ui::TipWindow*>(ev.getSource());
|
||||
Graphics* g = ev.getGraphics();
|
||||
Rect rc = widget->getClientBounds();
|
||||
gfx::Color fg = getColor(ThemeColor::TooltipText);
|
||||
gfx::Color bg = getColor(ThemeColor::TooltipFace);
|
||||
gfx::Color fg = colors.tooltipText();
|
||||
gfx::Color bg = colors.tooltipFace();
|
||||
|
||||
int nw = PART_TOOLTIP_NW;
|
||||
int n = PART_TOOLTIP_N;
|
||||
@ -1853,9 +1831,9 @@ gfx::Color SkinTheme::getWidgetBgColor(Widget* widget)
|
||||
if (!is_transparent(c) || widget->getType() == kWindowWidget)
|
||||
return c;
|
||||
else if (decorative)
|
||||
return getColor(ThemeColor::Selected);
|
||||
return colors.selected();
|
||||
else
|
||||
return getColor(ThemeColor::Face);
|
||||
return colors.face();
|
||||
}
|
||||
|
||||
void SkinTheme::drawTextString(Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color,
|
||||
@ -1914,16 +1892,16 @@ void SkinTheme::drawTextString(Graphics* g, const char *t, gfx::Color fg_color,
|
||||
if (!widget->isEnabled()) {
|
||||
// Draw white part
|
||||
g->drawUIString(t,
|
||||
getColor(ThemeColor::Background),
|
||||
colors.background(),
|
||||
gfx::ColorNone,
|
||||
textrc.getOrigin() + Point(guiscale(), guiscale()));
|
||||
}
|
||||
|
||||
g->drawUIString(t,
|
||||
(!widget->isEnabled() ?
|
||||
getColor(ThemeColor::Disabled):
|
||||
colors.disabled():
|
||||
(gfx::geta(fg_color) > 0 ? fg_color :
|
||||
getColor(ThemeColor::Text))),
|
||||
colors.text())),
|
||||
bg_color, textrc.getOrigin());
|
||||
}
|
||||
}
|
||||
@ -1931,7 +1909,7 @@ void SkinTheme::drawTextString(Graphics* g, const char *t, gfx::Color fg_color,
|
||||
|
||||
void SkinTheme::drawEntryCaret(ui::Graphics* g, Entry* widget, int x, int y)
|
||||
{
|
||||
gfx::Color color = getColor(ThemeColor::Text);
|
||||
gfx::Color color = colors.text();
|
||||
int h = widget->getTextHeight();
|
||||
|
||||
for (int u=x; u<x+2*guiscale(); ++u)
|
||||
@ -2142,7 +2120,7 @@ void SkinTheme::draw_part_as_vline(ui::Graphics* g, const gfx::Rect& rc, int par
|
||||
|
||||
void SkinTheme::paintProgressBar(ui::Graphics* g, const gfx::Rect& rc0, double progress)
|
||||
{
|
||||
g->drawRect(getColor(ThemeColor::Text), rc0);
|
||||
g->drawRect(colors.text(), rc0);
|
||||
|
||||
gfx::Rect rc = rc0;
|
||||
rc.shrink(1);
|
||||
@ -2151,10 +2129,10 @@ void SkinTheme::paintProgressBar(ui::Graphics* g, const gfx::Rect& rc0, double p
|
||||
u = MID(0, u, rc.w);
|
||||
|
||||
if (u > 0)
|
||||
g->fillRect(getColor(ThemeColor::Selected), gfx::Rect(rc.x, rc.y, u, rc.h));
|
||||
g->fillRect(colors.selected(), gfx::Rect(rc.x, rc.y, u, rc.h));
|
||||
|
||||
if (1+u < rc.w)
|
||||
g->fillRect(getColor(ThemeColor::Background), gfx::Rect(rc.x+u, rc.y, rc.w-u, rc.h));
|
||||
g->fillRect(colors.background(), gfx::Rect(rc.x+u, rc.y, rc.w-u, rc.h));
|
||||
}
|
||||
|
||||
void SkinTheme::paintIcon(Widget* widget, Graphics* g, IButtonIcon* iconInterface, int x, int y)
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "ui/manager.h"
|
||||
#include "ui/theme.h"
|
||||
|
||||
#include "generated_skin.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
@ -33,82 +35,18 @@ namespace she {
|
||||
namespace app {
|
||||
namespace skin {
|
||||
|
||||
namespace ThemeColor {
|
||||
enum Type {
|
||||
Text,
|
||||
Disabled,
|
||||
Face,
|
||||
HotFace,
|
||||
Selected,
|
||||
Background,
|
||||
TextBoxText,
|
||||
TextBoxFace,
|
||||
EntrySuffix,
|
||||
LinkText,
|
||||
ButtonNormalText,
|
||||
ButtonNormalFace,
|
||||
ButtonHotText,
|
||||
ButtonHotFace,
|
||||
ButtonSelectedText,
|
||||
ButtonSelectedFace,
|
||||
CheckHotFace,
|
||||
CheckFocusFace,
|
||||
RadioHotFace,
|
||||
RadioFocusFace,
|
||||
MenuItemNormalText,
|
||||
MenuItemNormalFace,
|
||||
MenuItemHotText,
|
||||
MenuItemHotFace,
|
||||
MenuItemHighlightText,
|
||||
MenuItemHighlightFace,
|
||||
EditorFace,
|
||||
EditorSpriteBorder,
|
||||
EditorSpriteBottomBorder,
|
||||
ListItemNormalText,
|
||||
ListItemNormalFace,
|
||||
ListItemSelectedText,
|
||||
ListItemSelectedFace,
|
||||
SliderEmptyText,
|
||||
SliderEmptyFace,
|
||||
SliderFullText,
|
||||
SliderFullFace,
|
||||
TabNormalText,
|
||||
TabNormalFace,
|
||||
TabSelectedText,
|
||||
TabSelectedFace,
|
||||
SplitterNormalFace,
|
||||
ScrollBarBgFace,
|
||||
ScrollBarThumbFace,
|
||||
PopupWindowBorder,
|
||||
TooltipText,
|
||||
TooltipFace,
|
||||
FileListEvenRowText,
|
||||
FileListEvenRowFace,
|
||||
FileListOddRowText,
|
||||
FileListOddRowFace,
|
||||
FileListSelectedRowText,
|
||||
FileListSelectedRowFace,
|
||||
FileListDisabledRowText,
|
||||
Workspace,
|
||||
MaxColors
|
||||
};
|
||||
}
|
||||
|
||||
extern const char* kWindowFaceColorId;
|
||||
|
||||
// This is the GUI theme used by Aseprite (which use images from
|
||||
// data/skins directory).
|
||||
class SkinTheme : public ui::Theme {
|
||||
class SkinTheme : public ui::Theme
|
||||
, public app::gen::SkinFile<SkinTheme> {
|
||||
public:
|
||||
static const char* kThemeCloseButtonId;
|
||||
|
||||
static SkinTheme* instance();
|
||||
|
||||
SkinTheme();
|
||||
~SkinTheme();
|
||||
|
||||
gfx::Color getColor(ThemeColor::Type k) const {
|
||||
return m_colors[k];
|
||||
}
|
||||
|
||||
she::Font* getMiniFont() const { return m_minifont; }
|
||||
|
||||
void reload_skin();
|
||||
@ -170,7 +108,12 @@ namespace app {
|
||||
return m_parts_by_id[id];
|
||||
}
|
||||
|
||||
int getDimensionById(const std::string& id) {
|
||||
return m_dimensions_by_id[id] * ui::guiscale();
|
||||
}
|
||||
|
||||
gfx::Color getColorById(const std::string& id) {
|
||||
ASSERT(m_colors_by_id.find(id) != m_colors_by_id.end());
|
||||
return m_colors_by_id[id];
|
||||
}
|
||||
|
||||
@ -203,16 +146,12 @@ namespace app {
|
||||
std::map<std::string, SkinPartPtr> m_parts_by_id;
|
||||
std::map<std::string, she::Surface*> m_toolicon;
|
||||
std::map<std::string, gfx::Color> m_colors_by_id;
|
||||
std::map<std::string, int> m_dimensions_by_id;
|
||||
std::vector<ui::Cursor*> m_cursors;
|
||||
std::vector<gfx::Color> m_colors;
|
||||
StyleSheet m_stylesheet;
|
||||
she::Font* m_minifont;
|
||||
};
|
||||
|
||||
inline Style* get_style(const std::string& id) {
|
||||
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getStyle(id);
|
||||
}
|
||||
|
||||
inline SkinPartPtr get_part_by_id(const std::string& id) {
|
||||
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getPartById(id);
|
||||
}
|
||||
|
@ -44,7 +44,26 @@ void BackgroundRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const cha
|
||||
if (!gfx::is_transparent(m_color))
|
||||
g->fillRect(m_color, bounds);
|
||||
|
||||
g->drawRgbaSurface(m_part->getBitmap(0), bounds.x, bounds.y);
|
||||
she::Surface* bmp = m_part->getBitmap(0);
|
||||
|
||||
if (m_repeat == BackgroundRepeat::NO_REPEAT) {
|
||||
g->drawRgbaSurface(bmp, bounds.x, bounds.y);
|
||||
}
|
||||
else {
|
||||
ui::IntersectClip clip(g, bounds);
|
||||
if (!clip)
|
||||
return;
|
||||
|
||||
for (int y=bounds.y; y<bounds.y2(); y+=bmp->height()) {
|
||||
for (int x=bounds.x; x<bounds.x2(); x+=bmp->width()) {
|
||||
g->drawRgbaSurface(bmp, x, y);
|
||||
if (m_repeat == BackgroundRepeat::REPEAT_Y)
|
||||
break;
|
||||
}
|
||||
if (m_repeat == BackgroundRepeat::REPEAT_X)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_part->size() == 8) {
|
||||
theme->draw_bounds_nw(g, bounds, m_part, m_color);
|
||||
@ -62,7 +81,7 @@ void TextRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* tex
|
||||
if (text) {
|
||||
g->drawAlignedUIString(text,
|
||||
(gfx::is_transparent(m_color) ?
|
||||
theme->getColor(ThemeColor::Text):
|
||||
theme->colors.text():
|
||||
m_color),
|
||||
gfx::ColorNone,
|
||||
gfx::Rect(bounds).shrink(m_padding), m_align);
|
||||
@ -88,6 +107,9 @@ void IconRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* tex
|
||||
else
|
||||
y = bounds.y;
|
||||
|
||||
x += m_x;
|
||||
y += m_y;
|
||||
|
||||
g->drawRgbaSurface(bmp, x, y);
|
||||
}
|
||||
|
||||
@ -98,8 +120,11 @@ Rules::Rules(const css::Query& query) :
|
||||
{
|
||||
css::Value backgroundColor = query[StyleSheet::backgroundColorRule()];
|
||||
css::Value backgroundPart = query[StyleSheet::backgroundPartRule()];
|
||||
css::Value backgroundRepeat = query[StyleSheet::backgroundRepeatRule()];
|
||||
css::Value iconAlign = query[StyleSheet::iconAlignRule()];
|
||||
css::Value iconPart = query[StyleSheet::iconPartRule()];
|
||||
css::Value iconX = query[StyleSheet::iconXRule()];
|
||||
css::Value iconY = query[StyleSheet::iconYRule()];
|
||||
css::Value textAlign = query[StyleSheet::textAlignRule()];
|
||||
css::Value textColor = query[StyleSheet::textColorRule()];
|
||||
css::Value paddingLeft = query[StyleSheet::paddingLeftRule()];
|
||||
@ -109,17 +134,23 @@ Rules::Rules(const css::Query& query) :
|
||||
css::Value none;
|
||||
|
||||
if (backgroundColor != none
|
||||
|| backgroundPart != none) {
|
||||
|| backgroundPart != none
|
||||
|| backgroundRepeat != none) {
|
||||
m_background = new BackgroundRule();
|
||||
m_background->setColor(StyleSheet::convertColor(backgroundColor));
|
||||
m_background->setPart(StyleSheet::convertPart(backgroundPart));
|
||||
m_background->setRepeat(StyleSheet::convertRepeat(backgroundRepeat));
|
||||
}
|
||||
|
||||
if (iconAlign != none
|
||||
|| iconPart != none) {
|
||||
|| iconPart != none
|
||||
|| iconX != none
|
||||
|| iconY != none) {
|
||||
m_icon = new IconRule();
|
||||
m_icon->setAlign((int)iconAlign.number());
|
||||
m_icon->setPart(StyleSheet::convertPart(iconPart));
|
||||
m_icon->setX((int)iconX.number()*ui::guiscale());
|
||||
m_icon->setY((int)iconY.number()*ui::guiscale());
|
||||
}
|
||||
|
||||
if (textAlign != none
|
||||
@ -155,7 +186,7 @@ void Rules::paint(ui::Graphics* g,
|
||||
if (m_text) m_text->paint(g, bounds, text);
|
||||
}
|
||||
|
||||
gfx::Size Rules::preferredSize(const char* text)
|
||||
gfx::Size Rules::preferredSize(const char* text, int maxWidth)
|
||||
{
|
||||
gfx::Size sz(0, 0);
|
||||
if (m_icon) {
|
||||
@ -164,10 +195,13 @@ gfx::Size Rules::preferredSize(const char* text)
|
||||
}
|
||||
if (m_text && text) {
|
||||
ui::ScreenGraphics g;
|
||||
gfx::Size textSize = g.measureUIString(text);
|
||||
//if (sz.w > 0) sz.w += 2; // TODO text separation
|
||||
gfx::Size textSize = g.fitString(text, maxWidth, m_text->align());
|
||||
if (sz.w > 0) sz.w += 2*ui::guiscale(); // TODO text separation
|
||||
sz.w += textSize.w;
|
||||
sz.h = MAX(sz.h, textSize.h);
|
||||
|
||||
sz.w += m_text->padding().left() + m_text->padding().right();
|
||||
sz.h += m_text->padding().top() + m_text->padding().bottom();
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
@ -212,9 +246,10 @@ void Style::paint(ui::Graphics* g,
|
||||
|
||||
gfx::Size Style::preferredSize(
|
||||
const char* text,
|
||||
const State& state)
|
||||
const State& state,
|
||||
int maxWidth)
|
||||
{
|
||||
return getRulesFromState(state)->preferredSize(text);
|
||||
return getRulesFromState(state)->preferredSize(text, maxWidth);
|
||||
}
|
||||
|
||||
} // namespace skin
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_UI_SKIN_STYLE_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/skin/background_repeat.h"
|
||||
#include "app/ui/skin/skin_part.h"
|
||||
#include "base/disable_copying.h"
|
||||
#include "css/compound_style.h"
|
||||
@ -44,10 +45,12 @@ namespace app {
|
||||
|
||||
class BackgroundRule : public Rule {
|
||||
public:
|
||||
BackgroundRule() : m_color(gfx::ColorNone) { }
|
||||
BackgroundRule() : m_color(gfx::ColorNone)
|
||||
, m_repeat(BackgroundRepeat::NO_REPEAT) { }
|
||||
|
||||
void setColor(gfx::Color color) { m_color = color; }
|
||||
void setPart(const SkinPartPtr& part) { m_part = part; }
|
||||
void setRepeat(BackgroundRepeat repeat) { m_repeat = repeat; }
|
||||
|
||||
protected:
|
||||
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) override;
|
||||
@ -55,6 +58,7 @@ namespace app {
|
||||
private:
|
||||
gfx::Color m_color;
|
||||
SkinPartPtr m_part;
|
||||
BackgroundRepeat m_repeat;
|
||||
};
|
||||
|
||||
class TextRule : public Rule {
|
||||
@ -66,6 +70,9 @@ namespace app {
|
||||
void setColor(gfx::Color color) { m_color = color; }
|
||||
void setPadding(const gfx::Border& padding) { m_padding = padding; }
|
||||
|
||||
int align() const { return m_align; }
|
||||
gfx::Border padding() const { return m_padding; }
|
||||
|
||||
protected:
|
||||
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) override;
|
||||
|
||||
@ -81,6 +88,8 @@ namespace app {
|
||||
|
||||
void setAlign(int align) { m_align = align; }
|
||||
void setPart(const SkinPartPtr& part) { m_part = part; }
|
||||
void setX(int x) { m_x = x; }
|
||||
void setY(int y) { m_y = y; }
|
||||
|
||||
SkinPartPtr getPart() { return m_part; }
|
||||
|
||||
@ -90,6 +99,7 @@ namespace app {
|
||||
private:
|
||||
int m_align;
|
||||
SkinPartPtr m_part;
|
||||
int m_x, m_y;
|
||||
};
|
||||
|
||||
class Rules {
|
||||
@ -101,7 +111,7 @@ namespace app {
|
||||
const gfx::Rect& bounds,
|
||||
const char* text);
|
||||
|
||||
gfx::Size preferredSize(const char* text);
|
||||
gfx::Size preferredSize(const char* text, int maxWidth);
|
||||
|
||||
private:
|
||||
BackgroundRule* m_background;
|
||||
@ -129,7 +139,8 @@ namespace app {
|
||||
|
||||
gfx::Size preferredSize(
|
||||
const char* text,
|
||||
const State& state);
|
||||
const State& state,
|
||||
int maxWidth = 0);
|
||||
|
||||
const std::string& id() const { return m_id; }
|
||||
|
||||
|
@ -23,8 +23,11 @@ namespace skin {
|
||||
|
||||
css::Rule StyleSheet::m_backgroundColorRule("background-color");
|
||||
css::Rule StyleSheet::m_backgroundPartRule("background-part");
|
||||
css::Rule StyleSheet::m_backgroundRepeatRule("background-repeat");
|
||||
css::Rule StyleSheet::m_iconAlignRule("icon-align");
|
||||
css::Rule StyleSheet::m_iconPartRule("icon-part");
|
||||
css::Rule StyleSheet::m_iconXRule("icon-x");
|
||||
css::Rule StyleSheet::m_iconYRule("icon-y");
|
||||
css::Rule StyleSheet::m_textAlignRule("text-align");
|
||||
css::Rule StyleSheet::m_textColorRule("text-color");
|
||||
css::Rule StyleSheet::m_paddingLeftRule("padding-left");
|
||||
@ -37,8 +40,11 @@ StyleSheet::StyleSheet()
|
||||
m_sheet = new css::Sheet;
|
||||
m_sheet->addRule(&m_backgroundColorRule);
|
||||
m_sheet->addRule(&m_backgroundPartRule);
|
||||
m_sheet->addRule(&m_backgroundRepeatRule);
|
||||
m_sheet->addRule(&m_iconAlignRule);
|
||||
m_sheet->addRule(&m_iconPartRule);
|
||||
m_sheet->addRule(&m_iconXRule);
|
||||
m_sheet->addRule(&m_iconYRule);
|
||||
m_sheet->addRule(&m_textAlignRule);
|
||||
m_sheet->addRule(&m_textColorRule);
|
||||
m_sheet->addRule(&m_paddingLeftRule);
|
||||
@ -114,5 +120,25 @@ gfx::Color StyleSheet::convertColor(const css::Value& value)
|
||||
return color;
|
||||
}
|
||||
|
||||
// static
|
||||
BackgroundRepeat StyleSheet::convertRepeat(const css::Value& value)
|
||||
{
|
||||
BackgroundRepeat repeat = BackgroundRepeat::NO_REPEAT;
|
||||
if (value.type() == css::Value::String) {
|
||||
const std::string& id = value.string();
|
||||
if (id == "repeat")
|
||||
repeat = BackgroundRepeat::REPEAT;
|
||||
else if (id == "repeat-x")
|
||||
repeat = BackgroundRepeat::REPEAT_X;
|
||||
else if (id == "repeat-y")
|
||||
repeat = BackgroundRepeat::REPEAT_Y;
|
||||
else if (id == "no_repeat")
|
||||
repeat = BackgroundRepeat::NO_REPEAT;
|
||||
else
|
||||
throw base::Exception("Unknown repeat value '%s'\n", id.c_str());
|
||||
}
|
||||
return repeat;
|
||||
}
|
||||
|
||||
} // namespace skin
|
||||
} // namespace app
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_UI_SKIN_STYLE_SHEET_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/skin/background_repeat.h"
|
||||
#include "app/ui/skin/skin_part.h"
|
||||
#include "css/rule.h"
|
||||
#include "css/state.h"
|
||||
@ -37,8 +38,11 @@ namespace app {
|
||||
|
||||
static css::Rule& backgroundColorRule() { return m_backgroundColorRule; }
|
||||
static css::Rule& backgroundPartRule() { return m_backgroundPartRule; }
|
||||
static css::Rule& backgroundRepeatRule() { return m_backgroundRepeatRule; }
|
||||
static css::Rule& iconAlignRule() { return m_iconAlignRule; }
|
||||
static css::Rule& iconPartRule() { return m_iconPartRule; }
|
||||
static css::Rule& iconXRule() { return m_iconXRule; }
|
||||
static css::Rule& iconYRule() { return m_iconYRule; }
|
||||
static css::Rule& textAlignRule() { return m_textAlignRule; }
|
||||
static css::Rule& textColorRule() { return m_textColorRule; }
|
||||
static css::Rule& paddingLeftRule() { return m_paddingLeftRule; }
|
||||
@ -53,14 +57,18 @@ namespace app {
|
||||
|
||||
static SkinPartPtr convertPart(const css::Value& value);
|
||||
static gfx::Color convertColor(const css::Value& value);
|
||||
static BackgroundRepeat convertRepeat(const css::Value& value);
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, Style*> StyleMap;
|
||||
|
||||
static css::Rule m_backgroundColorRule;
|
||||
static css::Rule m_backgroundPartRule;
|
||||
static css::Rule m_backgroundRepeatRule;
|
||||
static css::Rule m_iconAlignRule;
|
||||
static css::Rule m_iconPartRule;
|
||||
static css::Rule m_iconXRule;
|
||||
static css::Rule m_iconYRule;
|
||||
static css::Rule m_textAlignRule;
|
||||
static css::Rule m_textColorRule;
|
||||
static css::Rule m_paddingLeftRule;
|
||||
|
@ -1,54 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/start_view.h"
|
||||
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "ui/label.h"
|
||||
#include "ui/textbox.h"
|
||||
#include "ui/view.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
using namespace skin;
|
||||
|
||||
StartView::StartView()
|
||||
: Box(JI_VERTICAL)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->getColor(ThemeColor::Workspace));
|
||||
|
||||
child_spacing = 8 * guiscale();
|
||||
|
||||
addChild(new Label("Welcome to " PACKAGE " v" VERSION));
|
||||
}
|
||||
|
||||
StartView::~StartView()
|
||||
{
|
||||
}
|
||||
|
||||
std::string StartView::getTabText()
|
||||
{
|
||||
return "Start";
|
||||
}
|
||||
|
||||
WorkspaceView* StartView::cloneWorkspaceView()
|
||||
{
|
||||
return NULL; // This view cannot be cloned
|
||||
}
|
||||
|
||||
void StartView::onClonedFrom(WorkspaceView* from)
|
||||
{
|
||||
ASSERT(false); // Never called
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -1,39 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_START_VIEW_H_INCLUDED
|
||||
#define APP_UI_START_VIEW_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "ui/box.h"
|
||||
|
||||
namespace ui {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
class StartView : public ui::Box
|
||||
, public TabView
|
||||
, public WorkspaceView {
|
||||
public:
|
||||
StartView();
|
||||
~StartView();
|
||||
|
||||
// TabView implementation
|
||||
std::string getTabText() override;
|
||||
|
||||
// WorkspaceView implementation
|
||||
ui::Widget* getContentWidget() override { return this; }
|
||||
WorkspaceView* cloneWorkspaceView() override;
|
||||
void onClonedFrom(WorkspaceView* from) override;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -224,24 +224,6 @@ StatusBar::StatusBar()
|
||||
m_commandsBox = box1;
|
||||
}
|
||||
|
||||
// Create the box to show notifications.
|
||||
{
|
||||
Box* box1 = new Box(JI_HORIZONTAL);
|
||||
Box* box2 = new Box(JI_VERTICAL);
|
||||
|
||||
box1->setBorder(gfx::Border(2, 1, 2, 2)*guiscale());
|
||||
box2->noBorderNoChildSpacing();
|
||||
box2->setExpansive(true);
|
||||
|
||||
m_linkLabel = new LinkLabel((std::string(WEBSITE) + "donate/").c_str(), "Support This Project");
|
||||
|
||||
box1->addChild(box2);
|
||||
box1->addChild(m_linkLabel);
|
||||
m_notificationsBox = box1;
|
||||
}
|
||||
|
||||
addChild(m_notificationsBox);
|
||||
|
||||
App::instance()->CurrentToolChange.connect(&StatusBar::onCurrentToolChange, this);
|
||||
}
|
||||
|
||||
@ -252,7 +234,6 @@ StatusBar::~StatusBar()
|
||||
|
||||
delete m_tipwindow; // widget
|
||||
delete m_commandsBox;
|
||||
delete m_notificationsBox;
|
||||
}
|
||||
|
||||
void StatusBar::onCurrentToolChange()
|
||||
@ -455,11 +436,6 @@ void StatusBar::onResize(ResizeEvent& ev)
|
||||
setBoundsQuietly(ev.getBounds());
|
||||
|
||||
Rect rc = ev.getBounds();
|
||||
rc.x = rc.x2() - m_notificationsBox->getPreferredSize().w;
|
||||
rc.w = m_notificationsBox->getPreferredSize().w;
|
||||
m_notificationsBox->setBounds(rc);
|
||||
|
||||
rc = ev.getBounds();
|
||||
rc.w -= rc.w/4 + 4*guiscale();
|
||||
m_commandsBox->setBounds(rc);
|
||||
}
|
||||
@ -650,7 +626,6 @@ void StatusBar::updateSubwidgetsVisibility()
|
||||
{
|
||||
const Document* document = UIContext::instance()->activeDocument();
|
||||
bool commandsVisible = (document != NULL && hasMouse());
|
||||
bool notificationsVisible = (document == NULL);
|
||||
|
||||
if (commandsVisible) {
|
||||
if (!hasChild(m_commandsBox)) {
|
||||
@ -664,19 +639,6 @@ void StatusBar::updateSubwidgetsVisibility()
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
if (notificationsVisible) {
|
||||
if (!hasChild(m_notificationsBox)) {
|
||||
addChild(m_notificationsBox);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hasChild(m_notificationsBox)) {
|
||||
removeChild(m_notificationsBox);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -109,10 +109,6 @@ namespace app {
|
||||
ui::Button* m_b_next; // Go to next frame
|
||||
ui::Button* m_b_last; // Go to last frame
|
||||
|
||||
// Box of notifications.
|
||||
ui::Widget* m_notificationsBox;
|
||||
ui::LinkLabel* m_linkLabel;
|
||||
|
||||
// Tip window
|
||||
class CustomizedTipWindow;
|
||||
CustomizedTipWindow* m_tipwindow;
|
||||
|
@ -22,8 +22,10 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
StyledButton::StyledButton(const std::string& styleName) : Button("") {
|
||||
m_style = skin::get_style(styleName);
|
||||
StyledButton::StyledButton(skin::Style* style)
|
||||
: Button("")
|
||||
, m_style(style)
|
||||
{
|
||||
}
|
||||
|
||||
bool StyledButton::onProcessMessage(Message* msg) {
|
||||
|
@ -19,7 +19,7 @@ namespace app {
|
||||
|
||||
class StyledButton : public ui::Button {
|
||||
public:
|
||||
StyledButton(const std::string& styleName);
|
||||
StyledButton(skin::Style* style);
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,11 @@ namespace ui {
|
||||
namespace app {
|
||||
class Tabs;
|
||||
|
||||
enum class TabIcon {
|
||||
NONE,
|
||||
HOME,
|
||||
};
|
||||
|
||||
// Required interface to be implemented by each new tab that is added
|
||||
// in the Tabs widget.
|
||||
class TabView {
|
||||
@ -30,6 +35,9 @@ namespace app {
|
||||
|
||||
// Returns the text to be shown in the tab.
|
||||
virtual std::string getTabText() = 0;
|
||||
|
||||
// Returns the icon to be shown in the tab
|
||||
virtual TabIcon getTabIcon() = 0;
|
||||
};
|
||||
|
||||
// Interface used to control notifications from the Tabs widget.
|
||||
@ -37,12 +45,20 @@ namespace app {
|
||||
public:
|
||||
virtual ~TabsDelegate() { }
|
||||
|
||||
// Called when the user presses a mouse button over a tab.
|
||||
virtual void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons) = 0;
|
||||
// Called when the user selected the tab with the left mouse button.
|
||||
virtual void onSelectTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
// When the tab close button is pressed (or middle mouse button is used to close it).
|
||||
virtual void onCloseTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
// When the right-click is pressed in the tab.
|
||||
virtual void onContextMenuTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
// Called when the mouse is over a tab (the data can be null if the
|
||||
// mouse just leave all tabs)
|
||||
virtual void mouseOverTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
virtual void onMouseOverTab(Tabs* tabs, TabView* tabView) = 0;
|
||||
|
||||
virtual bool onIsModified(Tabs* tabs, TabView* tabView) = 0;
|
||||
};
|
||||
|
||||
// Tabs control. Used to show opened documents.
|
||||
@ -50,9 +66,12 @@ namespace app {
|
||||
struct Tab {
|
||||
TabView* view;
|
||||
std::string text;
|
||||
int width;
|
||||
TabIcon icon;
|
||||
int x, width;
|
||||
int oldX, oldWidth;
|
||||
bool modified;
|
||||
|
||||
Tab(TabView* view) : view(view), width(0) {
|
||||
Tab(TabView* view) : view(view) {
|
||||
}
|
||||
};
|
||||
|
||||
@ -62,8 +81,7 @@ namespace app {
|
||||
enum Ani { ANI_NONE,
|
||||
ANI_ADDING_TAB,
|
||||
ANI_REMOVING_TAB,
|
||||
ANI_SCROLL,
|
||||
ANI_SMOOTH_SCROLL };
|
||||
ANI_REORDER_TABS };
|
||||
|
||||
public:
|
||||
Tabs(TabsDelegate* delegate);
|
||||
@ -71,59 +89,59 @@ namespace app {
|
||||
|
||||
void addTab(TabView* tabView);
|
||||
void removeTab(TabView* tabView);
|
||||
void updateTabsText();
|
||||
void updateTabs();
|
||||
|
||||
void selectTab(TabView* tabView);
|
||||
void selectNextTab();
|
||||
void selectPreviousTab();
|
||||
TabView* getSelectedTab();
|
||||
|
||||
void startScrolling();
|
||||
void stopScrolling();
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPreferredSize(ui::PreferredSizeEvent& ev) override;
|
||||
void onInitTheme(ui::InitThemeEvent& ev) override;
|
||||
void onSetText() override;
|
||||
|
||||
private:
|
||||
void startAni(Ani ani);
|
||||
void resetOldPositions();
|
||||
void resetOldPositions(double t);
|
||||
void startAni(Ani ani, int T);
|
||||
void stopAni();
|
||||
|
||||
void selectTabInternal(Tab* tab);
|
||||
void drawTab(ui::Graphics* g, const gfx::Rect& box, Tab* tab, int y_delta, bool selected);
|
||||
void drawTab(ui::Graphics* g, const gfx::Rect& box, Tab* tab, int dy, bool hover, bool selected);
|
||||
void drawFiller(ui::Graphics* g, const gfx::Rect& box);
|
||||
TabsListIterator getTabIteratorByView(TabView* tabView);
|
||||
Tab* getTabByView(TabView* tabView);
|
||||
int getMaxScrollX();
|
||||
void makeTabVisible(Tab* tab);
|
||||
void setScrollX(int scroll_x);
|
||||
void calculateHot();
|
||||
void calcTabWidth(Tab* tab);
|
||||
gfx::Rect getTabCloseButtonBounds(Tab* tab, const gfx::Rect& box);
|
||||
void startDrag();
|
||||
void stopDrag();
|
||||
|
||||
TabsList m_list_of_tabs;
|
||||
int m_border;
|
||||
TabsList m_list;
|
||||
Tab* m_hot;
|
||||
bool m_hotCloseButton;
|
||||
bool m_clickedCloseButton;
|
||||
Tab* m_selected;
|
||||
int m_scrollX;
|
||||
|
||||
// Delegate of notifications
|
||||
TabsDelegate* m_delegate;
|
||||
|
||||
// Variables for animation purposes
|
||||
ui::Timer m_timer;
|
||||
int m_begScrollX; // Initial X position of scroll in the animation when you scroll with mouse wheel
|
||||
int m_endScrollX; // Final X position of scroll in the animation when you scroll with mouse wheel
|
||||
Ani m_ani; // Current animation
|
||||
int m_ani_t; // Number of ticks from the beginning of the animation
|
||||
int m_ani_t; // Number of ticks from the beginning of the transition/animation
|
||||
int m_ani_T; // Number of ticks in total for the current transition/animation
|
||||
Tab* m_removedTab;
|
||||
Tab* m_nextTabOfTheRemovedOne;
|
||||
|
||||
// Buttons to scroll tabs (useful when there are more tabs than visible area)
|
||||
class ScrollButton;
|
||||
ScrollButton* m_button_left;
|
||||
ScrollButton* m_button_right;
|
||||
// Drag-and-drop
|
||||
bool m_isDragging;
|
||||
int m_dragTabX;
|
||||
gfx::Point m_dragMousePos;
|
||||
int m_dragTabIndex;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "app/ui/document_view.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/skin/style.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/clipboard.h"
|
||||
@ -73,38 +74,6 @@ using namespace gfx;
|
||||
using namespace doc;
|
||||
using namespace ui;
|
||||
|
||||
static const char* kTimeline = "timeline";
|
||||
static const char* kTimelineBox = "timeline_box";
|
||||
static const char* kTimelineOpenEye = "timeline_open_eye";
|
||||
static const char* kTimelineClosedEye = "timeline_closed_eye";
|
||||
static const char* kTimelineOpenPadlock = "timeline_open_padlock";
|
||||
static const char* kTimelineClosedPadlock = "timeline_closed_padlock";
|
||||
static const char* kTimelineContinuous = "timeline_continuous";
|
||||
static const char* kTimelineDiscontinuous = "timeline_discontinuous";
|
||||
static const char* kTimelineLayer = "timeline_layer";
|
||||
static const char* kTimelineEmptyFrame = "timeline_empty_frame";
|
||||
static const char* kTimelineKeyframe = "timeline_keyframe";
|
||||
static const char* kTimelineFromLeft = "timeline_fromleft";
|
||||
static const char* kTimelineFromRight = "timeline_fromright";
|
||||
static const char* kTimelineFromBoth = "timeline_fromboth";
|
||||
static const char* kTimelineLeftLink = "timeline_leftlink";
|
||||
static const char* kTimelineRightLink = "timeline_rightlink";
|
||||
static const char* kTimelineBothLinks = "timeline_bothlinks";
|
||||
static const char* kTimelineGear = "timeline_gear";
|
||||
static const char* kTimelineOnionskin = "timeline_onionskin";
|
||||
static const char* kTimelineOnionskinRange = "timeline_onionskin_range";
|
||||
static const char* kTimelinePadding = "timeline_padding";
|
||||
static const char* kTimelinePaddingTr = "timeline_padding_tr";
|
||||
static const char* kTimelinePaddingBl = "timeline_padding_bl";
|
||||
static const char* kTimelinePaddingBr = "timeline_padding_br";
|
||||
static const char* kTimelineSelectedCelStyle = "timeline_selected_cel";
|
||||
static const char* kTimelineRangeOutlineStyle = "timeline_range_outline";
|
||||
static const char* kTimelineDropLayerDecoStyle = "timeline_drop_layer_deco";
|
||||
static const char* kTimelineDropFrameDecoStyle = "timeline_drop_frame_deco";
|
||||
static const char* kTimelineLoopRangeStyle = "timeline_loop_range";
|
||||
|
||||
static const char* kTimelineActiveColor = "timeline_active";
|
||||
|
||||
enum {
|
||||
A_PART_NOTHING,
|
||||
A_PART_SEPARATOR,
|
||||
@ -128,35 +97,6 @@ enum {
|
||||
|
||||
Timeline::Timeline()
|
||||
: Widget(kGenericWidget)
|
||||
, m_timelineStyle(get_style(kTimeline))
|
||||
, m_timelineBoxStyle(get_style(kTimelineBox))
|
||||
, m_timelineOpenEyeStyle(get_style(kTimelineOpenEye))
|
||||
, m_timelineClosedEyeStyle(get_style(kTimelineClosedEye))
|
||||
, m_timelineOpenPadlockStyle(get_style(kTimelineOpenPadlock))
|
||||
, m_timelineClosedPadlockStyle(get_style(kTimelineClosedPadlock))
|
||||
, m_timelineContinuousStyle(get_style(kTimelineContinuous))
|
||||
, m_timelineDiscontinuousStyle(get_style(kTimelineDiscontinuous))
|
||||
, m_timelineLayerStyle(get_style(kTimelineLayer))
|
||||
, m_timelineEmptyFrameStyle(get_style(kTimelineEmptyFrame))
|
||||
, m_timelineKeyframeStyle(get_style(kTimelineKeyframe))
|
||||
, m_timelineFromLeftStyle(get_style(kTimelineFromLeft))
|
||||
, m_timelineFromRightStyle(get_style(kTimelineFromRight))
|
||||
, m_timelineFromBothStyle(get_style(kTimelineFromBoth))
|
||||
, m_timelineLeftLinkStyle(get_style(kTimelineLeftLink))
|
||||
, m_timelineRightLinkStyle(get_style(kTimelineRightLink))
|
||||
, m_timelineBothLinksStyle(get_style(kTimelineBothLinks))
|
||||
, m_timelineGearStyle(get_style(kTimelineGear))
|
||||
, m_timelineOnionskinStyle(get_style(kTimelineOnionskin))
|
||||
, m_timelineOnionskinRangeStyle(get_style(kTimelineOnionskinRange))
|
||||
, m_timelinePaddingStyle(get_style(kTimelinePadding))
|
||||
, m_timelinePaddingTrStyle(get_style(kTimelinePaddingTr))
|
||||
, m_timelinePaddingBlStyle(get_style(kTimelinePaddingBl))
|
||||
, m_timelinePaddingBrStyle(get_style(kTimelinePaddingBr))
|
||||
, m_timelineSelectedCelStyle(get_style(kTimelineSelectedCelStyle))
|
||||
, m_timelineRangeOutlineStyle(get_style(kTimelineRangeOutlineStyle))
|
||||
, m_timelineDropLayerDecoStyle(get_style(kTimelineDropLayerDecoStyle))
|
||||
, m_timelineDropFrameDecoStyle(get_style(kTimelineDropFrameDecoStyle))
|
||||
, m_timelineLoopRangeStyle(get_style(kTimelineLoopRangeStyle))
|
||||
, m_context(UIContext::instance())
|
||||
, m_editor(NULL)
|
||||
, m_document(NULL)
|
||||
@ -832,7 +772,7 @@ void Timeline::onPaint(ui::PaintEvent& ev)
|
||||
gfx::Rect bounds = getOnionskinFramesBounds();
|
||||
if (!bounds.isEmpty()) {
|
||||
drawPart(g, bounds,
|
||||
NULL, m_timelineOnionskinRangeStyle,
|
||||
NULL, skinTheme()->styles.timelineOnionskinRange(),
|
||||
false, false, false);
|
||||
}
|
||||
}
|
||||
@ -889,7 +829,8 @@ void Timeline::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
paintNoDoc:;
|
||||
if (noDoc)
|
||||
drawPart(g, getClientBounds(), NULL, m_timelinePaddingStyle);
|
||||
drawPart(g, getClientBounds(), NULL,
|
||||
skinTheme()->styles.timelinePadding());
|
||||
}
|
||||
|
||||
void Timeline::onAfterCommandExecution(Command* command)
|
||||
@ -1098,46 +1039,47 @@ void Timeline::drawClipboardRange(ui::Graphics* g)
|
||||
|
||||
void Timeline::drawHeader(ui::Graphics* g)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
bool allInvisible = allLayersInvisible();
|
||||
bool allLocked = allLayersLocked();
|
||||
bool allContinuous = allLayersContinuous();
|
||||
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_EYE),
|
||||
NULL,
|
||||
allInvisible ? m_timelineClosedEyeStyle: m_timelineOpenEyeStyle,
|
||||
allInvisible ? styles.timelineClosedEye(): styles.timelineOpenEye(),
|
||||
m_clk_part == A_PART_HEADER_EYE,
|
||||
m_hot_part == A_PART_HEADER_EYE,
|
||||
m_clk_part == A_PART_HEADER_EYE);
|
||||
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_PADLOCK),
|
||||
NULL,
|
||||
allLocked ? m_timelineClosedPadlockStyle: m_timelineOpenPadlockStyle,
|
||||
allLocked ? styles.timelineClosedPadlock(): styles.timelineOpenPadlock(),
|
||||
m_clk_part == A_PART_HEADER_PADLOCK,
|
||||
m_hot_part == A_PART_HEADER_PADLOCK,
|
||||
m_clk_part == A_PART_HEADER_PADLOCK);
|
||||
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_CONTINUOUS),
|
||||
NULL,
|
||||
allContinuous ? m_timelineContinuousStyle: m_timelineDiscontinuousStyle,
|
||||
allContinuous ? styles.timelineContinuous(): styles.timelineDiscontinuous(),
|
||||
m_clk_part == A_PART_HEADER_CONTINUOUS,
|
||||
m_hot_part == A_PART_HEADER_CONTINUOUS,
|
||||
m_clk_part == A_PART_HEADER_CONTINUOUS);
|
||||
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_GEAR),
|
||||
NULL, m_timelineGearStyle,
|
||||
NULL, styles.timelineGear(),
|
||||
false,
|
||||
m_hot_part == A_PART_HEADER_GEAR,
|
||||
m_clk_part == A_PART_HEADER_GEAR);
|
||||
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_ONIONSKIN),
|
||||
NULL, m_timelineOnionskinStyle,
|
||||
NULL, styles.timelineOnionskin(),
|
||||
docPref().onionskin.active(),
|
||||
m_hot_part == A_PART_HEADER_ONIONSKIN,
|
||||
m_clk_part == A_PART_HEADER_ONIONSKIN);
|
||||
|
||||
// Empty header space.
|
||||
drawPart(g, getPartBounds(A_PART_HEADER_LAYER),
|
||||
NULL, m_timelineBoxStyle, false, false, false);
|
||||
NULL, styles.timelineBox(), false, false, false);
|
||||
}
|
||||
|
||||
void Timeline::drawHeaderFrame(ui::Graphics* g, frame_t frame)
|
||||
@ -1155,13 +1097,14 @@ void Timeline::drawHeaderFrame(ui::Graphics* g, frame_t frame)
|
||||
std::sprintf(buf, "%d", (frame+1)%100); // Draw only the first two digits.
|
||||
|
||||
she::Font* oldFont = g->getFont();
|
||||
g->setFont(((SkinTheme*)getTheme())->getMiniFont());
|
||||
drawPart(g, bounds, buf, m_timelineBoxStyle, is_active, is_hover, is_clicked);
|
||||
g->setFont(skinTheme()->getMiniFont());
|
||||
drawPart(g, bounds, buf, skinTheme()->styles.timelineBox(), is_active, is_hover, is_clicked);
|
||||
g->setFont(oldFont);
|
||||
}
|
||||
|
||||
void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
Layer* layer = m_layers[layerIdx];
|
||||
bool is_active = isLayerActive(layerIdx);
|
||||
bool hotlayer = (m_hot_layer == layerIdx);
|
||||
@ -1174,7 +1117,7 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
|
||||
// Draw the eye (visible flag).
|
||||
bounds = getPartBounds(A_PART_LAYER_EYE_ICON, layerIdx);
|
||||
drawPart(g, bounds, NULL,
|
||||
layer->isVisible() ? m_timelineOpenEyeStyle: m_timelineClosedEyeStyle,
|
||||
layer->isVisible() ? styles.timelineOpenEye(): styles.timelineClosedEye(),
|
||||
is_active,
|
||||
(hotlayer && m_hot_part == A_PART_LAYER_EYE_ICON),
|
||||
(clklayer && m_clk_part == A_PART_LAYER_EYE_ICON));
|
||||
@ -1182,7 +1125,7 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
|
||||
// Draw the padlock (editable flag).
|
||||
bounds = getPartBounds(A_PART_LAYER_PADLOCK_ICON, layerIdx);
|
||||
drawPart(g, bounds, NULL,
|
||||
layer->isEditable() ? m_timelineOpenPadlockStyle: m_timelineClosedPadlockStyle,
|
||||
layer->isEditable() ? styles.timelineOpenPadlock(): styles.timelineClosedPadlock(),
|
||||
is_active,
|
||||
(hotlayer && m_hot_part == A_PART_LAYER_PADLOCK_ICON),
|
||||
(clklayer && m_clk_part == A_PART_LAYER_PADLOCK_ICON));
|
||||
@ -1190,14 +1133,14 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
|
||||
// Draw the continuous flag.
|
||||
bounds = getPartBounds(A_PART_LAYER_CONTINUOUS_ICON, layerIdx);
|
||||
drawPart(g, bounds, NULL,
|
||||
layer->isContinuous() ? m_timelineContinuousStyle: m_timelineDiscontinuousStyle,
|
||||
layer->isContinuous() ? styles.timelineContinuous(): styles.timelineDiscontinuous(),
|
||||
is_active,
|
||||
(hotlayer && m_hot_part == A_PART_LAYER_CONTINUOUS_ICON),
|
||||
(clklayer && m_clk_part == A_PART_LAYER_CONTINUOUS_ICON));
|
||||
|
||||
// Draw the layer's name.
|
||||
bounds = getPartBounds(A_PART_LAYER_TEXT, layerIdx);
|
||||
drawPart(g, bounds, layer->name().c_str(), m_timelineLayerStyle,
|
||||
drawPart(g, bounds, layer->name().c_str(), styles.timelineLayer(),
|
||||
is_active,
|
||||
(hotlayer && m_hot_part == A_PART_LAYER_TEXT),
|
||||
(clklayer && m_clk_part == A_PART_LAYER_TEXT));
|
||||
@ -1207,13 +1150,15 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
|
||||
// layers.
|
||||
if (hotlayer && !is_active && m_clk_part == A_PART_LAYER_TEXT) {
|
||||
// TODO this should be skinneable
|
||||
g->fillRect(get_color_by_id(kTimelineActiveColor),
|
||||
gfx::Rect(bounds.x, bounds.y, bounds.w, 2));
|
||||
g->fillRect(
|
||||
skinTheme()->colors.timelineActive(),
|
||||
gfx::Rect(bounds.x, bounds.y, bounds.w, 2));
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::drawCel(ui::Graphics* g, LayerIndex layerIndex, frame_t frame, Cel* cel)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
Layer* layer = m_layers[layerIndex];
|
||||
Image* image = (cel ? cel->image(): NULL);
|
||||
bool is_hover = (m_hot_part == A_PART_CEL &&
|
||||
@ -1227,15 +1172,15 @@ void Timeline::drawCel(ui::Graphics* g, LayerIndex layerIndex, frame_t frame, Ce
|
||||
return;
|
||||
|
||||
if (layer == m_layer && frame == m_frame)
|
||||
drawPart(g, bounds, NULL, m_timelineSelectedCelStyle, false, false, true);
|
||||
drawPart(g, bounds, NULL, styles.timelineSelectedCel(), false, false, true);
|
||||
else
|
||||
drawPart(g, bounds, NULL, m_timelineBoxStyle, is_active, is_hover);
|
||||
drawPart(g, bounds, NULL, styles.timelineBox(), is_active, is_hover);
|
||||
|
||||
skin::Style* style;
|
||||
bool fromLeft = false;
|
||||
bool fromRight = false;
|
||||
if (is_empty) {
|
||||
style = m_timelineEmptyFrameStyle;
|
||||
style = styles.timelineEmptyFrame();
|
||||
}
|
||||
else {
|
||||
Cel* left = (layer->isImage() ? layer->cel(frame-1): NULL);
|
||||
@ -1246,13 +1191,13 @@ void Timeline::drawCel(ui::Graphics* g, LayerIndex layerIndex, frame_t frame, Ce
|
||||
fromRight = (rightImg == cel->image()->id());
|
||||
|
||||
if (fromLeft && fromRight)
|
||||
style = m_timelineFromBothStyle;
|
||||
style = styles.timelineFromBoth();
|
||||
else if (fromLeft)
|
||||
style = m_timelineFromLeftStyle;
|
||||
style = styles.timelineFromLeft();
|
||||
else if (fromRight)
|
||||
style = m_timelineFromRightStyle;
|
||||
style = styles.timelineFromRight();
|
||||
else
|
||||
style = m_timelineKeyframeStyle;
|
||||
style = styles.timelineKeyframe();
|
||||
}
|
||||
drawPart(g, bounds, NULL, style, is_active, is_hover);
|
||||
|
||||
@ -1267,6 +1212,7 @@ void Timeline::drawCel(ui::Graphics* g, LayerIndex layerIndex, frame_t frame, Ce
|
||||
void Timeline::drawCelLinkDecorators(ui::Graphics* g, const gfx::Rect& bounds,
|
||||
Cel* cel, Cel* activeCel, frame_t frame, bool is_active, bool is_hover)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
ObjectId imageId = activeCel->image()->id();
|
||||
|
||||
// Link in some cel at the left side
|
||||
@ -1291,18 +1237,18 @@ void Timeline::drawCelLinkDecorators(ui::Graphics* g, const gfx::Rect& bounds,
|
||||
|
||||
if (!cel || cel->image()->id() != imageId) {
|
||||
if (left && right)
|
||||
drawPart(g, bounds, NULL, m_timelineBothLinksStyle, is_active, is_hover);
|
||||
drawPart(g, bounds, NULL, styles.timelineBothLinks(), is_active, is_hover);
|
||||
}
|
||||
else {
|
||||
if (left) {
|
||||
Cel* prevCel = m_layer->cel(cel->frame()-1);
|
||||
if (!prevCel || prevCel->image()->id() != imageId)
|
||||
drawPart(g, bounds, NULL, m_timelineLeftLinkStyle, is_active, is_hover);
|
||||
drawPart(g, bounds, NULL, styles.timelineLeftLink(), is_active, is_hover);
|
||||
}
|
||||
if (right) {
|
||||
Cel* nextCel = m_layer->cel(cel->frame()+1);
|
||||
if (!nextCel || nextCel->image()->id() != imageId)
|
||||
drawPart(g, bounds, NULL, m_timelineRightLinkStyle, is_active, is_hover);
|
||||
drawPart(g, bounds, NULL, styles.timelineRightLink(), is_active, is_hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1326,11 +1272,14 @@ void Timeline::drawLoopRange(ui::Graphics* g)
|
||||
if (!clip)
|
||||
return;
|
||||
|
||||
drawPart(g, bounds, NULL, m_timelineLoopRangeStyle);
|
||||
drawPart(g, bounds, NULL,
|
||||
skinTheme()->styles.timelineLoopRange());
|
||||
}
|
||||
|
||||
void Timeline::drawFrameTags(ui::Graphics* g)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
|
||||
for (FrameTag* frameTag : m_sprite->frameTags()) {
|
||||
gfx::Rect bounds1 = getPartBounds(A_PART_HEADER_FRAME, firstLayer(), frameTag->fromFrame());
|
||||
gfx::Rect bounds2 = getPartBounds(A_PART_HEADER_FRAME, firstLayer(), frameTag->toFrame());
|
||||
@ -1338,13 +1287,15 @@ void Timeline::drawFrameTags(ui::Graphics* g)
|
||||
|
||||
IntersectClip clip(g, bounds);
|
||||
if (clip) {
|
||||
drawPart(g, bounds, NULL, m_timelineLoopRangeStyle);
|
||||
drawPart(g, bounds, NULL, styles.timelineLoopRange());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
|
||||
gfx::Rect clipBounds;
|
||||
switch (m_range.type()) {
|
||||
case Range::kCels: clipBounds = getCelsBounds(); break;
|
||||
@ -1360,7 +1311,7 @@ void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
if (m_hot_part == A_PART_RANGE_OUTLINE) state += Style::hover();
|
||||
|
||||
gfx::Rect bounds = getPartBounds(A_PART_RANGE_OUTLINE);
|
||||
m_timelineRangeOutlineStyle->paint(g, bounds, NULL, state);
|
||||
styles.timelineRangeOutline()->paint(g, bounds, NULL, state);
|
||||
|
||||
Range drop = m_dropRange;
|
||||
gfx::Rect dropBounds = getRangeBounds(drop);
|
||||
@ -1369,7 +1320,7 @@ void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
|
||||
case Range::kCels: {
|
||||
dropBounds = dropBounds.enlarge(OUTLINE_WIDTH);
|
||||
m_timelineRangeOutlineStyle->paint(g, dropBounds, NULL, Style::active());
|
||||
styles.timelineRangeOutline()->paint(g, dropBounds, NULL, Style::active());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1385,7 +1336,7 @@ void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
|
||||
dropBounds.w = w;
|
||||
|
||||
m_timelineDropFrameDecoStyle->paint(g, dropBounds, NULL, Style::State());
|
||||
styles.timelineDropFrameDeco()->paint(g, dropBounds, NULL, Style::State());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1401,7 +1352,7 @@ void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
|
||||
dropBounds.h = h;
|
||||
|
||||
m_timelineDropLayerDecoStyle->paint(g, dropBounds, NULL, Style::State());
|
||||
styles.timelineDropLayerDeco()->paint(g, dropBounds, NULL, Style::State());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1409,6 +1360,8 @@ void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||
|
||||
void Timeline::drawPaddings(ui::Graphics* g)
|
||||
{
|
||||
SkinTheme::Styles& styles = skinTheme()->styles;
|
||||
|
||||
gfx::Rect client = getClientBounds();
|
||||
gfx::Rect bottomLayer;
|
||||
gfx::Rect lastFrame;
|
||||
@ -1426,18 +1379,18 @@ void Timeline::drawPaddings(ui::Graphics* g)
|
||||
gfx::Rect(lastFrame.x+lastFrame.w, client.y,
|
||||
client.w - (lastFrame.x+lastFrame.w),
|
||||
bottomLayer.y+bottomLayer.h),
|
||||
NULL, m_timelinePaddingTrStyle);
|
||||
NULL, styles.timelinePaddingTr());
|
||||
|
||||
drawPart(g,
|
||||
gfx::Rect(client.x, bottomLayer.y+bottomLayer.h,
|
||||
lastFrame.x+lastFrame.w - client.x, client.h - (bottomLayer.y+bottomLayer.h)),
|
||||
NULL, m_timelinePaddingBlStyle);
|
||||
NULL, styles.timelinePaddingBl());
|
||||
|
||||
drawPart(g,
|
||||
gfx::Rect(lastFrame.x+lastFrame.w, bottomLayer.y+bottomLayer.h,
|
||||
client.w - (lastFrame.x+lastFrame.w),
|
||||
client.h - (bottomLayer.y+bottomLayer.h)),
|
||||
NULL, m_timelinePaddingBrStyle);
|
||||
NULL, styles.timelinePaddingBr());
|
||||
}
|
||||
|
||||
gfx::Rect Timeline::getLayerHeadersBounds() const
|
||||
@ -2210,4 +2163,9 @@ DocumentPreferences& Timeline::docPref() const
|
||||
return App::instance()->preferences().document(m_document);
|
||||
}
|
||||
|
||||
skin::SkinTheme* Timeline::skinTheme() const
|
||||
{
|
||||
return static_cast<SkinTheme*>(getTheme());
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "app/document_range.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/editor/editor_observer.h"
|
||||
#include "app/ui/skin/style.h"
|
||||
#include "base/connection.h"
|
||||
#include "doc/document_observer.h"
|
||||
#include "doc/documents_observer.h"
|
||||
@ -36,6 +35,12 @@ namespace ui {
|
||||
}
|
||||
|
||||
namespace app {
|
||||
|
||||
namespace skin {
|
||||
class Style;
|
||||
class SkinTheme;
|
||||
}
|
||||
|
||||
using namespace doc;
|
||||
|
||||
class Command;
|
||||
@ -191,36 +196,8 @@ namespace app {
|
||||
bool validFrame(frame_t frame) const { return frame >= firstFrame() && frame <= lastFrame(); }
|
||||
|
||||
DocumentPreferences& docPref() const;
|
||||
skin::SkinTheme* skinTheme() const;
|
||||
|
||||
skin::Style* m_timelineStyle;
|
||||
skin::Style* m_timelineBoxStyle;
|
||||
skin::Style* m_timelineOpenEyeStyle;
|
||||
skin::Style* m_timelineClosedEyeStyle;
|
||||
skin::Style* m_timelineOpenPadlockStyle;
|
||||
skin::Style* m_timelineClosedPadlockStyle;
|
||||
skin::Style* m_timelineContinuousStyle;
|
||||
skin::Style* m_timelineDiscontinuousStyle;
|
||||
skin::Style* m_timelineLayerStyle;
|
||||
skin::Style* m_timelineEmptyFrameStyle;
|
||||
skin::Style* m_timelineKeyframeStyle;
|
||||
skin::Style* m_timelineFromLeftStyle;
|
||||
skin::Style* m_timelineFromRightStyle;
|
||||
skin::Style* m_timelineFromBothStyle;
|
||||
skin::Style* m_timelineLeftLinkStyle;
|
||||
skin::Style* m_timelineRightLinkStyle;
|
||||
skin::Style* m_timelineBothLinksStyle;
|
||||
skin::Style* m_timelineGearStyle;
|
||||
skin::Style* m_timelineOnionskinStyle;
|
||||
skin::Style* m_timelineOnionskinRangeStyle;
|
||||
skin::Style* m_timelinePaddingStyle;
|
||||
skin::Style* m_timelinePaddingTrStyle;
|
||||
skin::Style* m_timelinePaddingBlStyle;
|
||||
skin::Style* m_timelinePaddingBrStyle;
|
||||
skin::Style* m_timelineSelectedCelStyle;
|
||||
skin::Style* m_timelineRangeOutlineStyle;
|
||||
skin::Style* m_timelineDropLayerDecoStyle;
|
||||
skin::Style* m_timelineDropFrameDecoStyle;
|
||||
skin::Style* m_timelineLoopRangeStyle;
|
||||
Context* m_context;
|
||||
Editor* m_editor;
|
||||
Document* m_document;
|
||||
|
@ -306,14 +306,14 @@ void ToolBar::onPaint(ui::PaintEvent& ev)
|
||||
gfx::Rect bounds = getClientBounds();
|
||||
Graphics* g = ev.getGraphics();
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
gfx::Color normalFace = theme->getColor(ThemeColor::ButtonNormalFace);
|
||||
gfx::Color hotFace = theme->getColor(ThemeColor::ButtonHotFace);
|
||||
gfx::Color normalFace = theme->colors.buttonNormalFace();
|
||||
gfx::Color hotFace = theme->colors.buttonHotFace();
|
||||
ToolBox* toolbox = App::instance()->getToolBox();
|
||||
ToolGroupList::iterator it = toolbox->begin_group();
|
||||
int groups = toolbox->getGroupsCount();
|
||||
Rect toolrc;
|
||||
|
||||
g->fillRect(theme->getColor(ThemeColor::TabSelectedFace), bounds);
|
||||
g->fillRect(theme->colors.tabActiveFace(), bounds);
|
||||
|
||||
for (int c=0; c<groups; ++c, ++it) {
|
||||
ToolGroup* tool_group = *it;
|
||||
@ -733,11 +733,11 @@ void ToolBar::ToolStrip::onPaint(PaintEvent& ev)
|
||||
if (UIContext::instance()->settings()->getCurrentTool() == tool ||
|
||||
m_hotTool == tool) {
|
||||
nw = PART_TOOLBUTTON_HOT_NW;
|
||||
face = theme->getColor(ThemeColor::ButtonHotFace);
|
||||
face = theme->colors.buttonHotFace();
|
||||
}
|
||||
else {
|
||||
nw = PART_TOOLBUTTON_LAST_NW;
|
||||
face = theme->getColor(ThemeColor::ButtonNormalFace);
|
||||
face = theme->colors.buttonNormalFace();
|
||||
}
|
||||
|
||||
toolrc = getToolBounds(index++);
|
||||
|
@ -13,11 +13,10 @@
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_part.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "ui/splitter.h"
|
||||
#include "app/ui/tabs.h"
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "base/remove_from_container.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <queue>
|
||||
@ -28,13 +27,11 @@ using namespace app::skin;
|
||||
using namespace ui;
|
||||
|
||||
Workspace::Workspace()
|
||||
: Box(JI_VERTICAL)
|
||||
, m_activePart(new WorkspacePart)
|
||||
: Widget(kGenericWidget)
|
||||
, m_activeView(nullptr)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->getColor(ThemeColor::Workspace));
|
||||
|
||||
addChild(m_activePart);
|
||||
setBgColor(theme->colors.workspace());
|
||||
}
|
||||
|
||||
Workspace::~Workspace()
|
||||
@ -47,198 +44,52 @@ void Workspace::addView(WorkspaceView* view)
|
||||
{
|
||||
m_views.push_back(view);
|
||||
|
||||
m_activePart->addView(view);
|
||||
|
||||
App::instance()->getMainWindow()->getTabsBar()->addTab(dynamic_cast<TabView*>(view));
|
||||
|
||||
ActiveViewChanged(); // Fire ActiveViewChanged event
|
||||
setActiveView(view);
|
||||
}
|
||||
|
||||
void Workspace::removeView(WorkspaceView* view)
|
||||
{
|
||||
WorkspaceViews::iterator it = std::find(m_views.begin(), m_views.end(), view);
|
||||
ASSERT(it != m_views.end());
|
||||
m_views.erase(it);
|
||||
base::remove_from_container(m_views, view);
|
||||
|
||||
WorkspacePart* part = getPartByView(view);
|
||||
ASSERT(part != NULL);
|
||||
Widget* content = view->getContentWidget();
|
||||
if (content->getParent())
|
||||
content->getParent()->removeChild(content);
|
||||
|
||||
part->removeView(view);
|
||||
if (part->getViewCount() == 0 &&
|
||||
part->getParent() != this) {
|
||||
bool activePartRemoved = (m_activePart == part);
|
||||
WorkspacePart* otherPart = destroyPart(part);
|
||||
// Remove related tab
|
||||
Tabs* tabs = App::instance()->getMainWindow()->getTabsBar();
|
||||
tabs->removeTab(dynamic_cast<TabView*>(view));
|
||||
|
||||
if (activePartRemoved)
|
||||
m_activePart = otherPart;
|
||||
}
|
||||
TabView* tabView = tabs->getSelectedTab();
|
||||
setActiveView(dynamic_cast<WorkspaceView*>(tabView));
|
||||
}
|
||||
|
||||
App::instance()->getMainWindow()->getTabsBar()->removeTab(dynamic_cast<TabView*>(view));
|
||||
|
||||
ActiveViewChanged(); // Fire ActiveViewChanged event
|
||||
bool Workspace::closeView(WorkspaceView* view)
|
||||
{
|
||||
return view->onCloseView(this);
|
||||
}
|
||||
|
||||
WorkspaceView* Workspace::activeView()
|
||||
{
|
||||
ASSERT(m_activePart != NULL);
|
||||
return m_activePart->activeView();
|
||||
return m_activeView;
|
||||
}
|
||||
|
||||
void Workspace::setActiveView(WorkspaceView* view)
|
||||
{
|
||||
ASSERT(view != NULL);
|
||||
m_activeView = view;
|
||||
|
||||
WorkspacePart* viewPart =
|
||||
static_cast<WorkspacePart*>(view->getContentWidget()->getParent());
|
||||
|
||||
viewPart->setActiveView(view);
|
||||
|
||||
m_activePart = viewPart;
|
||||
ActiveViewChanged(); // Fire ActiveViewChanged event
|
||||
}
|
||||
|
||||
void Workspace::splitView(WorkspaceView* view, int orientation)
|
||||
{
|
||||
// Try to clone the workspace view.
|
||||
WorkspaceView* newView = view->cloneWorkspaceView();
|
||||
if (newView == NULL)
|
||||
return;
|
||||
|
||||
// Get the part where the view-to-clone is located because we need
|
||||
// to split this part.
|
||||
WorkspacePart* viewPart =
|
||||
static_cast<WorkspacePart*>(view->getContentWidget()->getParent());
|
||||
|
||||
// Create a new splitter to add new WorkspacePart on it: the given
|
||||
// "viewPart" and a new part named "newPart".
|
||||
Splitter* splitter = new Splitter(Splitter::ByPercentage, orientation);
|
||||
splitter->setExpansive(true);
|
||||
|
||||
// Create the new part to contain the cloned view (see below, "newView").
|
||||
WorkspacePart* newPart = new WorkspacePart();
|
||||
|
||||
// Replace the "viewPart" with the "splitter".
|
||||
Widget* parent = viewPart->getParent();
|
||||
parent->replaceChild(viewPart, splitter);
|
||||
splitter->addChild(viewPart);
|
||||
splitter->addChild(newPart);
|
||||
|
||||
// The new part is the active one.
|
||||
m_activePart = newPart;
|
||||
|
||||
// Add the cloned view to the active part (newPart)
|
||||
// using Workspace::addView().
|
||||
addView(newView);
|
||||
setActiveView(newView);
|
||||
removeAllChildren();
|
||||
if (view)
|
||||
addChild(view->getContentWidget());
|
||||
|
||||
layout();
|
||||
|
||||
newView->onClonedFrom(view);
|
||||
|
||||
ActiveViewChanged(); // Fire ActiveViewChanged event
|
||||
}
|
||||
|
||||
WorkspacePart* Workspace::destroyPart(WorkspacePart* part)
|
||||
void Workspace::onPaint(PaintEvent& ev)
|
||||
{
|
||||
ASSERT(part != NULL);
|
||||
ASSERT(part->getViewCount() == 0);
|
||||
|
||||
Widget* splitter = part->getParent();
|
||||
ASSERT(splitter != this);
|
||||
ASSERT(splitter->getChildren().size() == 2);
|
||||
splitter->removeChild(part);
|
||||
delete part;
|
||||
ASSERT(splitter->getChildren().size() == 1);
|
||||
|
||||
Widget* otherWidget = splitter->getFirstChild();
|
||||
WorkspacePart* otherPart = dynamic_cast<WorkspacePart*>(otherWidget);
|
||||
if (otherPart == NULL) {
|
||||
Widget* widget = otherWidget;
|
||||
for (;;) {
|
||||
otherPart = widget->findFirstChildByType<WorkspacePart>();
|
||||
if (otherPart != NULL)
|
||||
break;
|
||||
|
||||
widget = widget->getFirstChild();
|
||||
}
|
||||
}
|
||||
ASSERT(otherPart != NULL);
|
||||
|
||||
splitter->removeChild(otherWidget);
|
||||
splitter->getParent()->replaceChild(splitter, otherWidget);
|
||||
delete splitter;
|
||||
|
||||
layout();
|
||||
|
||||
return otherPart;
|
||||
}
|
||||
|
||||
void Workspace::makeUnique(WorkspaceView* view)
|
||||
{
|
||||
WorkspaceParts parts;
|
||||
enumAllParts(parts);
|
||||
|
||||
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
|
||||
WorkspacePart* part = *it;
|
||||
if (part->getParent() != this) {
|
||||
while (part->activeView())
|
||||
part->removeView(part->activeView());
|
||||
}
|
||||
}
|
||||
|
||||
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
|
||||
WorkspacePart* part = *it;
|
||||
if (part->getParent() != this)
|
||||
destroyPart(part);
|
||||
}
|
||||
|
||||
WorkspacePart* uniquePart = dynamic_cast<WorkspacePart*>(getFirstChild());
|
||||
ASSERT(uniquePart != NULL);
|
||||
m_activePart = uniquePart;
|
||||
|
||||
for (WorkspaceViews::iterator it=m_views.begin(), end=m_views.end(); it != end; ++it) {
|
||||
WorkspaceView* v = *it;
|
||||
if (!v->getContentWidget()->getParent())
|
||||
uniquePart->addView(v);
|
||||
}
|
||||
|
||||
setActiveView(view);
|
||||
}
|
||||
|
||||
WorkspacePart* Workspace::getPartByView(WorkspaceView* view)
|
||||
{
|
||||
WorkspaceParts parts;
|
||||
enumAllParts(parts);
|
||||
|
||||
for (WorkspaceParts::iterator it=parts.begin(), end=parts.end(); it != end; ++it) {
|
||||
WorkspacePart* part = *it;
|
||||
if (part->hasView(view))
|
||||
return part;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Workspace::enumAllParts(WorkspaceParts& parts)
|
||||
{
|
||||
std::queue<Widget*> remaining;
|
||||
remaining.push(getFirstChild());
|
||||
while (!remaining.empty()) {
|
||||
Widget* widget = remaining.front();
|
||||
remaining.pop();
|
||||
|
||||
ASSERT(widget != NULL);
|
||||
|
||||
WorkspacePart* part = dynamic_cast<WorkspacePart*>(widget);
|
||||
if (part) {
|
||||
parts.push_back(part);
|
||||
}
|
||||
else {
|
||||
UI_FOREACH_WIDGET(widget->getChildren(), it) {
|
||||
remaining.push(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
ev.getGraphics()->fillRect(getBgColor(), getClientBounds());
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -11,13 +11,14 @@
|
||||
|
||||
#include "app/ui/workspace_views.h"
|
||||
#include "base/signal.h"
|
||||
#include "ui/box.h"
|
||||
#include "ui/widget.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
class WorkspacePart;
|
||||
|
||||
class Workspace : public ui::Box {
|
||||
class Workspace : public ui::Widget {
|
||||
public:
|
||||
typedef WorkspaceViews::iterator iterator;
|
||||
|
||||
@ -30,24 +31,21 @@ namespace app {
|
||||
void addView(WorkspaceView* view);
|
||||
void removeView(WorkspaceView* view);
|
||||
|
||||
// Closes the given view. Returns false if the user cancels the
|
||||
// operation.
|
||||
bool closeView(WorkspaceView* view);
|
||||
|
||||
WorkspaceView* activeView();
|
||||
void setActiveView(WorkspaceView* view);
|
||||
|
||||
void splitView(WorkspaceView* view, int orientation);
|
||||
void makeUnique(WorkspaceView* view);
|
||||
|
||||
Signal0<void> ActiveViewChanged;
|
||||
|
||||
protected:
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
|
||||
private:
|
||||
typedef std::vector<WorkspacePart*> WorkspaceParts;
|
||||
|
||||
WorkspacePart* destroyPart(WorkspacePart* part);
|
||||
WorkspacePart* getPartByView(WorkspaceView* view);
|
||||
void enumAllParts(WorkspaceParts& parts);
|
||||
|
||||
// All views of all parts.
|
||||
WorkspaceViews m_views;
|
||||
WorkspacePart* m_activePart;
|
||||
WorkspaceView* m_activeView;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -1,87 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/workspace_part.h"
|
||||
|
||||
#include "app/ui/workspace_view.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace app::skin;
|
||||
using namespace ui;
|
||||
|
||||
WorkspacePart::WorkspacePart()
|
||||
: Box(JI_VERTICAL)
|
||||
, m_activeView(NULL)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
|
||||
setBgColor(theme->getColor(ThemeColor::Workspace));
|
||||
|
||||
setExpansive(true);
|
||||
}
|
||||
|
||||
WorkspacePart::~WorkspacePart()
|
||||
{
|
||||
}
|
||||
|
||||
void WorkspacePart::addView(WorkspaceView* view)
|
||||
{
|
||||
m_views.push_back(view);
|
||||
|
||||
addChild(view->getContentWidget());
|
||||
|
||||
setActiveView(view);
|
||||
}
|
||||
|
||||
void WorkspacePart::removeView(WorkspaceView* view)
|
||||
{
|
||||
WorkspaceViews::iterator it = std::find(m_views.begin(), m_views.end(), view);
|
||||
ASSERT(it != m_views.end());
|
||||
it = m_views.erase(it);
|
||||
|
||||
removeChild(view->getContentWidget());
|
||||
|
||||
setActiveView((it != m_views.end() ?
|
||||
*it : (!m_views.empty() ? m_views.front(): NULL)));
|
||||
}
|
||||
|
||||
void WorkspacePart::setActiveView(WorkspaceView* view)
|
||||
{
|
||||
m_activeView = view;
|
||||
|
||||
Widget* newContent = (view ? view->getContentWidget(): NULL);
|
||||
WidgetsList children = getChildren();
|
||||
UI_FOREACH_WIDGET(children, it) {
|
||||
if ((*it) != newContent)
|
||||
(*it)->setVisible(false);
|
||||
}
|
||||
|
||||
if (newContent) {
|
||||
newContent->setExpansive(true);
|
||||
newContent->setVisible(true);
|
||||
newContent->requestFocus();
|
||||
}
|
||||
|
||||
if (m_activeView)
|
||||
m_activeView->onWorkspaceViewSelected();
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
bool WorkspacePart::hasView(WorkspaceView* view)
|
||||
{
|
||||
return (std::find(m_views.begin(), m_views.end(), view) != m_views.end());
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -1,40 +0,0 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_WORKSPACE_PART_H_INCLUDED
|
||||
#define APP_UI_WORKSPACE_PART_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/workspace_views.h"
|
||||
#include "ui/box.h"
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
|
||||
class WorkspacePart : public ui::Box {
|
||||
public:
|
||||
WorkspacePart();
|
||||
~WorkspacePart();
|
||||
|
||||
size_t getViewCount() { return m_views.size(); }
|
||||
|
||||
void addView(WorkspaceView* view);
|
||||
void removeView(WorkspaceView* view);
|
||||
|
||||
WorkspaceView* activeView() { return m_activeView; }
|
||||
void setActiveView(WorkspaceView* view);
|
||||
|
||||
bool hasView(WorkspaceView* view);
|
||||
|
||||
private:
|
||||
WorkspaceView* m_activeView;
|
||||
WorkspaceViews m_views;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -14,6 +14,7 @@ namespace ui {
|
||||
}
|
||||
|
||||
namespace app {
|
||||
class Workspace;
|
||||
|
||||
class WorkspaceView {
|
||||
public:
|
||||
@ -27,6 +28,12 @@ namespace app {
|
||||
// the workspace. It can be used to copy/clone scroll position
|
||||
// from the original view.
|
||||
virtual void onClonedFrom(WorkspaceView* from) = 0;
|
||||
|
||||
// Returns true if the view was closed successfully or false if
|
||||
// the user cancels the operation.
|
||||
virtual bool onCloseView(Workspace* workspace) = 0;
|
||||
|
||||
virtual void onTabPopup(Workspace* workspace) = 0;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
@ -127,7 +127,7 @@ DocumentView* UIContext::getFirstDocumentView(Document* document) const
|
||||
{
|
||||
Workspace* workspace = App::instance()->getMainWindow()->getWorkspace();
|
||||
|
||||
for (auto view : *workspace) {
|
||||
for (WorkspaceView* view : *workspace) {
|
||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
||||
if (docView->getDocument() == document) {
|
||||
return docView;
|
||||
@ -177,8 +177,7 @@ void UIContext::onRemoveDocument(doc::Document* doc)
|
||||
DocumentViews docViews;
|
||||
|
||||
// Collect all views related to the document.
|
||||
for (Workspace::iterator it=workspace->begin(); it != workspace->end(); ++it) {
|
||||
WorkspaceView* view = *it;
|
||||
for (WorkspaceView* view : *workspace) {
|
||||
if (DocumentView* docView = dynamic_cast<DocumentView*>(view)) {
|
||||
if (docView->getDocument() == doc) {
|
||||
docViews.push_back(docView);
|
||||
@ -186,8 +185,7 @@ void UIContext::onRemoveDocument(doc::Document* doc)
|
||||
}
|
||||
}
|
||||
|
||||
for (DocumentViews::iterator it=docViews.begin(); it != docViews.end(); ++it) {
|
||||
DocumentView* docView = *it;
|
||||
for (DocumentView* docView : docViews) {
|
||||
workspace->removeView(docView);
|
||||
delete docView;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "app/resource_finder.h"
|
||||
#include "app/ui/button_set.h"
|
||||
#include "app/ui/color_button.h"
|
||||
#include "app/ui/skin/skin_style_property.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/widget_not_found.h"
|
||||
#include "app/xml_document.h"
|
||||
@ -23,6 +24,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/memory.h"
|
||||
#include "she/system.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include "tinyxml.h"
|
||||
@ -429,6 +431,27 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (elem_name == "image") {
|
||||
if (!widget) {
|
||||
const char* file = elem->Attribute("file");
|
||||
|
||||
// Load image
|
||||
std::string icon(file);
|
||||
|
||||
ResourceFinder rf;
|
||||
rf.includeDataDir(file);
|
||||
if (!rf.findFirst())
|
||||
throw base::Exception("File %s not found", file);
|
||||
|
||||
try {
|
||||
she::Surface* sur = she::instance()->loadRgbaSurface(rf.filename().c_str());
|
||||
widget = new ImageView(sur, 0);
|
||||
}
|
||||
catch (...) {
|
||||
throw base::Exception("Error loading %s file", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Was the widget created?
|
||||
if (widget)
|
||||
@ -454,6 +477,8 @@ void WidgetLoader::fillWidgetWithXmlElementAttributes(const TiXmlElement* elem,
|
||||
const char* minheight = elem->Attribute("minheight");
|
||||
const char* maxwidth = elem->Attribute("maxwidth");
|
||||
const char* maxheight = elem->Attribute("maxheight");
|
||||
const char* border = elem->Attribute("border");
|
||||
const char* styleid = elem->Attribute("style");
|
||||
const char* childspacing = elem->Attribute("childspacing");
|
||||
|
||||
if (width) {
|
||||
@ -498,8 +523,11 @@ void WidgetLoader::fillWidgetWithXmlElementAttributes(const TiXmlElement* elem,
|
||||
if (noborders)
|
||||
widget->noBorderNoChildSpacing();
|
||||
|
||||
if (border)
|
||||
widget->setBorder(gfx::Border(strtol(border, NULL, 10)*guiscale()));
|
||||
|
||||
if (childspacing)
|
||||
widget->child_spacing = strtol(childspacing, NULL, 10);
|
||||
widget->child_spacing = strtol(childspacing, NULL, 10)*guiscale();
|
||||
|
||||
gfx::Size reqSize = widget->getPreferredSize();
|
||||
|
||||
@ -515,6 +543,14 @@ void WidgetLoader::fillWidgetWithXmlElementAttributes(const TiXmlElement* elem,
|
||||
widget->setMaxSize(gfx::Size(w, h));
|
||||
}
|
||||
|
||||
if (styleid) {
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(root->getTheme());
|
||||
skin::Style* style = theme->getStyle(styleid);
|
||||
ASSERT(style);
|
||||
SkinStylePropertyPtr prop(new SkinStyleProperty(style));
|
||||
widget->setProperty(prop);
|
||||
}
|
||||
|
||||
if (!root)
|
||||
root = widget;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Aseprite Base Library
|
||||
# Copyright (c) 2001-2014 David Capello
|
||||
# Copyright (c) 2001-2015 David Capello
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckCXXSourceCompiles)
|
||||
@ -65,6 +65,7 @@ set(BASE_SOURCES
|
||||
system_console.cpp
|
||||
temp_dir.cpp
|
||||
thread.cpp
|
||||
time.cpp
|
||||
trim_string.cpp
|
||||
version.cpp)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -28,6 +28,18 @@ template<> std::string convert_to(const int& from)
|
||||
return buf;
|
||||
}
|
||||
|
||||
template<> double convert_to(const std::string& from)
|
||||
{
|
||||
return std::strtod(from.c_str(), NULL);
|
||||
}
|
||||
|
||||
template<> std::string convert_to(const double& from)
|
||||
{
|
||||
char buf[32];
|
||||
std::sprintf(buf, "%g", from);
|
||||
return buf;
|
||||
}
|
||||
|
||||
template<> Sha1 convert_to(const std::string& from)
|
||||
{
|
||||
std::vector<uint8_t> digest(Sha1::HashSize);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -24,6 +24,9 @@ namespace base {
|
||||
template<> int convert_to(const std::string& from);
|
||||
template<> std::string convert_to(const int& from);
|
||||
|
||||
template<> double convert_to(const std::string& from);
|
||||
template<> std::string convert_to(const double& from);
|
||||
|
||||
template<> Sha1 convert_to(const std::string& from);
|
||||
template<> std::string convert_to(const Sha1& from);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -11,6 +11,7 @@
|
||||
#include "base/exception.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace base {
|
||||
@ -24,7 +25,7 @@ Exception::Exception() throw()
|
||||
Exception::Exception(const char* format, ...) throw()
|
||||
{
|
||||
try {
|
||||
if (!strchr(format, '%')) {
|
||||
if (!std::strchr(format, '%')) {
|
||||
m_msg = format;
|
||||
}
|
||||
else {
|
||||
@ -32,7 +33,7 @@ Exception::Exception(const char* format, ...) throw()
|
||||
va_start(ap, format);
|
||||
|
||||
char buf[1024]; // TODO warning buffer overflow
|
||||
vsprintf(buf, format, ap);
|
||||
std::vsprintf(buf, format, ap);
|
||||
m_msg = buf;
|
||||
|
||||
va_end(ap);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -12,6 +12,8 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
class Time;
|
||||
|
||||
bool is_file(const std::string& path);
|
||||
bool is_directory(const std::string& path);
|
||||
|
||||
@ -23,6 +25,8 @@ namespace base {
|
||||
bool has_readonly_attr(const std::string& path);
|
||||
void remove_readonly_attr(const std::string& path);
|
||||
|
||||
Time get_modification_time(const std::string& path);
|
||||
|
||||
void make_directory(const std::string& path);
|
||||
void make_all_directories(const std::string& path);
|
||||
void remove_directory(const std::string& path);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -10,12 +10,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
|
||||
#if __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#include "base/path.h"
|
||||
#include "base/time.h"
|
||||
|
||||
#define MAXPATHLEN 1024
|
||||
|
||||
@ -82,6 +84,19 @@ void remove_readonly_attr(const std::string& path)
|
||||
}
|
||||
}
|
||||
|
||||
Time get_modification_time(const std::string& path)
|
||||
{
|
||||
struct stat sts;
|
||||
int result = stat(path.c_str(), &sts);
|
||||
if (result != 0)
|
||||
return Time();
|
||||
|
||||
std::tm* t = std::localtime(&sts.st_mtime);
|
||||
return Time(
|
||||
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec);
|
||||
}
|
||||
|
||||
void remove_directory(const std::string& path)
|
||||
{
|
||||
int result = rmdir(path.c_str());
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -12,6 +12,7 @@
|
||||
#include "base/path.h"
|
||||
#include "base/string.h"
|
||||
#include "base/win32_exception.h"
|
||||
#include "base/time.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
@ -68,6 +69,24 @@ void remove_readonly_attr(const std::string& path)
|
||||
::SetFileAttributes(fn.c_str(), attr & ~FILE_ATTRIBUTE_READONLY);
|
||||
}
|
||||
|
||||
Time get_modification_time(const std::string& path)
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
ZeroMemory(&data, sizeof(data));
|
||||
|
||||
std::wstring fn = from_utf8(path);
|
||||
if (!GetFileAttributesEx(fn.c_str(), GetFileExInfoStandard, (LPVOID)&data))
|
||||
return Time();
|
||||
|
||||
SYSTEMTIME utc, local;
|
||||
FileTimeToSystemTime(&data.ftLastWriteTime, &utc);
|
||||
SystemTimeToTzSpecificLocalTime(NULL, &utc, &local);
|
||||
|
||||
return Time(
|
||||
local.wYear, local.wMonth, local.wDay,
|
||||
local.wHour, local.wMinute, local.wSecond);
|
||||
}
|
||||
|
||||
void make_directory(const std::string& path)
|
||||
{
|
||||
BOOL result = ::CreateDirectory(from_utf8(path).c_str(), NULL);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
std::string get_pretty_memory_size(size_t memsize);
|
||||
std::string get_pretty_memory_size(std::size_t memsize);
|
||||
|
||||
} // namespace base
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -8,9 +8,11 @@
|
||||
#define BASE_MEMORY_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
void* base_malloc (size_t bytes);
|
||||
void* base_malloc0(size_t bytes);
|
||||
void* base_realloc(void* mem, size_t bytes);
|
||||
#include <cstddef>
|
||||
|
||||
void* base_malloc (std::size_t bytes);
|
||||
void* base_malloc0(std::size_t bytes);
|
||||
void* base_realloc(void* mem, std::size_t bytes);
|
||||
void base_free (void* mem);
|
||||
char* base_strdup (const char* string);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2014 David Capello
|
||||
// Copyright (c) 2001-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -22,7 +22,7 @@ public:
|
||||
typedef typename list_type::const_iterator const_iterator;
|
||||
|
||||
bool empty() const { return m_observers.empty(); }
|
||||
size_t size() const { return m_observers.size(); }
|
||||
std::size_t size() const { return m_observers.size(); }
|
||||
|
||||
// Adds the observer in the collection. The observer is owned by the
|
||||
// collection and will be destroyed calling the T::dispose() member
|
||||
|
@ -187,11 +187,11 @@ std::string ProgramOptions::value_of(const Option& option) const
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po)
|
||||
{
|
||||
size_t maxOptionWidth = 0;
|
||||
std::size_t maxOptionWidth = 0;
|
||||
for (base::ProgramOptions::OptionList::const_iterator
|
||||
it=po.options().begin(), end=po.options().end(); it != end; ++it) {
|
||||
const base::ProgramOptions::Option* option = *it;
|
||||
size_t optionWidth =
|
||||
std::size_t optionWidth =
|
||||
6+option->name().size()+1+
|
||||
(option->doesRequireValue() ? option->getValueName().size()+1: 0);
|
||||
|
||||
@ -202,7 +202,7 @@ std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po)
|
||||
for (base::ProgramOptions::OptionList::const_iterator
|
||||
it=po.options().begin(), end=po.options().end(); it != end; ++it) {
|
||||
const base::ProgramOptions::Option* option = *it;
|
||||
size_t optionWidth = 6+option->name().size()+1+
|
||||
std::size_t optionWidth = 6+option->name().size()+1+
|
||||
(option->doesRequireValue() ? option->getValueName().size()+1: 0);
|
||||
|
||||
if (option->mnemonic() != 0)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -20,14 +20,14 @@ public:
|
||||
typedef typename Items::iterator iterator;
|
||||
typedef typename Items::const_iterator const_iterator;
|
||||
|
||||
RecentItems(size_t limit) : m_limit(limit) { }
|
||||
RecentItems(std::size_t limit) : m_limit(limit) { }
|
||||
|
||||
const_iterator begin() { return m_items.begin(); }
|
||||
const_iterator end() { return m_items.end(); }
|
||||
|
||||
bool empty() const { return m_items.empty(); }
|
||||
size_t size() const { return m_items.size(); }
|
||||
size_t limit() const { return m_limit; }
|
||||
std::size_t size() const { return m_items.size(); }
|
||||
std::size_t limit() const { return m_limit; }
|
||||
|
||||
void addItem(const T& item) {
|
||||
iterator it = std::find(m_items.begin(), m_items.end(), item);
|
||||
@ -57,7 +57,7 @@ public:
|
||||
|
||||
private:
|
||||
Items m_items;
|
||||
size_t m_limit;
|
||||
std::size_t m_limit;
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
@ -20,7 +20,7 @@ void replace_string(
|
||||
if (replace_this.empty()) // Do nothing case
|
||||
return;
|
||||
|
||||
size_t i = 0;
|
||||
std::size_t i = 0;
|
||||
while (true) {
|
||||
i = subject.find(replace_this, i);
|
||||
if (i == std::string::npos)
|
||||
@ -29,5 +29,5 @@ void replace_string(
|
||||
i += with_that.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace base
|
||||
|
@ -42,7 +42,7 @@ Sha1 Sha1::calculateFromFile(const std::string& fileName)
|
||||
unsigned char buf[1024];
|
||||
while (file.good()) {
|
||||
file.read((char*)buf, 1024);
|
||||
size_t len = (size_t)file.gcount();
|
||||
std::size_t len = (std::size_t)file.gcount();
|
||||
if (len > 0)
|
||||
SHA1Input(&sha, buf, len);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013 David Capello
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
@ -38,10 +38,10 @@ void base::split_string(const std::string& string,
|
||||
std::vector<std::string>& parts,
|
||||
const std::string& separators)
|
||||
{
|
||||
size_t elements = 1 + std::count_if(string.begin(), string.end(), is_separator(&separators));
|
||||
std::size_t elements = 1 + std::count_if(string.begin(), string.end(), is_separator(&separators));
|
||||
parts.reserve(elements);
|
||||
|
||||
size_t beg = 0, end;
|
||||
std::size_t beg = 0, end;
|
||||
while (true) {
|
||||
end = string.find_first_of(separators, beg);
|
||||
if (end != std::string::npos) {
|
||||
|
@ -83,7 +83,7 @@ std::wstring from_utf8(const std::string& src)
|
||||
#else
|
||||
|
||||
// Based on Allegro Unicode code (allegro/src/unicode.c)
|
||||
static size_t insert_utf8_char(std::string* result, wchar_t chr)
|
||||
static std::size_t insert_utf8_char(std::string* result, wchar_t chr)
|
||||
{
|
||||
int size, bits, b, i;
|
||||
|
||||
@ -129,7 +129,7 @@ std::string to_utf8(const std::wstring& src)
|
||||
|
||||
// Get required size to reserve a string so string::push_back()
|
||||
// doesn't need to reallocate its data.
|
||||
size_t required_size = 0;
|
||||
std::size_t required_size = 0;
|
||||
for (it = begin; it != end; ++it)
|
||||
required_size += insert_utf8_char(NULL, *it);
|
||||
if (!required_size)
|
||||
|
40
src/base/time.cpp
Normal file
40
src/base/time.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Aseprite Base Library
|
||||
// Copyright (c) 2001-2013, 2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "base/time.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <ctime>
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
|
||||
Time current_time()
|
||||
{
|
||||
#if _WIN32
|
||||
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
return Time(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
||||
|
||||
#else
|
||||
|
||||
std::time_t now = std::time(nullptr);
|
||||
std::tm* t = std::localtime(&now);
|
||||
return Time(
|
||||
t->tm_year+1900, t->tm_mon+1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace base
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user