Remove signals and hooks in GUI code.

Several refactoring tasks where made:
- Removed the old Widget::id field (JID).
- Renamed Widget::get/setName to get/setId.
- Moved load_widget_from_xmlfile() to app::load_widget and WidgetLoader
  class.
- Removed jhook structure & jwidget_add_hook function. Hooks were replaced
  subclassing widgets.
- Added InitThemeEvent class and Widget::onInitTheme member function.
This commit is contained in:
David Capello 2012-06-15 23:37:59 -03:00
parent b599f0f85a
commit 02e8c66da4
112 changed files with 3112 additions and 3319 deletions

View File

@ -14,7 +14,8 @@
<key command="SaveFileCopyAs" shortcut="Ctrl+Shift+C" />
<key command="CloseFile" shortcut="Ctrl+W" />
<key command="CloseAllFiles" shortcut="Ctrl+Shift+W" />
<key command="DeveloperConsole" shortcut="F11" />
<key command="AdvancedMode" shortcut="F11" />
<key command="DeveloperConsole" shortcut="F12" />
<key command="Exit" shortcut="Ctrl+Q" />
<key command="Exit" shortcut="Alt+F4" />
<key command="Cancel" shortcut="Esc" />
@ -404,7 +405,7 @@
<menu id="layer_popup">
<item command="LayerProperties" text="&amp;Properties..." />
<separator />
<item command="NewLayer" text="&amp;New..." />
<item command="NewLayer" text="&amp;New" />
<item command="RemoveLayer" text="&amp;Remove" />
<item command="BackgroundFromLayer" text="&amp;Background from Layer" />
<item command="LayerFromBackground" text="&amp;Layer from Background" />

View File

@ -1,13 +1,13 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Warning - Important" name="advanced_mode_warning">
<gui>
<window text="Warning - Important" id="advanced_mode_warning">
<grid columns="1">
<label text="You are going to enter in &quot;Advanced Mode&quot;." />
<label text="" name="warning_label" />
<check text="Don't show this again" name="donot_show" />
<label text="" id="warning_label" />
<check text="Don't show this again" id="donot_show" />
<separator horizontal="true" />
<button text="&amp;OK" closewindow="true" magnetic="true" minwidth="60" cell_align="center" />
<button text="&amp;OK" closewindow="true" magnet="true" minwidth="60" cell_align="center" />
</grid>
</window>
</jinete>
</gui>

View File

@ -1,32 +1,32 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<box vertical="true" name="main_box">
<gui>
<box vertical="true" id="main_box">
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="Left:" />
<label text="Right:" />
</box>
<box vertical="true" homogeneous="true">
<entry text="0" name="left" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the left side.&#10;Use a negative number to remove columns." />
<entry text="0" name="right" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the right side.&#10;Use a negative number to remove columns." />
<entry text="0" id="left" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the left side.&#10;Use a negative number to remove columns." />
<entry text="0" id="right" maxsize="32" maxwidth="64" tooltip="Columns to be added/removed in the right side.&#10;Use a negative number to remove columns." />
</box>
<box vertical="true" homogeneous="true">
<label text="Top:" />
<label text="Bottom:" />
</box>
<box vertical="true" homogeneous="true">
<entry text="0" name="top" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the top side.&#10;Use a negative number to remove rows." />
<entry text="0" name="bottom" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the bottom side.&#10;Use a negative number to remove rows." />
<entry text="0" id="top" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the top side.&#10;Use a negative number to remove rows." />
<entry text="0" id="bottom" maxsize="32" maxwidth="64" tooltip="Rows to be added/removed in the bottom side.&#10;Use a negative number to remove rows." />
</box>
</box>
<separator horizontal="true" />
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" width="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</box>
</jinete>
</gui>

View File

@ -1,26 +1,26 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Cel Properties" name="cel_properties">
<gui>
<window text="Cel Properties" id="cel_properties">
<grid columns="2">
<label text="Frame:" />
<label name="frame" />
<label id="frame" />
<label text="Position: " />
<label name="pos" readonly="true" tooltip="X axis, Y axis" />
<label id="pos" readonly="true" tooltip="X axis, Y axis" />
<label text="Dimension:" />
<label name="size" readonly="true" tooltip="Width x Height (Memory size)" />
<label id="size" readonly="true" tooltip="Width x Height (Memory size)" />
<label text="Opacity:" />
<slider min="0" max="255" name="opacity" cell_align="horizontal" width="128" />
<slider min="0" max="255" id="opacity" cell_align="horizontal" width="128" />
<separator horizontal="true" cell_hspan="2" />
<box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" minwidth="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</jinete>
</gui>

View File

@ -1,7 +1,7 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Point Properties" name="point_properties">
<gui>
<window text="Point Properties" id="point_properties">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true" homogeneous="true">
@ -9,14 +9,14 @@
<label text="Y:" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<entry maxsize="32" name="x" magnetic="true" />
<entry maxsize="32" name="y" />
<entry maxsize="32" id="x" magnet="true" />
<entry maxsize="32" id="y" />
</box>
</box>
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="button_ok" magnetic="true" />
<button text="&amp;OK" closewindow="true" id="button_ok" magnet="true" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,12 +1,12 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<box vertical="true" name="controls" expansive="true">
<view expansive="true" name="view" minwidth="128" minheight="64">
<listbox name="stock" />
<gui>
<box vertical="true" id="controls" expansive="true">
<view expansive="true" id="view" minwidth="128" minheight="64">
<listbox id="stock" />
</view>
<box horizontal="true">
<button text="&amp;Reload Stock" name="reload" />
<button text="&amp;Reload Stock" id="reload" />
</box>
</box>
</jinete>
</gui>

View File

@ -1,10 +1,10 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<grid columns="2" name="controls">
<gui>
<grid columns="2" id="controls">
<label text="Width:" />
<entry name="width" maxsize="4" cell_align="horizontal" />
<entry id="width" maxsize="4" cell_align="horizontal" />
<label text="Height:" />
<entry name="height" maxsize="4" cell_align="horizontal" />
<entry id="height" maxsize="4" cell_align="horizontal" />
</grid>
</jinete>
</gui>

View File

@ -1,36 +0,0 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Draw Text" name="drawtext_window">
<box vertical="true">
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="Font:" />
<label text="Size:" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<button text="" name="font" />
<entry maxsize="8" name="size"/>
</box>
</box>
<!-- <label text="Fixed Size:" /> -->
<!-- <view expansive="true"> -->
<!-- <listbox /> -->
<!-- </view> -->
<separator horizontal="true" />
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="Text:" />
<label text="Color:" />
</box>
<box vertical="true" homogeneous="true" expansive="true" name="color_box">
<entry maxsize="256" name="text" expansive="true" />
</box>
</box>
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</window>
</jinete>

View File

@ -1,7 +1,7 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Duplicate Sprite" name="duplicate_sprite">
<gui>
<window text="Duplicate Sprite" id="duplicate_sprite">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true" homogeneous="true">
@ -9,15 +9,15 @@
<label text="As:" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<label text="" name="src_name" />
<entry maxsize="256" name="dst_name" magnetic="true" />
<label text="" id="src_name" />
<entry maxsize="256" id="dst_name" magnet="true" />
</box>
</box>
<check text="Duplicate merged layers only" name="flatten" />
<check text="Duplicate merged layers only" id="flatten" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,29 +1,27 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="" name="file_selector">
<box vertical="true">
<gui>
<box id="main" vertical="true">
<box horizontal="true">
<box horizontal="true" noborders="true">
<button text="" name="goback" bevel="2 0 2 0" tooltip="Go back one folder" />
<button text="" name="goforward" bevel="0 2 0 2" tooltip="Go forward one folder" />
<button text="" id="goback" bevel="2 0 2 0" tooltip="Go back one folder" />
<button text="" id="goforward" bevel="0 2 0 2" tooltip="Go forward one folder" />
</box>
<button text="" name="goup" tooltip="Up to parent folder&#10;(Backspace)" />
<combobox name="location" expansive="true" />
<button text="" id="goup" tooltip="Up to parent folder&#10;(Backspace)" />
<combobox id="location" expansive="true" />
</box>
<box vertical="true" expansive="true" name="box" />
<view id="fileview_container" expansive="true"></view>
<box horizontal="true">
<label text="Name:" />
<entry text="" maxsize="256" name="filename" expansive="true" magnetic="true" />
<combobox name="filetype" minwidth="70" />
<filenameentry id="filename" expansive="true" magnet="true" />
<combobox id="filetype" minwidth="70" />
</box>
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" width="60" />
<button text="&amp;Cancel" closewindow="true" name="cancel" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" id="cancel" />
</box>
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,22 +1,22 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Frame Duration" name="frame_duration">
<gui>
<window text="Frame Duration" id="frame_duration">
<grid columns="3">
<label text="Frame number:" />
<label text="" name="frame" />
<label text="" id="frame" />
<box cell_align="horizontal" />
<label text="Duration (milliseconds):" />
<entry maxsize="10" name="frlen" magnetic="true" />
<entry maxsize="10" id="frlen" magnet="true" />
<box cell_align="horizontal" />
<separator horizontal="true" cell_hspan="3" />
<box horizontal="true" homogeneous="true" cell_hspan="3" cell_align="right">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" minwidth="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</jinete>
</gui>

View File

@ -1,18 +1,18 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Go to Frame" name="goto_frame">
<gui>
<window text="Go to Frame" id="goto_frame">
<grid columns="3">
<label text="Frame number:" />
<entry expansive="true" maxsize="4" name="frame" magnetic="true" />
<entry expansive="true" maxsize="4" id="frame" magnet="true" />
<box cell_align="horizontal" />
<separator horizontal="true" cell_hspan="3" />
<box horizontal="true" homogeneous="true" cell_hspan="3" cell_align="right">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" minwidth="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</jinete>
</gui>

View File

@ -1,27 +1,27 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Grid Settings" name="grid_settings">
<gui>
<window text="Grid Settings" id="grid_settings">
<grid columns="4">
<label text="X:" />
<entry name="grid_x" text="" maxsize="4" magnetic="true" />
<entry id="grid_x" text="" maxsize="4" magnet="true" />
<label text="Y:" />
<entry name="grid_y" text="" maxsize="4" />
<entry id="grid_y" text="" maxsize="4" />
<label text="Width:" />
<entry name="grid_w" text="" maxsize="4" />
<entry id="grid_w" text="" maxsize="4" />
<label text="Height:" />
<entry name="grid_h" text="" maxsize="4" />
<entry id="grid_h" text="" maxsize="4" />
<separator horizontal="true" cell_hspan="4" />
<box horizontal="true" homogeneous="true" cell_hspan="4" cell_align="right">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" minwidth="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</jinete>
</gui>

View File

@ -1,17 +1,17 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="JPEG Options" name="jpeg_options">
<gui>
<window text="JPEG Options" id="jpeg_options">
<grid columns="2">
<label text="Quality:" />
<slider min="0" max="10" name="quality" cell_align="horizontal" width="128" />
<slider min="0" max="10" id="quality" cell_align="horizontal" width="128" />
<separator horizontal="true" cell_hspan="2" />
<box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" minwidth="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</grid>
</window>
</jinete>
</gui>

View File

@ -1,16 +1,16 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window noborders="true" desktop="true" text="Main Window" name="main_window">
<gui>
<window noborders="true" desktop="true" text="Main Window" id="main_window">
<box noborders="true" vertical="true">
<box noborders="true" horizontal="true" name="menubar" />
<box noborders="true" horizontal="true" name="tabsbar" />
<box noborders="true" horizontal="true" id="menubar" />
<box noborders="true" horizontal="true" id="tabsbar" />
<box noborders="true" horizontal="true" expansive="true">
<box noborders="true" vertical="true" name="colorbar" />
<box noborders="true" horizontal="true" name="editor" expansive="true" />
<box noborders="true" vertical="true" name="toolbar" />
<box noborders="true" vertical="true" id="colorbar" />
<box noborders="true" horizontal="true" id="editor" expansive="true" />
<box noborders="true" vertical="true" id="toolbar" />
</box>
<box noborders="true" horizontal="true" name="statusbar" />
<box noborders="true" horizontal="true" id="statusbar" />
</box>
</window>
</jinete>
</gui>

View File

@ -1,32 +1,32 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="New Image Layer" name="new_layer">
<gui>
<window text="New Image Layer" id="new_layer">
<box vertical="true">
<box horizontal="true">
<box vertical="true" homogeneous="true">
<label text="Name:" />
</box>
<box vertical="true" homogeneous="true">
<entry maxsize="256" text="New Layer" name="name" magnetic="true" />
<entry maxsize="256" text="New Layer" id="name" magnet="true" />
</box>
</box>
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</window>
<window text="New Layer Set" name="new_layer_set">
<window text="New Layer Set" id="new_layer_set">
<box vertical="true">
<box horizontal="true">
<label text="Name:" />
<entry maxsize="256" text="New Set" name="name" />
<entry maxsize="256" text="New Set" id="name" />
</box>
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,31 +1,31 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="New Sprite" name="new_sprite">
<gui>
<window text="New Sprite" id="new_sprite">
<box vertical="true">
<separator text="Size:" left="true" horizontal="true" />
<grid columns="2">
<label text="Width:" />
<entry name="width" maxsize="8" magnetic="true" cell_align="horizontal" tooltip="Width of the new sprite&#10;(in pixels)" />
<entry id="width" maxsize="8" magnet="true" cell_align="horizontal" tooltip="Width of the new sprite&#10;(in pixels)" />
<label text="Height:" />
<entry name="height" maxsize="8" cell_align="horizontal" tooltip="Height of the new sprite&#10;(in pixels)" />
<entry id="height" maxsize="8" cell_align="horizontal" tooltip="Height of the new sprite&#10;(in pixels)" />
</grid>
<separator text="Color Mode:" left="true" horizontal="true" />
<box vertical="true" homogeneous="true" childspacing="0">
<box horizontal="true">
<radio name="radio3" text="&amp;Indexed with " group="1" tooltip="Using a palette of 256 colors&#10;(8 bits per pixel)" />
<entry name="colors" maxsize="8" tooltip="Maximum number of colors&#10;(only for Indexed images)&#10;&#10;This field cannot be modified in this beta version." disabled="true" />
<radio id="radio3" text="&amp;Indexed with " group="1" tooltip="Using a palette of 256 colors&#10;(8 bits per pixel)" />
<entry id="colors" maxsize="8" tooltip="Maximum number of colors&#10;(only for Indexed images)&#10;&#10;This field cannot be modified in this beta version." disabled="true" />
<label text="Colors" />
</box>
<radio name="radio1" text="&amp;RGB Color" group="1" tooltip="RGBA color mode&#10;(32 bits per pixel)" />
<radio name="radio2" text="&amp;Grayscale" group="1" tooltip="Value and Alpha&#10;(16 bits per pixel)" />
<radio id="radio1" text="&amp;RGB Color" group="1" tooltip="RGBA color mode&#10;(32 bits per pixel)" />
<radio id="radio2" text="&amp;Grayscale" group="1" tooltip="Value and Alpha&#10;(16 bits per pixel)" />
</box>
<separator text="Background:" left="true" horizontal="true" />
<view maxsize="true" expansive="true">
<listbox name="bg_box">
<listbox id="bg_box">
<listitem text="Transparent" />
<listitem text="Black" />
<listitem text="White" />
@ -37,11 +37,11 @@
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok_button" magnetic="true" width="60" />
<button text="&amp;OK" closewindow="true" id="ok_button" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,7 +1,7 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Options" name="options">
<gui>
<window text="Options" id="options">
<box vertical="true">
<box horizontal="true">
<box vertical="true">
@ -9,18 +9,18 @@
<!-- Editor -->
<separator text="Editor:" horizontal="true" />
<check text="Smooth auto-scroll" name="smooth" />
<check text="2 Click Movement" name="move_click2" disabled="true" />
<check text="2 Click Drawing" name="draw_click2" disabled="true" />
<check text="Smooth auto-scroll" id="smooth" />
<check text="2 Click Movement" id="move_click2" disabled="true" />
<check text="2 Click Drawing" id="draw_click2" disabled="true" />
<grid columns="2">
<label text="Cursor:" />
<box name="cursor_color_box" /><!-- custom widget -->
<box id="cursor_color_box" /><!-- custom widget -->
<label text="Grid Color:" />
<box name="grid_color_box" /><!-- custom widget -->
<box id="grid_color_box" /><!-- custom widget -->
<label text="Pixel Grid:" />
<box name="pixel_grid_color_box" /><!-- custom widget -->
<box id="pixel_grid_color_box" /><!-- custom widget -->
</grid>
<!-- Undo -->
@ -28,7 +28,7 @@
<separator text="Undo:" horizontal="true" />
<box horizontal="true">
<label text="Undo Limit:" />
<entry name="undo_size_limit" maxsize="4" tooltip="Limit of memory to be used&#10;for undo information per sprite.&#10;Specified in megabytes." />
<entry id="undo_size_limit" maxsize="4" tooltip="Limit of memory to be used&#10;for undo information per sprite.&#10;Specified in megabytes." />
<label text="MB" />
</box>
@ -41,16 +41,16 @@
<separator text="Checked Background:" horizontal="true" />
<box horizontal="true">
<label text="Size:" />
<combobox name="checked_bg_size" expansive="true" />
<combobox id="checked_bg_size" expansive="true" />
</box>
<check text="Apply Zoom" name="checked_bg_zoom" />
<check text="Apply Zoom" id="checked_bg_zoom" />
<grid columns="2">
<label text="Color 1" />
<box horizontal="true" name="checked_bg_color1_box" />
<box horizontal="true" id="checked_bg_color1_box" />
<label text="Color 2" />
<box horizontal="true" name="checked_bg_color2_box" />
<box horizontal="true" id="checked_bg_color2_box" />
</grid>
<button name="checked_bg_reset" text="Reset" />
<button id="checked_bg_reset" text="Reset" />
</box>
</box>
@ -60,10 +60,10 @@
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="button_ok" magnetic="true" width="60" />
<button text="&amp;OK" closewindow="true" id="button_ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,15 +0,0 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Play FLI/FLC" name="play_fli">
<box vertical="true">
<check text="Loop" name="loop" />
<check text="Fullscreen" name="fullscreen" />
<button text="&amp;Open" name="button_open" />
<box horizontal="true" homogeneous="true" expansive="true">
<button text="&amp;Play" name="button_play" magnetic="true" />
<button text="&amp;Close" />
</box>
</box>
</window>
</jinete>

View File

@ -1,16 +1,16 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<box vertical="true" expansive="true" name="controls">
<gui>
<box vertical="true" expansive="true" id="controls">
<box horizontal="true" expansive="true">
<grid columns="2" name="controls">
<grid columns="2" id="controls">
<label text="From:" />
<colorpicker name="from" cell_align="horizontal" />
<colorpicker id="from" cell_align="horizontal" />
<label text="To:" />
<colorpicker name="to" cell_align="horizontal" />
<colorpicker id="to" cell_align="horizontal" />
</grid>
</box>
<label text="Tolerance:" />
<slider min="0" max="255" name="tolerance" />
<slider min="0" max="255" id="tolerance" />
</box>
</jinete>
</gui>

View File

@ -1,33 +1,33 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Sprite Properties" name="sprite_properties">
<gui>
<window text="Sprite Properties" id="sprite_properties">
<box vertical="true">
<box horizontal="true">
<grid columns="2" expansive="true">
<label text="File name:" />
<entry text="" name="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<label text="Type:" />
<label text="" name="type" />
<label text="" id="type" />
<label text="Size:" />
<label text="" name="size" />
<label text="" id="size" />
<label text="Frames:" />
<label text="" name="frames" />
<label text="" id="frames" />
<label text="Transparent Color:" />
<box horizontal="true" name="box_transparent" tooltip="Palette entry used as transparent color in each layer (only for indexed images)." />
<box horizontal="true" id="box_transparent" tooltip="Palette entry used as transparent color in each layer (only for indexed images)." />
</grid>
</box>
<separator horizontal="true" />
<box horizontal="true">
<box horizontal="true" expansive="true" />
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" width="60" />
<button text="&amp;Cancel" closewindow="true" name="cancel" width="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" id="cancel" width="60" />
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,7 +1,7 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Sprite Size" name="sprite_size">
<gui>
<window text="Sprite Size" id="sprite_size">
<box vertical="true">
<box vertical="true">
<separator text="Pixels:" left="true" horizontal="true" />
@ -12,10 +12,10 @@
<label text="Height:" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<entry expansive="true" name="width_px" maxsize="8" magnetic="true" tooltip="New width for the sprite (in pixels)" />
<entry expansive="true" name="height_px" maxsize="8" tooltip="New height for the sprite (in pixels)" />
<entry expansive="true" id="width_px" maxsize="8" magnet="true" tooltip="New width for the sprite (in pixels)" />
<entry expansive="true" id="height_px" maxsize="8" tooltip="New height for the sprite (in pixels)" />
</box>
<check text="Lock Ratio" name="lock_ratio" selected="true" />
<check text="Lock Ratio" id="lock_ratio" selected="true" />
</box>
</box>
<separator text="Percentage:" left="true" horizontal="true" />
@ -26,8 +26,8 @@
<label text="Height:" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<entry expansive="true" text="100%%" name="width_perc" maxsize="8" magnetic="true" tooltip="New width for the sprite&#10;Percentage of current width." />
<entry expansive="true" text="100%%" name="height_perc" maxsize="8" tooltip="New height for the sprite&#10;Percentage of current height." />
<entry expansive="true" text="100%%" id="width_perc" maxsize="8" magnet="true" tooltip="New width for the sprite&#10;Percentage of current width." />
<entry expansive="true" text="100%%" id="height_perc" maxsize="8" tooltip="New height for the sprite&#10;Percentage of current height." />
</box>
<box horizontal="true" width="64" />
</box>
@ -37,16 +37,16 @@
<box vertical="true" expansive="true">
<box horizontal="true">
<label text="Method:" />
<combobox name="method" expansive="true" />
<combobox id="method" expansive="true" />
</box>
</box>
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="&amp;OK" closewindow="true" name="ok" magnetic="true" width="60" />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -1,21 +1,21 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2001-2012 by David Capello -->
<jinete>
<window text="Tools Configuration" name="configure_tool">
<gui>
<window text="Tools Configuration" id="configure_tool">
<box vertical="true" childspacing="0">
<box horizontal="true" expansive="true">
<box vertical="true" childspacing="2">
<box horizontal="true" childspacing="0">
<check text="Tiled" name="tiled" />
<check text="x" name="tiled_x" />
<check text="y" name="tiled_y" />
<check text="Tiled" id="tiled" />
<check text="x" id="tiled_x" />
<check text="y" id="tiled_y" />
</box>
<check text="Onionskin" name="onionskin" />
<check text="Onionskin" id="onionskin" />
<separator text="Grid:" horizontal="true" left="true" />
<check text="Snap to Grid" name="snap_to_grid" />
<check text="View Grid" name="view_grid" />
<check text="Pixel Grid" name="pixel_grid" />
<button text="Set &amp;Grid" name="set_grid" />
<check text="Snap to Grid" id="snap_to_grid" />
<check text="View Grid" id="view_grid" />
<check text="Pixel Grid" id="pixel_grid" />
<button text="Set &amp;Grid" id="set_grid" />
</box>
<separator vertical="true" />
<box vertical="true" expansive="true" childspacing="2">
@ -23,24 +23,24 @@
<grid columns="2" childspacing="0" expansive="true">
<label text="Pen:" />
<box horizontal="true" childspacing="0" name="brush_type_box" /><!-- custom widget -->
<box horizontal="true" childspacing="0" id="brush_type_box" /><!-- custom widget -->
<label text="Size:" />
<slider min="1" max="32" name="brush_size" minwidth="32" cell_align="horizontal" />
<slider min="1" max="32" id="brush_size" minwidth="32" cell_align="horizontal" />
<label text="Angle:" />
<slider min="0" max="180" name="brush_angle" cell_align="horizontal" />
<slider min="0" max="180" id="brush_angle" cell_align="horizontal" />
<label text="Opacity:" name="opacity_label" />
<slider min="0" max="255" name="opacity" cell_align="horizontal" />
<label text="Opacity:" id="opacity_label" />
<slider min="0" max="255" id="opacity" cell_align="horizontal" />
<label text="Tolerance:" name="tolerance_label" />
<slider min="0" max="255" name="tolerance" cell_align="horizontal" />
<label text="Tolerance:" id="tolerance_label" />
<slider min="0" max="255" id="tolerance" cell_align="horizontal" />
</grid>
<box name="brush_preview_box" /><!-- custom widget -->
<box id="brush_preview_box" /><!-- custom widget -->
</box>
<box vertical="true" name="spray_box">
<box vertical="true" id="spray_box">
<separator text="Spray:" horizontal="true" left="true" />
<box horizontal="true">
<box vertical="true" homogeneous="true" childspacing="0">
@ -48,8 +48,8 @@
<label text="Air Speed:" />
</box>
<box vertical="true" homogeneous="true" expansive="true" childspacing="0">
<slider min="1" max="32" name="spray_width" />
<slider min="1" max="100" name="air_speed" />
<slider min="1" max="32" id="spray_width" />
<slider min="1" max="100" id="air_speed" />
</box>
</box>
</box>
@ -57,4 +57,4 @@
</box>
</box>
</window>
</jinete>
</gui>

View File

@ -159,10 +159,11 @@ add_library(aseprite-library
ui_context.cpp
undo_transaction.cpp
xml_exception.cpp
xml_widgets.cpp
app/check_update.cpp
app/color.cpp
app/color_utils.cpp
app/file_selector.cpp
app/widget_loader.cpp
commands/cmd_about.cpp
commands/cmd_advanced_mode.cpp
commands/cmd_background_from_layer.cpp
@ -247,7 +248,6 @@ add_library(aseprite-library
commands/filters/filter_window.cpp
commands/filters/filter_worker.cpp
dialogs/aniedit.cpp
dialogs/filesel.cpp
dialogs/maskcol.cpp
file/ase_format.cpp
file/bmp_format.cpp
@ -366,7 +366,8 @@ add_library(aseprite-library
widgets/editor/standby_state.cpp
widgets/editor/tool_loop_impl.cpp
widgets/editor/transform_handles.cpp
widgets/fileview.cpp
widgets/file_list.cpp
widgets/file_selector.cpp
widgets/hex_color_entry.cpp
widgets/menuitem2.cpp
widgets/palette_view.cpp

View File

@ -22,6 +22,8 @@
#include "app/check_update.h"
#include "app/color_utils.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/exception.h"
#include "base/unique_ptr.h"
#include "check_args.h"
@ -181,7 +183,7 @@ int App::run()
gui::Manager::getDefault()->invalidate();
// Load main window
top_window = static_cast<Frame*>(load_widget("main_window.xml", "main_window"));
top_window = app::load_widget<Frame>("main_window.xml", "main_window");
box_menubar = top_window->findChild("menubar");
box_editors = top_window->findChild("editor");

33
src/app/file_selector.cpp Normal file
View File

@ -0,0 +1,33 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "widgets/file_selector.h"
namespace app {
base::string show_file_selector(const base::string& title,
const base::string& initialPath,
const base::string& showExtensions)
{
widgets::FileSelector fileSelector;
return fileSelector.show(title, initialPath, showExtensions);
}
} // namespace app

View File

@ -1,28 +1,32 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DIALOGS_FILESEL_H_INCLUDED
#define DIALOGS_FILESEL_H_INCLUDED
#include "base/string.h"
base::string ase_file_selector(const base::string& message,
const base::string& init_path,
const base::string& exts);
#endif
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_FILE_SELECTOR_H_INCLUDED
#define APP_FILE_SELECTOR_H_INCLUDED
#include "base/string.h"
namespace app {
base::string show_file_selector(const base::string& title,
const base::string& initialPath,
const base::string& showExtensions);
} // namespace app
#endif

View File

@ -1,41 +1,39 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WIDGETS_FILEVIEW_H_INCLUDED
#define WIDGETS_FILEVIEW_H_INCLUDED
#include "base/string.h"
#include "file_system.h"
#include "gui/base.h"
/* TODO use some JI_SIGNAL_USER */
#define SIGNAL_FILEVIEW_FILE_SELECTED 0x10006
#define SIGNAL_FILEVIEW_FILE_ACCEPT 0x10007
#define SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED 0x10008
JWidget fileview_new(IFileItem* start_folder, const base::string& exts);
int fileview_type();
IFileItem* fileview_get_current_folder(JWidget fileview);
IFileItem* fileview_get_selected(JWidget fileview);
void fileview_set_current_folder(JWidget widget, IFileItem* folder);
const FileItemList& fileview_get_filelist(JWidget fileview);
void fileview_goup(JWidget fileview);
#endif
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_GUI_FIND_WIDGET_H_INCLUDED
#define APP_GUI_FIND_WIDGET_H_INCLUDED
#include "app/widget_not_found.h"
class Widget;
namespace app {
template<class T>
inline T* find_widget(Widget* parent, const char* childId) {
T* child = parent->findChildT<T>(childId);
if (!child)
throw WidgetNotFound(childId);
return child;
}
} // namespace app
#endif

View File

@ -1,26 +1,35 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XML_WIDGETS_H_INCLUDED
#define XML_WIDGETS_H_INCLUDED
class Widget;
Widget* load_widget_from_xmlfile(const char* xmlFilename, const char* widgetName);
#endif
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_GUI_LOAD_WIDGET_H_INCLUDED
#define APP_GUI_LOAD_WIDGET_H_INCLUDED
#include "app/widget_loader.h"
#include "base/unique_ptr.h"
namespace app {
template<class T>
inline T* load_widget(const char* fileName, const char* widgetId) {
WidgetLoader loader;
return loader.loadWidgetT<T>(fileName, widgetId);
}
} // namespace app
#endif

File diff suppressed because it is too large Load Diff

81
src/app/widget_loader.h Normal file
View File

@ -0,0 +1,81 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_WIDGET_LOADER_H_INCLUDED
#define APP_WIDGET_LOADER_H_INCLUDED
#include "app/widget_type_mismatch.h"
#include <map>
#include <string>
class Widget;
class TiXmlElement;
namespace gui { class TooltipManager; }
namespace app {
class WidgetLoader
{
public:
// Interface used to create customized widgets.
class IWidgetTypeCreator {
public:
virtual ~IWidgetTypeCreator() { }
virtual void dispose() = 0;
virtual Widget* createWidgetFromXml(const TiXmlElement* xmlElem) = 0;
};
WidgetLoader();
~WidgetLoader();
// Adds a new widget type that can be referenced in the .xml file
// with an XML element. The "tagName" is the same name as in the
// .xml should appear as <tagName>...</tagName>
//
// The "creator" will not be deleted automatically at the
// WidgetLoader dtor.
void addWidgetType(const char* tagName, IWidgetTypeCreator* creator);
// Loads the specified widget from an .xml file.
Widget* loadWidget(const char* fileName, const char* widgetId);
template<class T>
T* loadWidgetT(const char* fileName, const char* widgetId) {
Widget* widget = loadWidget(fileName, widgetId);
T* specificWidget = dynamic_cast<T*>(widget);
if (!specificWidget)
throw WidgetTypeMismatch(widgetId);
return specificWidget;
}
private:
Widget* loadWidgetFromXmlFile(const char* xmlFilename, const char* widgetId);
Widget* convertXmlElementToWidget(const TiXmlElement* elem, Widget* root);
typedef std::map<std::string, IWidgetTypeCreator*> TypeCreatorsMap;
TypeCreatorsMap m_typeCreators;
::gui::TooltipManager* m_tooltipManager;
};
} // namespace app
#endif

View File

@ -0,0 +1,39 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_WIDGET_NOT_FOUND_H_INCLUDED
#define APP_WIDGET_NOT_FOUND_H_INCLUDED
#include <string>
#include <stdexcept>
class Widget;
namespace app {
class WidgetNotFound : public std::runtime_error
{
public:
WidgetNotFound(const char* widgetId)
: std::runtime_error(std::string("A data file is corrupted.\nPlease reinstall the program\n\n"
"Details: Widget not found: ") + widgetId) { }
};
} // namespace app
#endif

View File

@ -0,0 +1,37 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_WIDGET_TYPE_MISMATCH_H_INCLUDED
#define APP_WIDGET_TYPE_MISMATCH_H_INCLUDED
#include <string>
#include <stdexcept>
namespace app {
class WidgetTypeMismatch : public std::runtime_error
{
public:
WidgetTypeMismatch(const char* widgetId)
: std::runtime_error(std::string("Widget ") + widgetId +
" of the expected type.\nPlease reinstall the program.\n\n") { }
};
} // namespace app
#endif

View File

@ -48,7 +48,7 @@ AboutCommand::AboutCommand()
void AboutCommand::onExecute(Context* context)
{
FramePtr frame(new Frame(false, "About " PACKAGE));
UniquePtr<Frame> frame(new Frame(false, "About " PACKAGE));
Box* box1 = new Box(JI_VERTICAL);
Grid* grid = new Grid(2, false);
Label* title = new Label(PACKAGE " v" VERSION);

View File

@ -18,10 +18,11 @@
#include "config.h"
#include "gui/gui.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/gui.h"
#include "widgets/color_bar.h"
@ -71,9 +72,9 @@ void AdvancedModeCommand::onExecute(Context* context)
char key[1024];
char buf[1024];
FramePtr window(load_widget("advanced_mode.xml", "advanced_mode_warning"));
Widget* warning_label = find_widget(window, "warning_label");
Widget* donot_show = find_widget(window, "donot_show");
UniquePtr<Frame> window(app::load_widget<Frame>("advanced_mode.xml", "advanced_mode_warning"));
Widget* warning_label = app::find_widget<Widget>(window, "warning_label");
Widget* donot_show = app::find_widget<Widget>(window, "donot_show");
strcpy(warning, "You can back pressing the \"%s\" key.");
jaccel_to_string(accel, key);

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "app/color_utils.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "base/unique_ptr.h"
#include "commands/command.h"
@ -53,15 +55,13 @@ public:
, m_selectBoxState(new SelectBoxState(this, m_rect,
SelectBoxState::PaintRulers |
SelectBoxState::PaintDarkOutside))
, m_mainBox(app::load_widget<Widget>("canvas_size.xml", "main_box"))
, m_left(app::find_widget<Entry>(m_mainBox, "left"))
, m_top(app::find_widget<Entry>(m_mainBox, "top"))
, m_right(app::find_widget<Entry>(m_mainBox, "right"))
, m_bottom(app::find_widget<Entry>(m_mainBox, "bottom"))
, m_ok(app::find_widget<Button>(m_mainBox, "ok"))
{
m_mainBox = load_widget("canvas_size.xml", "main_box");
get_widgets(m_mainBox,
"left", &m_left,
"top", &m_top,
"right", &m_right,
"bottom", &m_bottom,
"ok", &m_ok, NULL);
addChild(m_mainBox);
m_left->setTextf("%d", left);

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/mem_utils.h"
#include "commands/command.h"
#include "document_wrappers.h"
@ -60,11 +62,6 @@ bool CelPropertiesCommand::onEnabled(Context* context)
void CelPropertiesCommand::onExecute(Context* context)
{
JWidget label_frame, label_pos, label_size;
Widget* button_ok;
Slider* slider_opacity;
int memsize;
const ActiveDocumentReader document(context);
const Sprite* sprite = document->getSprite();
const Layer* layer = sprite->getCurrentLayer();
@ -72,13 +69,13 @@ void CelPropertiesCommand::onExecute(Context* context)
// Get current cel (can be NULL)
const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(sprite->getCurrentFrame());
FramePtr window(load_widget("cel_properties.xml", "cel_properties"));
get_widgets(window,
"frame", &label_frame,
"pos", &label_pos,
"size", &label_size,
"opacity", &slider_opacity,
"ok", &button_ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("cel_properties.xml", "cel_properties"));
Widget* label_frame = app::find_widget<Widget>(window, "frame");
Widget* label_pos = app::find_widget<Widget>(window, "pos");
Widget* label_size = app::find_widget<Widget>(window, "size");
Slider* slider_opacity = app::find_widget<Slider>(window, "opacity");
Widget* button_ok = app::find_widget<Widget>(window, "ok");
gui::TooltipManager* tooltipManager = window->findFirstChildByType<gui::TooltipManager>();
// Mini look for the opacity slider
setup_mini_look(slider_opacity);
@ -96,7 +93,7 @@ void CelPropertiesCommand::onExecute(Context* context)
label_pos->setTextf("%d, %d", cel->getX(), cel->getY());
// Dimension (and memory size)
memsize =
int memsize =
image_line_size(sprite->getStock()->getImage(cel->getImage()),
sprite->getStock()->getImage(cel->getImage())->w)*
sprite->getStock()->getImage(cel->getImage())->h;
@ -110,9 +107,10 @@ void CelPropertiesCommand::onExecute(Context* context)
slider_opacity->setValue(cel->getOpacity());
if (layer->is_background()) {
slider_opacity->setEnabled(false);
jwidget_add_tooltip_text(slider_opacity, "The `Background' layer is opaque,\n"
"you can't change its opacity.",
JI_LEFT);
tooltipManager->addTooltipFor(slider_opacity,
"The `Background' layer is opaque,\n"
"you can't change its opacity.",
JI_LEFT);
}
}
else {

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "commands/command.h"
#include "commands/commands.h"
@ -267,7 +269,7 @@ void ConfigureTools::onExecute(Context* context)
bool first_time = false;
if (!window) {
window = static_cast<Frame*>(load_widget("tools_configuration.xml", "configure_tool"));
window = app::load_widget<Frame>("tools_configuration.xml", "configure_tool");
first_time = true;
}
/* if the window is opened, close it */
@ -277,23 +279,22 @@ void ConfigureTools::onExecute(Context* context)
}
try {
get_widgets(window,
"tiled", &m_tiled,
"tiled_x", &m_tiledX,
"tiled_y", &m_tiledY,
"snap_to_grid", &m_snapToGrid,
"view_grid", &m_viewGrid,
"pixel_grid", &m_pixelGrid,
"set_grid", &set_grid,
"brush_size", &m_brushSize,
"brush_angle", &m_brushAngle,
"opacity", &m_opacity,
"tolerance", &m_tolerance,
"spray_width", &m_sprayWidth,
"air_speed", &m_airSpeed,
"brush_preview_box", &brush_preview_box,
"brush_type_box", &brush_type_box,
"onionskin", &m_onionSkin, NULL);
m_tiled = app::find_widget<CheckBox>(window, "tiled");
m_tiledX = app::find_widget<CheckBox>(window, "tiled_x");
m_tiledY = app::find_widget<CheckBox>(window, "tiled_y");
m_snapToGrid = app::find_widget<CheckBox>(window, "snap_to_grid");
m_viewGrid = app::find_widget<CheckBox>(window, "view_grid");
m_pixelGrid = app::find_widget<CheckBox>(window, "pixel_grid");
set_grid = app::find_widget<Button>(window, "set_grid");
m_brushSize = app::find_widget<Slider>(window, "brush_size");
m_brushAngle = app::find_widget<Slider>(window, "brush_angle");
m_opacity = app::find_widget<Slider>(window, "opacity");
m_tolerance = app::find_widget<Slider>(window, "tolerance");
m_sprayWidth = app::find_widget<Slider>(window, "spray_width");
m_airSpeed = app::find_widget<Slider>(window, "air_speed");
brush_preview_box = app::find_widget<Widget>(window, "brush_preview_box");
brush_type_box = app::find_widget<Widget>(window, "brush_type_box");
m_onionSkin = app::find_widget<CheckBox>(window, "onionskin");
}
catch (...) {
delete window;
@ -306,7 +307,7 @@ void ConfigureTools::onExecute(Context* context)
m_brushPreview = new BrushPreview();
m_brushPreview->min_w = 32 + 4;
m_brushPreview->min_h = 32 + 4;
m_brushPreview->setName("brush_preview");
m_brushPreview->setId("brush_preview");
}
else {
m_brushPreview = window->findChild("brush_preview");
@ -326,7 +327,7 @@ void ConfigureTools::onExecute(Context* context)
PART_BRUSH_SQUARE,
PART_BRUSH_LINE);
m_brushType->setName("brush_type");
m_brushType->setId("brush_type");
}
else {
m_brushType = window->findChildT<ButtonSet>("brush_type");

View File

@ -20,14 +20,14 @@
#include <allegro.h>
#include "gui/gui.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "document_wrappers.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/editors.h"
#include "modules/gui.h"
#include "raster/sprite.h"
#include "ui_context.h"
@ -64,7 +64,7 @@ void DuplicateSpriteCommand::onExecute(Context* context)
char buf[1024];
/* load the window widget */
FramePtr window(load_widget("duplicate_sprite.xml", "duplicate_sprite"));
UniquePtr<Frame> window(app::load_widget<Frame>("duplicate_sprite.xml", "duplicate_sprite"));
src_name = window->findChild("src_name");
dst_name = window->findChild("dst_name");

View File

@ -307,7 +307,7 @@ bool ExportSpriteSheetCommand::onEnabled(Context* context)
void ExportSpriteSheetCommand::onExecute(Context* context)
{
FramePtr frame(new ExportSpriteSheetFrame(context));
UniquePtr<Frame> frame(new ExportSpriteSheetFrame(context));
frame->open_window_fg();
}

View File

@ -18,12 +18,13 @@
#include "config.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/convert_to.h"
#include "commands/command.h"
#include "commands/params.h"
#include "document_wrappers.h"
#include "gui/gui.h"
#include "modules/gui.h"
#include "raster/sprite.h"
#include "undo_transaction.h"
@ -82,13 +83,11 @@ void FramePropertiesCommand::onExecute(Context* context)
{
const ActiveDocumentReader document(context);
const Sprite* sprite = document->getSprite();
JWidget frame, frlen, ok;
FramePtr window(load_widget("frame_duration.xml", "frame_duration"));
get_widgets(window,
"frame", &frame,
"frlen", &frlen,
"ok", &ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("frame_duration.xml", "frame_duration"));
Widget* frame = app::find_widget<Widget>(window, "frame");
Widget* frlen = app::find_widget<Widget>(window, "frlen");
Widget* ok = app::find_widget<Widget>(window, "ok");
int sprite_frame = 0;
switch (m_frame) {

View File

@ -18,6 +18,8 @@
#include "config.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "commands/params.h"
#include "document_wrappers.h"
@ -231,11 +233,9 @@ bool GotoFrameCommand::onEnabled(Context* context)
void GotoFrameCommand::onExecute(Context* context)
{
if (m_frame == 0 && context->isUiAvailable()) {
Widget* frame, *ok;
FramePtr window(load_widget("goto_frame.xml", "goto_frame"));
get_widgets(window,
"frame", &frame,
"ok", &ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("goto_frame.xml", "goto_frame"));
Widget* frame = app::find_widget<Widget>(window, "frame");
Widget* ok = app::find_widget<Widget>(window, "ok");
frame->setTextf("%d", context->getActiveDocument()->getSprite()->getCurrentFrame()+1);

View File

@ -20,16 +20,16 @@
#include <allegro/unicode.h>
#include "gui/frame.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "context.h"
#include "app.h"
#include "gui/frame.h"
#include "modules/editors.h"
#include "modules/gui.h"
#include "settings/settings.h"
#include "widgets/statebar.h"
#include "ui_context.h"
#include "widgets/statebar.h"
using namespace gfx;
@ -131,15 +131,12 @@ bool GridSettingsCommand::onEnabled(Context* context)
void GridSettingsCommand::onExecute(Context* context)
{
JWidget grid_x, grid_y, grid_w, grid_h, button_ok;
FramePtr window(load_widget("grid_settings.xml", "grid_settings"));
get_widgets(window,
"ok", &button_ok,
"grid_x", &grid_x,
"grid_y", &grid_y,
"grid_w", &grid_w,
"grid_h", &grid_h, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("grid_settings.xml", "grid_settings"));
Widget* button_ok = app::find_widget<Widget>(window, "ok");
Widget* grid_x = app::find_widget<Widget>(window, "grid_x");
Widget* grid_y = app::find_widget<Widget>(window, "grid_y");
Widget* grid_w = app::find_widget<Widget>(window, "grid_w");
Widget* grid_h = app::find_widget<Widget>(window, "grid_h");
Rect bounds = UIContext::instance()->getSettings()->getGridBounds();

View File

@ -22,7 +22,6 @@
#include "commands/command.h"
#include "commands/commands.h"
#include "commands/params.h"
#include "dialogs/filesel.h"
#include "document_wrappers.h"
#include "gui/gui.h"
#include "ini_file.h"
@ -358,7 +357,7 @@ ImportSpriteSheetCommand::ImportSpriteSheetCommand()
void ImportSpriteSheetCommand::onExecute(Context* context)
{
FramePtr frame(new ImportSpriteSheetFrame(context));
UniquePtr<Frame> frame(new ImportSpriteSheetFrame(context));
frame->open_window_fg();
}

View File

@ -62,7 +62,7 @@ void LayerPropertiesCommand::onExecute(Context* context)
const Sprite* sprite(document->getSprite());
const Layer* layer = sprite->getCurrentLayer();
FramePtr window(new Frame(false, "Layer Properties"));
UniquePtr<Frame> window(new Frame(false, "Layer Properties"));
Box* box1 = new Box(JI_VERTICAL);
Box* box2 = new Box(JI_HORIZONTAL);
Box* box3 = new Box(JI_HORIZONTAL + JI_HOMOGENEOUS);

View File

@ -18,9 +18,9 @@
#include "config.h"
#include "app/file_selector.h"
#include "commands/command.h"
#include "commands/params.h"
#include "dialogs/filesel.h"
#include "document_wrappers.h"
#include "gui/alert.h"
#include "modules/gui.h"
@ -70,7 +70,7 @@ void LoadMaskCommand::onExecute(Context* context)
base::string filename = m_filename;
if (context->isUiAvailable()) {
filename = ase_file_selector("Load .msk File", filename, "msk");
filename = app::show_file_selector("Load .msk File", filename, "msk");
if (filename.empty())
return;

View File

@ -21,6 +21,8 @@
#include "app.h"
#include "app/color.h"
#include "app/color_utils.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/unique_ptr.h"
#include "commands/command.h"
#include "console.h"
@ -28,7 +30,6 @@
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/editors.h"
#include "modules/gui.h"
#include "modules/palettes.h"
#include "raster/image.h"
#include "raster/layer.h"
@ -68,8 +69,6 @@ NewFileCommand::NewFileCommand()
*/
void NewFileCommand::onExecute(Context* context)
{
JWidget width, height, radio1, radio2, radio3, colors, ok;
ListBox* bg_box;
PixelFormat format;
int w, h, bg, ncolors;
char buf[1024];
@ -82,16 +81,15 @@ void NewFileCommand::onExecute(Context* context)
};
// Load the window widget
FramePtr window(load_widget("new_sprite.xml", "new_sprite"));
get_widgets(window,
"width", &width,
"height", &height,
"radio1", &radio1,
"radio2", &radio2,
"radio3", &radio3,
"colors", &colors,
"ok_button", &ok,
"bg_box", &bg_box, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("new_sprite.xml", "new_sprite"));
Widget* width = app::find_widget<Widget>(window, "width");
Widget* height = app::find_widget<Widget>(window, "height");
Widget* radio1 = app::find_widget<Widget>(window, "radio1");
Widget* radio2 = app::find_widget<Widget>(window, "radio2");
Widget* radio3 = app::find_widget<Widget>(window, "radio3");
Widget* colors = app::find_widget<Widget>(window, "colors");
ListBox* bg_box = app::find_widget<ListBox>(window, "bg_box");
Widget* ok = app::find_widget<Widget>(window, "ok_button");
// Default values: Indexed, 320x240, Background color
format = static_cast<PixelFormat>(get_config_int("NewSprite", "Type", IMAGE_INDEXED));

View File

@ -19,6 +19,8 @@
#include "config.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "commands/params.h"
#include "document_wrappers.h"
@ -89,8 +91,8 @@ void NewLayerCommand::onExecute(Context* context)
// If params specify to ask the user about the name...
if (m_ask) {
// We open the window to ask the name
FramePtr window(load_widget("new_layer.xml", "new_layer"));
JWidget name_widget = find_widget(window, "name");
UniquePtr<Frame> window(app::load_widget<Frame>("new_layer.xml", "new_layer"));
Widget* name_widget = app::find_widget<Widget>(window, "name");
name_widget->setText(name.c_str());
jwidget_set_min_size(name_widget, 128, 0);

View File

@ -18,14 +18,15 @@
#include "config.h"
#include "gui/gui.h"
#include "commands/command.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/command.h"
#include "document_wrappers.h"
#include "gui/gui.h"
#include "modules/gui.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "document_wrappers.h"
//////////////////////////////////////////////////////////////////////
// new_layer_set
@ -60,7 +61,7 @@ void NewLayerSetCommand::onExecute(Context* context)
Sprite* sprite(document->getSprite());
// load the window widget
FramePtr window(load_widget("new_layer.xml", "new_layer_set"));
UniquePtr<Frame> window(app::load_widget<Frame>("new_layer.xml", "new_layer_set"));
window->open_window_fg();

View File

@ -22,11 +22,11 @@
#include <stdio.h>
#include "app.h"
#include "app/file_selector.h"
#include "base/thread.h"
#include "commands/command.h"
#include "commands/params.h"
#include "console.h"
#include "dialogs/filesel.h"
#include "document.h"
#include "file/file.h"
#include "gui/gui.h"
@ -143,7 +143,7 @@ void OpenFileCommand::onExecute(Context* context)
if (context->isUiAvailable() && m_filename.empty()) {
char exts[4096];
get_readable_extensions(exts, sizeof(exts));
m_filename = ase_file_selector("Open", "", exts);
m_filename = app::show_file_selector("Open", "", exts);
}
if (!m_filename.empty()) {

View File

@ -18,22 +18,22 @@
#include "config.h"
#include <allegro.h>
#include "base/bind.h"
#include "gui/gui.h"
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "commands/command.h"
#include "context.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/editors.h"
#include "modules/gui.h"
#include "raster/image.h"
#include "util/render.h"
#include "widgets/color_button.h"
#include "widgets/editor/editor.h"
#include <allegro.h>
//////////////////////////////////////////////////////////////////////
// options
@ -64,49 +64,35 @@ OptionsCommand::OptionsCommand()
void OptionsCommand::onExecute(Context* context)
{
JWidget check_smooth;
ColorButton* cursor_color;
ColorButton* grid_color;
ColorButton* pixel_grid_color;
Widget* cursor_color_box;
Widget* grid_color_box;
Widget* pixel_grid_color_box;
Button* button_ok;
Widget* move_click2, *draw_click2;
Button* checked_bg_reset;
JWidget checked_bg_color1_box, checked_bg_color2_box;
JWidget undo_size_limit;
/* load the window widget */
FramePtr window(load_widget("options.xml", "options"));
get_widgets(window,
"smooth", &check_smooth,
"move_click2", &move_click2,
"draw_click2", &draw_click2,
"cursor_color_box", &cursor_color_box,
"grid_color_box", &grid_color_box,
"pixel_grid_color_box", &pixel_grid_color_box,
"checked_bg_size", &m_checked_bg,
"checked_bg_zoom", &m_checked_bg_zoom,
"checked_bg_color1_box", &checked_bg_color1_box,
"checked_bg_color2_box", &checked_bg_color2_box,
"checked_bg_reset", &checked_bg_reset,
"undo_size_limit", &undo_size_limit,
"button_ok", &button_ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("options.xml", "options"));
Widget* check_smooth = app::find_widget<Widget>(window, "smooth");
Widget* move_click2 = app::find_widget<Widget>(window, "move_click2");
Widget* draw_click2 = app::find_widget<Widget>(window, "draw_click2");
Widget* cursor_color_box = app::find_widget<Widget>(window, "cursor_color_box");
Widget* grid_color_box = app::find_widget<Widget>(window, "grid_color_box");
Widget* pixel_grid_color_box = app::find_widget<Widget>(window, "pixel_grid_color_box");
m_checked_bg = app::find_widget<ComboBox>(window, "checked_bg_size");
m_checked_bg_zoom = app::find_widget<Widget>(window, "checked_bg_zoom");
Widget* checked_bg_color1_box = app::find_widget<Widget>(window, "checked_bg_color1_box");
Widget* checked_bg_color2_box = app::find_widget<Widget>(window, "checked_bg_color2_box");
Button* checked_bg_reset = app::find_widget<Button>(window, "checked_bg_reset");
Widget* undo_size_limit = app::find_widget<Widget>(window, "undo_size_limit");
Widget* button_ok = app::find_widget<Widget>(window, "button_ok");
// Cursor color
cursor_color = new ColorButton(Editor::get_cursor_color(), IMAGE_RGB);
cursor_color->setName("cursor_color");
ColorButton* cursor_color = new ColorButton(Editor::get_cursor_color(), IMAGE_RGB);
cursor_color->setId("cursor_color");
cursor_color_box->addChild(cursor_color);
// Grid color
grid_color = new ColorButton(context->getSettings()->getGridColor(), IMAGE_RGB);
grid_color->setName("grid_color");
ColorButton* grid_color = new ColorButton(context->getSettings()->getGridColor(), IMAGE_RGB);
grid_color->setId("grid_color");
grid_color_box->addChild(grid_color);
// Pixel grid color
pixel_grid_color = new ColorButton(context->getSettings()->getPixelGridColor(), IMAGE_RGB);
pixel_grid_color->setName("pixel_grid_color");
ColorButton* pixel_grid_color = new ColorButton(context->getSettings()->getPixelGridColor(), IMAGE_RGB);
pixel_grid_color->setId("pixel_grid_color");
pixel_grid_color_box->addChild(pixel_grid_color);
// Others

View File

@ -21,12 +21,12 @@
#include "app.h"
#include "app/color.h"
#include "app/color_utils.h"
#include "app/file_selector.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "commands/command.h"
#include "commands/params.h"
#include "console.h"
#include "dialogs/filesel.h"
#include "document_wrappers.h"
#include "gfx/hsv.h"
#include "gfx/rgb.h"
@ -578,7 +578,7 @@ void PaletteEntryEditor::onPasteColorsClick(Event& ev)
void PaletteEntryEditor::onLoadPaletteClick(Event& ev)
{
Palette *palette;
base::string filename = ase_file_selector("Load Palette", "", "png,pcx,bmp,tga,lbm,col");
base::string filename = app::show_file_selector("Load Palette", "", "png,pcx,bmp,tga,lbm,col");
if (!filename.empty()) {
palette = Palette::load(filename.c_str());
if (!palette) {
@ -597,7 +597,7 @@ void PaletteEntryEditor::onSavePaletteClick(Event& ev)
int ret;
again:
filename = ase_file_selector("Save Palette", "", "png,pcx,bmp,tga,col");
filename = app::show_file_selector("Save Palette", "", "png,pcx,bmp,tga,col");
if (!filename.empty()) {
if (exists(filename.c_str())) {
ret = Alert::show("Warning<<File exists, overwrite it?<<%s||&Yes||&No||&Cancel",

View File

@ -21,16 +21,16 @@
#include <allegro.h>
#include "app.h"
#include "app/file_selector.h"
#include "base/thread.h"
#include "commands/command.h"
#include "console.h"
#include "dialogs/filesel.h"
#include "document_wrappers.h"
#include "file/file.h"
#include "gui/gui.h"
#include "modules/gui.h"
#include "raster/sprite.h"
#include "recent_files.h"
#include "document_wrappers.h"
#include "widgets/statebar.h"
struct SaveFileData
@ -154,7 +154,7 @@ static void save_as_dialog(const DocumentReader& document, const char* dlg_title
get_writable_extensions(exts, sizeof(exts));
for (;;) {
newfilename = ase_file_selector(dlg_title, filename, exts);
newfilename = app::show_file_selector(dlg_title, filename, exts);
if (newfilename.empty())
return;

View File

@ -20,12 +20,12 @@
#include <allegro/file.h>
#include "app/file_selector.h"
#include "commands/command.h"
#include "dialogs/filesel.h"
#include "document_wrappers.h"
#include "gui/alert.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "document_wrappers.h"
#include "util/msk_file.h"
//////////////////////////////////////////////////////////////////////
@ -61,7 +61,7 @@ void SaveMaskCommand::onExecute(Context* context)
int ret;
for (;;) {
filename = ase_file_selector("Save .msk File", filename, "msk");
filename = app::show_file_selector("Save .msk File", filename, "msk");
if (filename.empty())
return;

View File

@ -18,21 +18,22 @@
#include "config.h"
#include <allegro/unicode.h>
#include "base/bind.h"
#include "gui/gui.h"
#include "app/color.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "base/mem_utils.h"
#include "commands/command.h"
#include "document_wrappers.h"
#include "gui/gui.h"
#include "modules/gui.h"
#include "raster/image.h"
#include "raster/palette.h"
#include "raster/sprite.h"
#include "document_wrappers.h"
#include "widgets/color_button.h"
#include <allegro/unicode.h>
//////////////////////////////////////////////////////////////////////
// sprite_properties
@ -68,14 +69,13 @@ void SpritePropertiesCommand::onExecute(Context* context)
ColorButton* color_button = NULL;
// Load the window widget
FramePtr window(load_widget("sprite_properties.xml", "sprite_properties"));
get_widgets(window,
"name", &name,
"type", &type,
"size", &size,
"frames", &frames,
"ok", &ok,
"box_transparent", &box_transparent, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("sprite_properties.xml", "sprite_properties"));
name = app::find_widget<Widget>(window, "name");
type = app::find_widget<Widget>(window, "type");
size = app::find_widget<Widget>(window, "size");
frames = app::find_widget<Widget>(window, "frames");
ok = app::find_widget<Widget>(window, "ok");
box_transparent = app::find_widget<Widget>(window, "box_transparent");
// Get sprite properties and fill frame fields
{

View File

@ -18,6 +18,8 @@
#include "config.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "base/unique_ptr.h"
#include "commands/command.h"
@ -189,21 +191,18 @@ bool SpriteSizeCommand::onEnabled(Context* context)
void SpriteSizeCommand::onExecute(Context* context)
{
Widget *ok;
ComboBox* method;
const ActiveDocumentReader document(context);
const Sprite* sprite(document ? document->getSprite(): 0);
// load the window widget
FramePtr window(load_widget("sprite_size.xml", "sprite_size"));
get_widgets(window,
"width_px", &m_widthPx,
"height_px", &m_heightPx,
"width_perc", &m_widthPerc,
"height_perc", &m_heightPerc,
"lock_ratio", &m_lockRatio,
"method", &method,
"ok", &ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("sprite_size.xml", "sprite_size"));
m_widthPx = app::find_widget<Entry>(window, "width_px");
m_heightPx = app::find_widget<Entry>(window, "height_px");
m_widthPerc = app::find_widget<Entry>(window, "width_perc");
m_heightPerc = app::find_widget<Entry>(window, "height_perc");
m_lockRatio = app::find_widget<CheckBox>(window, "lock_ratio");
ComboBox* method = app::find_widget<ComboBox>(window, "method");
Widget* ok = app::find_widget<Widget>(window, "ok");
m_widthPx->setTextf("%d", sprite->getWidth());
m_heightPx->setTextf("%d", sprite->getHeight());

View File

@ -21,6 +21,8 @@
#include <string.h>
#include "app/color.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "commands/command.h"
#include "commands/filters/convolution_matrix_stock.h"
@ -38,7 +40,6 @@
#include "gui/view.h"
#include "gui/widget.h"
#include "ini_file.h"
#include "modules/gui.h"
#include "raster/mask.h"
#include "raster/sprite.h"
@ -56,20 +57,16 @@ public:
WithTiledCheckBox,
filter.getTiledMode())
, m_filter(filter)
, m_controlsWidget(load_widget("convolution_matrix.xml", "controls"))
, m_controlsWidget(app::load_widget<Widget>("convolution_matrix.xml", "controls"))
, m_stock(stock)
, m_view(app::find_widget<View>(m_controlsWidget, "view"))
, m_stockListBox(app::find_widget<ListBox>(m_controlsWidget, "stock"))
, m_reloadButton(app::find_widget<Button>(m_controlsWidget, "reload"))
{
get_widgets(m_controlsWidget,
"view", &m_view,
"stock", &m_stockListBox,
"reload", &m_reloadButton, NULL);
getContainer()->addChild(m_controlsWidget);
m_reloadButton->Click.connect(&ConvolutionMatrixWindow::onReloadStock, this);
// TODO convert listbox to c++ class ListBox
//m_stockListBox->Change.connect(Bind<void>(&ConvolutionMatrixWindow::onMatrixChange, this));
hook_signal(m_stockListBox, JI_SIGNAL_LISTBOX_CHANGE, &ConvolutionMatrixWindow::listboxChangeHandler, this);
m_stockListBox->ChangeSelectedItem.connect(Bind<void>(&ConvolutionMatrixWindow::onMatrixChange, this));
fillStockListBox();
}
@ -145,16 +142,8 @@ private:
restartPreview();
}
// TODO This function must be removed if ListBox C++ class is added.
static bool listboxChangeHandler(Widget* widget, void *data)
{
ConvolutionMatrixWindow* window = (ConvolutionMatrixWindow*)data;
window->onMatrixChange();
return true;
}
ConvolutionMatrixFilter& m_filter;
WidgetPtr m_controlsWidget;
UniquePtr<Widget> m_controlsWidget;
ConvolutionMatrixStock& m_stock;
View* m_view;
ListBox* m_stockListBox;

View File

@ -20,6 +20,8 @@
#include <stdio.h>
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "commands/command.h"
#include "commands/filters/filter_manager_impl.h"
@ -32,7 +34,6 @@
#include "gui/grid.h"
#include "gui/widget.h"
#include "ini_file.h"
#include "modules/gui.h"
#include "raster/mask.h"
#include "raster/sprite.h"
#include "settings/settings.h"
@ -51,12 +52,10 @@ public:
WithTiledCheckBox,
filter.getTiledMode())
, m_filter(filter)
, m_controlsWidget(load_widget("despeckle.xml", "controls"))
, m_controlsWidget(app::load_widget<Widget>("despeckle.xml", "controls"))
, m_widthEntry(app::find_widget<Entry>(m_controlsWidget, "width"))
, m_heightEntry(app::find_widget<Entry>(m_controlsWidget, "height"))
{
get_widgets(m_controlsWidget,
"width", &m_widthEntry,
"height", &m_heightEntry, NULL);
getContainer()->addChild(m_controlsWidget);
m_widthEntry->setTextf("%d", m_filter.getWidth());
@ -80,7 +79,7 @@ private:
}
MedianFilter& m_filter;
WidgetPtr m_controlsWidget;
UniquePtr<Widget> m_controlsWidget;
Entry* m_widthEntry;
Entry* m_heightEntry;
};

View File

@ -23,6 +23,8 @@
#include "app.h"
#include "app/color.h"
#include "app/color_utils.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/bind.h"
#include "commands/command.h"
#include "commands/filters/filter_manager_impl.h"
@ -31,7 +33,6 @@
#include "filters/replace_color_filter.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/gui.h"
#include "raster/image.h"
#include "raster/mask.h"
#include "raster/sprite.h"
@ -77,13 +78,11 @@ public:
WithChannelsSelector,
WithoutTiledCheckBox)
, m_filter(filter)
, m_controlsWidget(load_widget("replace_color.xml", "controls"))
, m_controlsWidget(app::load_widget<Widget>("replace_color.xml", "controls"))
, m_fromButton(app::find_widget<ColorButton>(m_controlsWidget, "from"))
, m_toButton(app::find_widget<ColorButton>(m_controlsWidget, "to"))
, m_toleranceSlider(app::find_widget<Slider>(m_controlsWidget, "tolerance"))
{
get_widgets(m_controlsWidget,
"from", &m_fromButton,
"to", &m_toButton,
"tolerance", &m_toleranceSlider, NULL);
getContainer()->addChild(m_controlsWidget);
m_fromButton->setColor(m_filter.getFrom());
@ -116,7 +115,7 @@ protected:
private:
ReplaceColorFilterWrapper& m_filter;
WidgetPtr m_controlsWidget;
UniquePtr<Widget> m_controlsWidget;
ColorButton* m_fromButton;
ColorButton* m_toButton;
Slider* m_toleranceSlider;

View File

@ -18,12 +18,8 @@
#include "config.h"
#include <allegro.h>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "commands/filters/color_curve_editor.h"
#include "filters/color_curve.h"
#include "gui/alert.h"
@ -35,7 +31,12 @@
#include "gui/system.h"
#include "gui/view.h"
#include "gui/widget.h"
#include "modules/gui.h"
#include <allegro.h>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>
#define SCR2EDIT_X(xpos) \
(m_x1 + \
@ -356,7 +357,7 @@ int ColorCurveEditor::editNodeManually(gfx::Point& point)
gfx::Point point_copy = point;
int res;
FramePtr window(load_widget("color_curve.xml", "point_properties"));
UniquePtr<Frame> window(app::load_widget<Frame>("color_curve.xml", "point_properties"));
entry_x = window->findChild("x");
entry_y = window->findChild("y");

View File

@ -67,17 +67,17 @@ FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
g = check_button_new("G", 0, 0, 0, 0);
b = check_button_new("B", 0, (imgtype == IMAGE_RGB) ? 0: 2, 0, 0);
r->setName("r");
g->setName("g");
b->setName("b");
r->setId("r");
g->setId("g");
b->setId("b");
if (imgtype == IMAGE_RGB) {
a = check_button_new("A", 0, 2, 0, 0);
a->setName("a");
a->setId("a");
}
else {
index = check_button_new("Index", 0, 0, 0, 0);
index->setName("i");
index->setId("i");
}
break;
@ -85,8 +85,8 @@ FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
k = check_button_new("K", 2, 0, 0, 0);
a = check_button_new("A", 0, 2, 0, 0);
k->setName("k");
a->setName("a");
k->setId("k");
a->setId("a");
break;
}
}
@ -133,15 +133,16 @@ void FilterTargetButtons::setTarget(int target)
void FilterTargetButtons::selectTargetButton(const char* name, int specificTarget)
{
Widget* wgt = findChild(name);
if (wgt != NULL)
if (wgt != NULL) {
wgt->setSelected((m_target & specificTarget) == specificTarget);
}
}
void FilterTargetButtons::onChannelChange(ButtonBase* button)
{
int flag = 0;
switch (button->name[0]) {
switch (button->getId()[0]) {
case 'r': flag = TARGET_RED_CHANNEL; break;
case 'g': flag = TARGET_GREEN_CHANNEL; break;
case 'b': flag = TARGET_BLUE_CHANNEL; break;

View File

@ -1,734 +0,0 @@
/* ASEPRITE
* Copyright (C) 2001-2012 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <algorithm>
#include <cctype>
#include <iterator>
#include <set>
#include <string>
#include <vector>
#include <allegro.h>
#include <allegro/internal/aintern.h>
#include <errno.h>
#include "app.h"
#include "base/bind.h"
#include "base/path.h"
#include "base/split_string.h"
#include "file/file.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/gfx.h"
#include "modules/gui.h"
#include "recent_files.h"
#include "skin/skin_parts.h"
#include "widgets/fileview.h"
#if (DEVICE_SEPARATOR != 0) && (DEVICE_SEPARATOR != '\0')
# define HAVE_DRIVES
#endif
#ifndef MAX_PATH
# define MAX_PATH 4096 /* TODO this is needed for Linux, is it correct? */
#endif
template<class Container>
class NullableIterator
{
public:
typedef typename Container::iterator iterator;
NullableIterator() : m_isNull(true) { }
void reset() { m_isNull = true; }
bool isNull() const { return m_isNull; }
bool isValid() const { return !m_isNull; }
iterator getIterator() {
ASSERT(!m_isNull);
return m_iterator;
}
void setIterator(const iterator& it) {
m_isNull = false;
m_iterator = it;
}
private:
bool m_isNull;
typename Container::iterator m_iterator;
};
// Variables used only to maintain the history of navigation.
static FileItemList* navigation_history = NULL; // Set of FileItems navigated
static NullableIterator<FileItemList> navigation_position; // Current position in the navigation history
static bool navigation_locked = false; // If true the navigation_history isn't
// modified if the current folder changes
//(used when the back/forward buttons
// are pushed)
static void update_location(Widget* window);
static void update_navigation_buttons(Widget* window);
static void add_in_navigation_history(IFileItem* folder);
static void select_filetype_from_filename(Widget* window);
static void goback_command(Widget* widget);
static void goforward_command(Widget* widget);
static void goup_command(Widget* widget);
static bool fileview_msg_proc(Widget* widget, Message* msg);
static bool location_msg_proc(Widget* widget, Message* msg);
static bool filetype_msg_proc(Widget* widget, Message* msg);
static bool filename_msg_proc(Widget* widget, Message* msg);
// Slot for App::Exit signal
static void on_exit_delete_navigation_history()
{
delete navigation_history;
}
/**
* Shows the dialog to select a file in ASE.
*
* Mainly it uses:
* - the 'file_system' routines.
* - the 'widgets/fileview' widget.
*/
base::string ase_file_selector(const base::string& message,
const base::string& init_path,
const base::string& exts)
{
static Frame* window = NULL;
Widget* fileview;
Entry* filename_entry;
ComboBox* filetype;
base::string result;
FileSystemModule::instance()->refresh();
if (!navigation_history) {
navigation_history = new FileItemList();
App::instance()->Exit.connect(&on_exit_delete_navigation_history);
}
// we have to find where the user should begin to browse files (start_folder)
base::string start_folder_path;
IFileItem* start_folder = NULL;
// if init_path doesn't contain a path...
if (base::get_file_path(init_path).empty()) {
// get the saved `path' in the configuration file
base::string path = get_config_string("FileSelect", "CurrentDirectory", "");
start_folder = FileSystemModule::instance()->getFileItemFromPath(path);
// is the folder find?
if (!start_folder) {
// if the `path' doesn't exist...
if (path.empty() || (!FileSystemModule::instance()->dirExists(path))) {
// we can get the current `path' from the system
#ifdef HAVE_DRIVES
int drive = _al_getdrive();
#else
int drive = 0;
#endif
char tmp[1024];
_al_getdcwd(drive, tmp, sizeof(tmp) - ucwidth(OTHER_PATH_SEPARATOR));
path = tmp;
}
start_folder_path = base::join_path(path, init_path);
}
}
else {
// remove the filename
start_folder_path = base::join_path(base::get_file_path(init_path), "");
}
start_folder_path = base::fix_path_separators(start_folder_path);
if (!start_folder)
start_folder = FileSystemModule::instance()->getFileItemFromPath(start_folder_path);
PRINTF("start_folder_path = %s (%p)\n", start_folder_path.c_str(), start_folder);
if (!window) {
// load the window widget
window = static_cast<Frame*>(load_widget("file_selector.xml", "file_selector"));
Widget* box = window->findChild("box");
Button* goback = window->findChildT<Button>("goback");
Button* goforward = window->findChildT<Button>("goforward");
Button* goup = window->findChildT<Button>("goup");
Widget* location = window->findChild("location");
filetype = window->findChildT<ComboBox>("filetype");
ASSERT(filetype != NULL);
filename_entry = window->findChildT<Entry>("filename");
goback->setFocusStop(false);
goforward->setFocusStop(false);
goup->setFocusStop(false);
set_gfxicon_to_button(goback,
PART_COMBOBOX_ARROW_LEFT,
PART_COMBOBOX_ARROW_LEFT_SELECTED,
PART_COMBOBOX_ARROW_LEFT_DISABLED,
JI_CENTER | JI_MIDDLE);
set_gfxicon_to_button(goforward,
PART_COMBOBOX_ARROW_RIGHT,
PART_COMBOBOX_ARROW_RIGHT_SELECTED,
PART_COMBOBOX_ARROW_RIGHT_DISABLED,
JI_CENTER | JI_MIDDLE);
set_gfxicon_to_button(goup,
PART_COMBOBOX_ARROW_UP,
PART_COMBOBOX_ARROW_UP_SELECTED,
PART_COMBOBOX_ARROW_UP_DISABLED,
JI_CENTER | JI_MIDDLE);
setup_mini_look(goback);
setup_mini_look(goforward);
setup_mini_look(goup);
goback->Click.connect(Bind<void>(&goback_command, goback));
goforward->Click.connect(Bind<void>(&goforward_command, goforward));
goup->Click.connect(Bind<void>(&goup_command, goup));
View* view = new View();
fileview = fileview_new(start_folder, exts);
jwidget_add_hook(fileview, -1, fileview_msg_proc, NULL);
jwidget_add_hook(location, -1, location_msg_proc, NULL);
jwidget_add_hook(filetype, -1, filetype_msg_proc, NULL);
jwidget_add_hook(filename_entry, -1, filename_msg_proc, NULL);
fileview->setName("fileview");
view->attachToView(fileview);
view->setExpansive(true);
box->addChild(view);
jwidget_set_min_size(window, JI_SCREEN_W*9/10, JI_SCREEN_H*9/10);
window->remap_window();
window->center_window();
}
else {
fileview = window->findChild("fileview");
filetype = window->findChildT<ComboBox>("filetype");
ASSERT(filetype != NULL);
filename_entry = window->findChildT<Entry>("filename");
jwidget_signal_off(fileview);
fileview_set_current_folder(fileview, start_folder);
jwidget_signal_on(fileview);
}
// current location
navigation_position.reset();
add_in_navigation_history(fileview_get_current_folder(fileview));
// fill the location combo-box
update_location(window);
update_navigation_buttons(window);
// fill file-type combo-box
filetype->removeAllItems();
std::vector<base::string> tokens;
std::vector<base::string>::iterator tok;
base::split_string(exts, tokens, ",");
for (tok=tokens.begin(); tok!=tokens.end(); ++tok)
filetype->addItem(tok->c_str());
// file name entry field
filename_entry->setText(base::get_file_name(init_path).c_str());
select_filetype_from_filename(window);
filename_entry->selectText(0, -1);
// setup the title of the window
window->setText(message.c_str());
// get the ok-button
Widget* ok = window->findChild("ok");
// update the view
View::getView(fileview)->updateView();
// open the window and run... the user press ok?
again:
window->open_window_fg();
if (window->get_killer() == ok ||
window->get_killer() == fileview) {
// open the selected file
IFileItem *folder = fileview_get_current_folder(fileview);
ASSERT(folder);
base::string fn = filename_entry->getText();
base::string buf;
IFileItem* enter_folder = NULL;
// up a level?
if (fn == "..") {
enter_folder = folder->getParent();
if (!enter_folder)
enter_folder = folder;
}
else if (!fn.empty()) {
// check if the user specified in "fn" a item of "fileview"
const FileItemList& children = fileview_get_filelist(fileview);
base::string fn2 = fn;
#ifdef WIN32
fn2 = base::string_to_lower(fn2);
#endif
for (FileItemList::const_iterator
it=children.begin(); it!=children.end(); ++it) {
IFileItem* child = *it;
base::string child_name = child->getDisplayName();
#ifdef WIN32
child_name = base::string_to_lower(child_name);
#endif
if (child_name == fn2) {
enter_folder = *it;
buf = enter_folder->getFileName();
break;
}
}
if (!enter_folder) {
// does the file-name entry have separators?
if (base::is_path_separator(*fn.begin())) { // absolute path (UNIX style)
#ifdef WIN32
// get the drive of the current folder
base::string drive = folder->getFileName();
if (drive.size() >= 2 && drive[1] == ':') {
buf += drive[0];
buf += ':';
buf += fn;
}
else
buf = base::join_path("C:", fn);
#else
buf = fn;
#endif
}
#ifdef WIN32
// does the file-name entry have colon?
else if (fn.find(':') != base::string::npos) { // absolute path on Windows
if (fn.size() == 2 && fn[1] == ':') {
buf = base::join_path(fn, "");
}
else {
buf = fn;
}
}
#endif
else {
buf = folder->getFileName();
buf = base::join_path(buf, fn);
}
buf = base::fix_path_separators(buf);
// we can check if 'buf' is a folder, so we have to enter in it
enter_folder = FileSystemModule::instance()->getFileItemFromPath(buf);
}
}
else {
// show the window again
window->setVisible(true);
goto again;
}
// did we find a folder to enter?
if (enter_folder &&
enter_folder->isFolder() &&
enter_folder->isBrowsable()) {
// enter in the folder that was specified in the 'filename_entry'
fileview_set_current_folder(fileview, enter_folder);
// clear the text of the entry widget
filename_entry->setText("");
// show the window again
window->setVisible(true);
goto again;
}
// else file-name specified in the entry is really a file to open...
// does it not have extension? ...we should add the extension
// selected in the filetype combo-box
if (base::get_file_extension(buf).empty()) {
buf += '.';
buf += filetype->getItemText(filetype->getSelectedItem());
}
// duplicate the buffer to return a new string
result = buf;
// save the path in the configuration file
base::string lastpath = folder->getKeyName();
set_config_string("FileSelect", "CurrentDirectory",
lastpath.c_str());
}
delete window;
window = NULL;
return result;
}
/**
* Updates the content of the combo-box that shows the current
* location in the file-system.
*/
static void update_location(Widget* window)
{
Widget* fileview = window->findChild("fileview");
ComboBox* location = dynamic_cast<ComboBox*>(window->findChild("location"));
ASSERT(location != NULL);
IFileItem* current_folder = fileview_get_current_folder(fileview);
IFileItem* fileitem = current_folder;
JList locations = jlist_new();
JLink link;
int selected_index = -1;
int newItem;
while (fileitem != NULL) {
jlist_prepend(locations, fileitem);
fileitem = fileitem->getParent();
}
// Clear all the items from the combo-box
location->removeAllItems();
// Add item by item (from root to the specific current folder)
int level = 0;
JI_LIST_FOR_EACH(locations, link) {
fileitem = reinterpret_cast<IFileItem*>(link->data);
// Indentation
base::string buf;
for (int c=0; c<level; ++c)
buf += " ";
// Location name
buf += fileitem->getDisplayName();
// Add the new location to the combo-box
newItem = location->addItem(buf.c_str());
location->setItemData(newItem, fileitem);
if (fileitem == current_folder)
selected_index = level;
level++;
}
// Add paths from recent files list
{
newItem = location->addItem("");
newItem = location->addItem("-------- Recent Paths --------");
RecentFiles::const_iterator it = App::instance()->getRecentFiles()->paths_begin();
RecentFiles::const_iterator end = App::instance()->getRecentFiles()->paths_end();
for (; it != end; ++it)
location->addItem(*it);
}
// Select the location
{
jwidget_signal_off(location);
location->setSelectedItem(selected_index);
location->getEntryWidget()->setText(current_folder->getDisplayName().c_str());
location->getEntryWidget()->deselectText();
jwidget_signal_on(location);
}
jlist_free(locations);
}
static void update_navigation_buttons(Widget* window)
{
Widget* fileview = window->findChild("fileview");
Widget* goback = window->findChild("goback");
Widget* goforward = window->findChild("goforward");
Widget* goup = window->findChild("goup");
IFileItem* current_folder = fileview_get_current_folder(fileview);
// Update the state of the go back button: if the navigation-history
// has two elements and the navigation-position isn't the first one.
goback->setEnabled(navigation_history->size() > 1 &&
(navigation_position.isNull() ||
navigation_position.getIterator() != navigation_history->begin()));
// Update the state of the go forward button: if the
// navigation-history has two elements and the navigation-position
// isn't the last one.
goforward->setEnabled(navigation_history->size() > 1 &&
(navigation_position.isNull() ||
navigation_position.getIterator() != navigation_history->end()-1));
// Update the state of the go up button: if the current-folder isn't
// the root-item
goup->setEnabled(current_folder != FileSystemModule::instance()->getRootFileItem());
}
static void add_in_navigation_history(IFileItem* folder)
{
ASSERT(folder != NULL);
ASSERT(folder->isFolder());
// Remove the history from the current position
if (navigation_position.isValid()) {
navigation_history->erase(navigation_position.getIterator()+1, navigation_history->end());
navigation_position.reset();
}
// If the history is empty or if the last item isn't the folder that
// we are visiting...
if (navigation_history->empty() ||
navigation_history->back() != folder) {
// We can add the location in the history
navigation_history->push_back(folder);
navigation_position.setIterator(navigation_history->end()-1);
}
}
static void select_filetype_from_filename(Widget* window)
{
Widget* entry = window->findChild("filename");
ComboBox* filetype = dynamic_cast<ComboBox*>(window->findChild("filetype"));
ASSERT(filetype != NULL);
const char *filename = entry->getText();
char *p = get_extension(filename);
char buf[MAX_PATH];
if (p && *p != 0) {
ustrcpy(buf, get_extension(filename));
ustrlwr(buf);
filetype->setSelectedItem(filetype->findItemIndex(buf));
}
}
static void goback_command(Widget* widget)
{
Widget* fileview = widget->findSibling("fileview");
if (navigation_history->size() > 1) {
if (navigation_position.isNull())
navigation_position.setIterator(navigation_history->end()-1);
if (navigation_position.getIterator() != navigation_history->begin()) {
navigation_position.setIterator(navigation_position.getIterator()-1);
navigation_locked = true;
fileview_set_current_folder(fileview, *navigation_position.getIterator());
navigation_locked = false;
}
}
}
static void goforward_command(Widget* widget)
{
Widget* fileview = widget->findSibling("fileview");
if (jlist_length(navigation_history) > 1) {
if (navigation_position.isNull())
navigation_position.setIterator(navigation_history->begin());
if (navigation_position.getIterator() != navigation_history->end()-1) {
navigation_position.setIterator(navigation_position.getIterator()+1);
navigation_locked = true;
fileview_set_current_folder(fileview, *navigation_position.getIterator());
navigation_locked = false;
}
}
}
static void goup_command(Widget* widget)
{
Widget* fileview = widget->findSibling("fileview");
fileview_goup(fileview);
}
/* hook for the 'fileview' widget in the dialog */
static bool fileview_msg_proc(Widget* widget, Message* msg)
{
if (msg->type == JM_SIGNAL) {
switch (msg->signal.num) {
case SIGNAL_FILEVIEW_FILE_SELECTED: {
IFileItem* fileitem = fileview_get_selected(widget);
if (!fileitem->isFolder()) {
Frame* window = widget->getRoot();
Widget* entry = window->findChild("filename");
base::string filename = base::get_file_name(fileitem->getFileName());
entry->setText(filename.c_str());
select_filetype_from_filename(window);
}
break;
}
/* when a file is accepted */
case SIGNAL_FILEVIEW_FILE_ACCEPT:
widget->closeWindow();
break;
/* when the current folder change */
case SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED: {
Frame* window = widget->getRoot();
if (!navigation_locked)
add_in_navigation_history(fileview_get_current_folder(widget));
update_location(window);
update_navigation_buttons(window);
break;
}
}
}
return false;
}
// Hook for the 'location' combo-box
static bool location_msg_proc(Widget* widget, Message* msg)
{
if (msg->type == JM_SIGNAL) {
ComboBox* combobox = dynamic_cast<ComboBox*>(widget);
ASSERT(combobox != NULL);
switch (msg->signal.num) {
// When the user change the location we have to set the
// current-folder in the 'fileview' widget
case JI_SIGNAL_COMBOBOX_SELECT: {
int itemIndex = combobox->getSelectedItem();
IFileItem* fileitem = reinterpret_cast<IFileItem*>(combobox->getItemData(itemIndex));
// Maybe the user selected a recent file path
if (fileitem == NULL) {
base::string path = combobox->getItemText(itemIndex);
if (!path.empty())
fileitem = FileSystemModule::instance()->getFileItemFromPath(path);
}
if (fileitem != NULL) {
Widget* fileview = widget->findSibling("fileview");
fileview_set_current_folder(fileview, fileitem);
// Refocus the 'fileview' (the focus in that widget is more
// useful for the user)
widget->getManager()->setFocus(fileview);
}
break;
}
}
}
return false;
}
// Hook for the 'filetype' combo-box
static bool filetype_msg_proc(Widget* widget, Message* msg)
{
if (msg->type == JM_SIGNAL) {
ComboBox* combobox = dynamic_cast<ComboBox*>(widget);
ASSERT(combobox != NULL);
switch (msg->signal.num) {
// When the user select a new file-type (extension), we have to
// change the file-extension in the 'filename' entry widget
case JI_SIGNAL_COMBOBOX_SELECT: {
std::string ext = combobox->getItemText(combobox->getSelectedItem());
Frame* window = combobox->getRoot();
Entry* entry = window->findChildT<Entry>("filename");
char buf[MAX_PATH];
char* p;
ustrcpy(buf, entry->getText());
p = get_extension(buf);
if (p && *p != 0) {
ustrcpy(p, ext.c_str());
entry->setText(buf);
entry->selectText(0, -1);
}
break;
}
}
}
return false;
}
static bool filename_msg_proc(Widget* widget, Message* msg)
{
if (msg->type == JM_KEYRELEASED && msg->key.ascii >= 32) {
// Check if all keys are released
for (int c=0; c<KEY_MAX; ++c) {
if (key[c])
return false;
}
// String to be autocompleted
base::string left_part = widget->getText();
if (left_part.empty())
return false;
// First we'll need the fileview widget
Widget* fileview = widget->findSibling("fileview");
const FileItemList& children = fileview_get_filelist(fileview);
for (FileItemList::const_iterator
it=children.begin(); it!=children.end(); ++it) {
IFileItem* child = *it;
base::string child_name = child->getDisplayName();
base::string::iterator it1, it2;
for (it1 = child_name.begin(), it2 = left_part.begin();
it1!=child_name.end() && it2!=left_part.end();
++it1, ++it2) {
if (std::tolower(*it1) != std::tolower(*it2))
break;
}
// Is the pattern (left_part) in the child_name's beginning?
if (it2 == left_part.end()) {
widget->setText(child_name.c_str());
((Entry*)widget)->selectText(child_name.size(),
left_part.size());
clear_keybuf();
return true;
}
}
}
return false;
}

View File

@ -28,7 +28,6 @@
#include "gui/box.h"
#include "gui/button.h"
#include "gui/frame.h"
#include "gui/hook.h"
#include "gui/label.h"
#include "gui/slider.h"
#include "gui/widget.h"
@ -74,7 +73,7 @@ void dialogs_mask_color(Document* document)
if (!image)
return;
FramePtr window(new Frame(false, "Mask by Color"));
UniquePtr<Frame> window(new Frame(false, "Mask by Color"));
box1 = new Box(JI_VERTICAL);
box2 = new Box(JI_HORIZONTAL);
box3 = new Box(JI_HORIZONTAL);

View File

@ -18,11 +18,9 @@
#include "config.h"
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include "app.h"
#include "app/find_widget.h"
#include "app/load_widget.h"
#include "base/compiler_specific.h"
#include "base/memory.h"
#include "console.h"
@ -32,9 +30,12 @@
#include "file/format_options.h"
#include "gui/gui.h"
#include "ini_file.h"
#include "modules/gui.h"
#include "raster/raster.h"
#include <csetjmp>
#include <cstdio>
#include <cstdlib>
#include "jpeglib.h"
class JpegFormat : public FileFormat
@ -365,12 +366,9 @@ SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
return jpeg_options;
// Load the window to ask to the user the JPEG options he wants.
FramePtr window(load_widget("jpeg_options.xml", "jpeg_options"));
Slider* slider_quality;
Widget* ok;
get_widgets(window,
"quality", &slider_quality,
"ok", &ok, NULL);
UniquePtr<Frame> window(app::load_widget<Frame>("jpeg_options.xml", "jpeg_options"));
Slider* slider_quality = app::find_widget<Slider>(window, "quality");
Widget* ok = app::find_widget<Widget>(window, "ok");
slider_quality->setValue(jpeg_options->quality * 10.0f);

View File

@ -19,7 +19,6 @@ add_library(gui-lib
graphics.cpp
grid.cpp
gui.cpp
hook.cpp
image_view.cpp
intern.cpp
label.cpp

View File

@ -138,13 +138,13 @@ void Alert::processString(char* buf, std::vector<Widget*>& labels, std::vector<W
labels.push_back(new Separator(NULL, JI_HORIZONTAL));
}
else if (button) {
char button_name[256];
char buttonId[256];
Button* button_widget = new Button(beg);
jwidget_set_min_size(button_widget, 60*jguiscale(), 0);
buttons.push_back(button_widget);
usprintf(button_name, "button-%d", buttons.size());
button_widget->setName(button_name);
usprintf(buttonId, "button-%d", buttons.size());
button_widget->setId(buttonId);
button_widget->Click.connect(Bind<void>(&Frame::closeWindow, this, button_widget));
}
@ -178,8 +178,8 @@ void Alert::processString(char* buf, std::vector<Widget*>& labels, std::vector<W
box3 = new Box(JI_HORIZONTAL | JI_HOMOGENEOUS);
// To identify by the user
box2->setName("labels");
box3->setName("buttons");
box2->setId("labels");
box3->setId("buttons");
// Pseudo separators (only to fill blank space)
box4 = new Box(0);

View File

@ -83,7 +83,6 @@ enum {
JI_IMAGE_VIEW,
JI_LABEL,
JI_LISTBOX,
JI_LISTBOX2,
JI_LISTITEM,
JI_MANAGER,
JI_MENU,
@ -110,9 +109,7 @@ enum {
JM_OPEN, // Windows is open.
JM_CLOSE, // Windows is closed.
JM_CLOSE_APP, // The user wants to close the entire application.
JM_DESTROY, // Widget is destroyed.
JM_DRAW, // Widget needs be repainted.
JM_SIGNAL, // Signal from some widget.
JM_TIMER, // A timer timeout.
JM_REQSIZE, // Request size.
JM_SETPOS, // Set position.
@ -145,29 +142,6 @@ enum {
JM_REGISTERED_MESSAGES
};
// Signals.
enum {
// Generic signals
JI_SIGNAL_ENABLE,
JI_SIGNAL_DISABLE,
JI_SIGNAL_SELECT,
JI_SIGNAL_DESELECT,
JI_SIGNAL_SHOW,
JI_SIGNAL_HIDE,
JI_SIGNAL_ADD_CHILD,
JI_SIGNAL_SET_TEXT,
JI_SIGNAL_SET_FONT,
JI_SIGNAL_INIT_THEME,
// Special widget signals
JI_SIGNAL_BUTTON_SELECT,
JI_SIGNAL_LISTBOX_CHANGE,
JI_SIGNAL_LISTBOX_SELECT,
JI_SIGNAL_COMBOBOX_SELECT,
JI_SIGNAL_MANAGER_LOSTCHAR,
JI_SIGNAL_MENUITEM_SELECT,
};
// Flags for jwidget_get_drawable_region.
#define JI_GDR_CUTTOPWINDOWS 1 // Cut areas where are windows on top.
#define JI_GDR_USECHILDAREA 2 // Use areas where are children.

View File

@ -24,13 +24,15 @@
ButtonBase::ButtonBase(const char* text, int type, int behaviorType, int drawType)
: Widget(type)
, m_pressedStatus(false)
, m_handleSelect(true)
, m_behaviorType(behaviorType)
, m_drawType(drawType)
, m_iconInterface(NULL)
{
this->setAlign(JI_CENTER | JI_MIDDLE);
this->setText(text);
this->setFocusStop(true);
setAlign(JI_CENTER | JI_MIDDLE);
setText(text);
setFocusStop(true);
// Initialize theme
this->type = m_drawType; // TODO Fix this nasty trick
@ -76,41 +78,41 @@ bool ButtonBase::onProcessMessage(Message* msg)
case JM_FOCUSENTER:
case JM_FOCUSLEAVE:
if (this->isEnabled()) {
if (isEnabled()) {
if (m_behaviorType == JI_BUTTON) {
/* deselect the widget (maybe the user press the key, but
before release it, changes the focus) */
if (this->isSelected())
this->setSelected(false);
// Deselect the widget (maybe the user press the key, but
// before release it, changes the focus).
if (isSelected())
setSelected(false);
}
/* TODO theme specific stuff */
// TODO theme specific stuff
invalidate();
}
break;
case JM_KEYPRESSED:
/* if the button is enabled */
if (this->isEnabled()) {
/* for JI_BUTTON */
// If the button is enabled.
if (isEnabled()) {
// For JI_BUTTON
if (m_behaviorType == JI_BUTTON) {
/* has focus and press enter/space */
if (this->hasFocus()) {
// Has focus and press enter/space
if (hasFocus()) {
if ((msg->key.scancode == KEY_ENTER) ||
(msg->key.scancode == KEY_ENTER_PAD) ||
(msg->key.scancode == KEY_SPACE)) {
this->setSelected(true);
setSelected(true);
return true;
}
}
// Check if the user pressed mnemonic.
if ((msg->any.shifts & KB_ALT_FLAG) &&
(isScancodeMnemonic(msg->key.scancode))) {
this->setSelected(true);
setSelected(true);
return true;
}
/* magnetic */
else if (this->isFocusMagnet() &&
// Magnetic widget catches ENTERs
else if (isFocusMagnet() &&
((msg->key.scancode == KEY_ENTER) ||
(msg->key.scancode == KEY_ENTER_PAD))) {
getManager()->setFocus(this);
@ -119,27 +121,27 @@ bool ButtonBase::onProcessMessage(Message* msg)
// process them)
getManager()->dispatchMessages();
this->setSelected(true);
setSelected(true);
return true;
}
}
/* for JI_CHECK or JI_RADIO */
// For JI_CHECK or JI_RADIO
else {
/* if the widget has the focus and the user press space or
if the user press Alt+the underscored letter of the button */
if ((this->hasFocus() &&
if ((hasFocus() &&
(msg->key.scancode == KEY_SPACE)) ||
((msg->any.shifts & KB_ALT_FLAG) &&
(isScancodeMnemonic(msg->key.scancode)))) {
if (m_behaviorType == JI_CHECK) {
// Swap the select status
this->setSelected(!this->isSelected());
setSelected(!isSelected());
invalidate();
}
else if (m_behaviorType == JI_RADIO) {
if (!this->isSelected()) {
this->setSelected(true);
if (!isSelected()) {
setSelected(true);
}
}
return true;
@ -149,9 +151,9 @@ bool ButtonBase::onProcessMessage(Message* msg)
break;
case JM_KEYRELEASED:
if (this->isEnabled()) {
if (isEnabled()) {
if (m_behaviorType == JI_BUTTON) {
if (this->isSelected()) {
if (isSelected()) {
generateButtonSelectSignal();
return true;
}
@ -163,32 +165,32 @@ bool ButtonBase::onProcessMessage(Message* msg)
switch (m_behaviorType) {
case JI_BUTTON:
if (this->isEnabled()) {
this->setSelected(true);
if (isEnabled()) {
setSelected(true);
m_pressedStatus = this->isSelected();
this->captureMouse();
m_pressedStatus = isSelected();
captureMouse();
}
return true;
case JI_CHECK:
if (this->isEnabled()) {
this->setSelected(!this->isSelected());
if (isEnabled()) {
setSelected(!isSelected());
m_pressedStatus = this->isSelected();
this->captureMouse();
m_pressedStatus = isSelected();
captureMouse();
}
return true;
case JI_RADIO:
if (this->isEnabled()) {
if (!this->isSelected()) {
jwidget_signal_off(this);
this->setSelected(true);
jwidget_signal_on(this);
if (isEnabled()) {
if (!isSelected()) {
m_handleSelect = false;
setSelected(true);
m_handleSelect = true;
m_pressedStatus = this->isSelected();
this->captureMouse();
m_pressedStatus = isSelected();
captureMouse();
}
}
return true;
@ -196,10 +198,10 @@ bool ButtonBase::onProcessMessage(Message* msg)
break;
case JM_BUTTONRELEASED:
if (this->hasCapture()) {
this->releaseMouse();
if (hasCapture()) {
releaseMouse();
if (this->hasMouseOver()) {
if (hasMouseOver()) {
switch (m_behaviorType) {
case JI_BUTTON:
@ -218,8 +220,8 @@ bool ButtonBase::onProcessMessage(Message* msg)
case JI_RADIO:
{
this->setSelected(false);
this->setSelected(true);
setSelected(false);
setSelected(true);
// Fire onClick() event
Event ev(this);
@ -233,30 +235,28 @@ bool ButtonBase::onProcessMessage(Message* msg)
break;
case JM_MOTION:
if (this->isEnabled() && this->hasCapture()) {
bool hasMouse = this->hasMouseOver();
if (isEnabled() && hasCapture()) {
bool hasMouse = hasMouseOver();
m_handleSelect = false;
// Switch state when the mouse go out
if (( hasMouse && this->isSelected() != m_pressedStatus) ||
(!hasMouse && this->isSelected() == m_pressedStatus)) {
jwidget_signal_off(this);
if (hasMouse) {
this->setSelected(m_pressedStatus);
}
else {
this->setSelected(!m_pressedStatus);
}
jwidget_signal_on(this);
if ((hasMouse && isSelected() != m_pressedStatus) ||
(!hasMouse && isSelected() == m_pressedStatus)) {
if (hasMouse)
setSelected(m_pressedStatus);
else
setSelected(!m_pressedStatus);
}
m_handleSelect = true;
}
break;
case JM_MOUSEENTER:
case JM_MOUSELEAVE:
// TODO theme stuff
if (this->isEnabled())
if (isEnabled())
invalidate();
break;
}
@ -289,10 +289,7 @@ void ButtonBase::onPaint(PaintEvent& ev)
void ButtonBase::generateButtonSelectSignal()
{
// Deselect
this->setSelected(false);
// Emit JI_SIGNAL_BUTTON_SELECT signal
jwidget_emit_signal(this, JI_SIGNAL_BUTTON_SELECT);
setSelected(false);
// Fire onClick() event
Event ev(this);
@ -367,22 +364,18 @@ void RadioButton::deselectRadioGroup()
}
}
bool RadioButton::onProcessMessage(Message* msg)
void RadioButton::onSelect()
{
switch (msg->type) {
ButtonBase::onSelect();
case JM_SIGNAL:
if (getBehaviorType() == JI_RADIO) {
if (msg->signal.num == JI_SIGNAL_SELECT) {
deselectRadioGroup();
if (!m_handleSelect)
return;
jwidget_signal_off(this);
this->setSelected(true);
jwidget_signal_on(this);
}
}
break;
if (getBehaviorType() == JI_RADIO) {
deselectRadioGroup();
m_handleSelect = false;
setSelected(true);
m_handleSelect = true;
}
return ButtonBase::onProcessMessage(msg);
}

View File

@ -69,6 +69,9 @@ private:
int m_behaviorType;
int m_drawType;
IButtonIcon* m_iconInterface;
protected:
bool m_handleSelect;
};
// Pushable button to execute commands
@ -85,10 +88,7 @@ public:
CheckBox(const char* text, int drawType = JI_CHECK);
};
//////////////////////////////////////////////////////////////////////
// Radio buttons
// Radio button
class RadioButton : public ButtonBase
{
public:
@ -100,8 +100,7 @@ public:
void deselectRadioGroup();
protected:
// Events
bool onProcessMessage(Message* msg) OVERRIDE;
void onSelect() OVERRIDE;
private:
int m_radioGroup;

View File

@ -12,19 +12,8 @@
class CloseEvent : public Event
{
public:
enum Trigger {
ByCode, // The CloseEvent was generated by code.
ByUser, // The CloseEvent was generated by the user.
};
CloseEvent(Component* source, Trigger trigger)
: Event(source)
, m_trigger(trigger){ }
Trigger getTrigger() const { return m_trigger; }
private:
Trigger m_trigger;
CloseEvent(Component* source)
: Event(source) { }
};
#endif // GUI_CLOSE_EVENT_H_INCLUDED

View File

@ -20,12 +20,45 @@ class ComboBoxButton : public Button
public:
ComboBoxButton() : Button("") { }
void onPaint(PaintEvent& ev) OVERRIDE
{
void onPaint(PaintEvent& ev) OVERRIDE {
getTheme()->paintComboBoxButton(ev);
}
};
class ComboBoxEntry : public Entry
{
public:
ComboBoxEntry(ComboBox* comboBox)
: Entry(256, ""),
m_comboBox(comboBox) {
}
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
private:
ComboBox* m_comboBox;
};
class ComboBoxListBox : public ListBox
{
public:
ComboBoxListBox(ComboBox* comboBox)
: m_comboBox(comboBox) {
}
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onChangeSelectedItem() OVERRIDE;
private:
bool isValidItem(int index) const {
return (index >= 0 && index < m_comboBox->getItemCount());
}
ComboBox* m_comboBox;
};
struct ComboBox::Item
{
std::string text;
@ -34,16 +67,10 @@ struct ComboBox::Item
Item() : data(NULL) { }
};
#define IS_VALID_ITEM(combobox, index) \
(index >= 0 && index < combobox->getItemCount())
static bool combobox_entry_msg_proc(JWidget widget, Message* msg);
static bool combobox_listbox_msg_proc(JWidget widget, Message* msg);
ComboBox::ComboBox()
: Widget(JI_COMBOBOX)
{
m_entry = new Entry(256, "");
m_entry = new ComboBoxEntry(this);
m_button = new ComboBoxButton();
m_window = NULL;
m_selected = 0;
@ -51,15 +78,9 @@ ComboBox::ComboBox()
m_clickopen = true;
m_casesensitive = true;
m_entry->user_data[0] = this;
m_button->user_data[0] = this;
// TODO this separation should be from the Theme*
this->child_spacing = 0;
this->setFocusStop(true);
jwidget_add_hook(m_entry, JI_WIDGET, combobox_entry_msg_proc, NULL);
m_entry->setExpansive(true);
// When the "m_button" is clicked ("Click" signal) call onButtonClick() method
@ -68,6 +89,7 @@ ComboBox::ComboBox()
addChild(m_entry);
addChild(m_button);
setFocusStop(true);
setEditable(m_editable);
initTheme();
@ -321,26 +343,24 @@ void ComboBox::onPreferredSize(PreferredSizeEvent& ev)
ev.setPreferredSize(reqSize);
}
static bool combobox_entry_msg_proc(JWidget widget, Message* msg)
bool ComboBoxEntry::onProcessMessage(Message* msg)
{
ComboBox* combobox = reinterpret_cast<ComboBox*>(widget->user_data[0]);
switch (msg->type) {
case JM_KEYPRESSED:
if (widget->hasFocus()) {
if (!combobox->isEditable()) {
if (hasFocus()) {
if (!m_comboBox->isEditable()) {
if (msg->key.scancode == KEY_SPACE ||
msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
combobox->switchListBox();
m_comboBox->switchListBox();
return true;
}
}
else {
if (msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
combobox->switchListBox();
m_comboBox->switchListBox();
return true;
}
}
@ -348,52 +368,37 @@ static bool combobox_entry_msg_proc(JWidget widget, Message* msg)
break;
case JM_BUTTONPRESSED:
if (combobox->isClickOpen()) {
combobox->switchListBox();
if (m_comboBox->isClickOpen()) {
m_comboBox->switchListBox();
}
if (combobox->isEditable()) {
widget->getManager()->setFocus(widget);
if (m_comboBox->isEditable()) {
getManager()->setFocus(this);
}
else
return true;
break;
case JM_DRAW:
widget->getTheme()->draw_combobox_entry(static_cast<Entry*>(widget),
&msg->draw.rect);
getTheme()->draw_combobox_entry(this, &msg->draw.rect);
return true;
}
return false;
return Entry::onProcessMessage(msg);
}
static bool combobox_listbox_msg_proc(JWidget widget, Message* msg)
bool ComboBoxListBox::onProcessMessage(Message* msg)
{
ComboBox* combobox = reinterpret_cast<ComboBox*>(widget->user_data[0]);
switch (msg->type) {
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_LISTBOX_CHANGE) {
int index = static_cast<ListBox*>(widget)->getSelectedIndex();
if (IS_VALID_ITEM(combobox, index))
combobox->setSelectedItem(index);
}
break;
case JM_BUTTONRELEASED:
{
int index = combobox->getSelectedItem();
int index = m_comboBox->getSelectedItem();
if (isValidItem(index))
m_comboBox->Change();
combobox->closeListBox();
if (IS_VALID_ITEM(combobox, index)) {
combobox->Change();
jwidget_emit_signal(combobox, JI_SIGNAL_COMBOBOX_SELECT);
}
m_comboBox->closeListBox();
}
return true;
@ -413,18 +418,27 @@ static bool combobox_listbox_msg_proc(JWidget widget, Message* msg)
/* } */
case JM_KEYPRESSED:
if (widget->hasFocus()) {
if (hasFocus()) {
if (msg->key.scancode == KEY_SPACE ||
msg->key.scancode == KEY_ENTER ||
msg->key.scancode == KEY_ENTER_PAD) {
combobox->closeListBox();
m_comboBox->closeListBox();
return true;
}
}
break;
}
return false;
return ListBox::onProcessMessage(msg);
}
void ComboBoxListBox::onChangeSelectedItem()
{
ListBox::onChangeSelectedItem();
int index = getSelectedIndex();
if (isValidItem(index))
m_comboBox->setSelectedItem(index);
}
// When the mouse is clicked we switch the visibility-status of the list-box
@ -438,11 +452,7 @@ void ComboBox::openListBox()
if (!m_window) {
m_window = new Frame(false, NULL);
View* view = new View();
m_listbox = new ListBox();
m_listbox->user_data[0] = this;
jwidget_add_hook(m_listbox, JI_WIDGET,
combobox_listbox_msg_proc, NULL);
m_listbox = new ComboBoxListBox(this);
std::vector<Item*>::iterator it, end = m_items.end();
for (it = m_items.begin(); it != end; ++it) {
@ -465,9 +475,7 @@ void ComboBox::openListBox()
m_window->addChild(view);
view->attachToView(m_listbox);
jwidget_signal_off(m_listbox);
m_listbox->selectIndex(m_selected);
jwidget_signal_on(m_listbox);
m_window->remap_window();

View File

@ -92,6 +92,12 @@ HitTest Frame::hitTest(const gfx::Point& point)
return ev.getHit();
}
void Frame::onClose(CloseEvent& ev)
{
// Fire Close signal
Close(ev);
}
void Frame::onHitTest(HitTestEvent& ev)
{
HitTest ht = HitTestNowhere;
@ -247,6 +253,10 @@ void Frame::closeWindow(Widget* killer)
m_killer = killer;
getManager()->_closeWindow(this, true);
// Close event
CloseEvent ev(killer);
onClose(ev);
}
bool Frame::is_toplevel()
@ -271,29 +281,6 @@ bool Frame::onProcessMessage(Message* msg)
m_killer = NULL;
break;
case JM_CLOSE:
// Fire Close signal
{
CloseEvent::Trigger trigger;
if (m_killer &&
m_killer->getName() &&
strcmp(m_killer->getName(), "theme_close_button") == 0) {
trigger = CloseEvent::ByUser;
}
else {
trigger = CloseEvent::ByCode;
}
CloseEvent ev(this, trigger);
Close(ev);
}
break;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_SET_TEXT)
initTheme();
break;
case JM_BUTTONPRESSED: {
if (!m_is_moveable)
break;
@ -515,6 +502,12 @@ void Frame::onBroadcastMouseMessage(WidgetsList& targets)
sibling->broadcastMouseMessage(targets);
}
void Frame::onSetText()
{
Widget::onSetText();
initTheme();
}
void Frame::window_set_position(JRect rect)
{
JWidget child;

View File

@ -15,8 +15,6 @@
#include "gui/hit_test_event.h"
#include "gui/widget.h"
class CloseEvent;
class Frame : public Widget
{
public:
@ -57,8 +55,12 @@ protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE;
virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
virtual void onPaint(PaintEvent& ev) OVERRIDE;
virtual void onBroadcastMouseMessage(WidgetsList& targets) OVERRIDE;
virtual void onSetText() OVERRIDE;
// New events
virtual void onClose(CloseEvent& ev);
virtual void onHitTest(HitTestEvent& ev);
virtual void onBroadcastMouseMessage(WidgetsList& targets);
private:
void window_set_position(JRect rect);

View File

@ -24,8 +24,8 @@
#include "gui/graphics.h"
#include "gui/grid.h"
#include "gui/hit_test_event.h"
#include "gui/hook.h"
#include "gui/image_view.h"
#include "gui/init_theme_event.h"
#include "gui/label.h"
#include "gui/link_label.h"
#include "gui/list.h"

View File

@ -1,38 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#include "config.h"
#include "gui/hook.h"
/**
* Creates a new empty hook.
*
* You shouldn't use this routine, you should use jwidget_add_hook
* instead.
*
* @see jhook
*/
JHook jhook_new()
{
JHook hook = new jhook;
hook->type = JI_WIDGET;
hook->msg_proc = NULL;
hook->data = NULL;
return hook;
}
/**
* Destroys the hook.
*
* @see jhook
*/
void jhook_free(JHook hook)
{
delete hook;
}

View File

@ -1,35 +0,0 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef GUI_HOOK_H_INCLUDED
#define GUI_HOOK_H_INCLUDED
#include "gui/base.h"
/**
* A hook is a way to intercept messages which are sent to a @ref jwidget.
*
* Because each widget could has various hooks, each one has a unique
* type-id (you can use the @ref ji_register_widget_type routine to
* get one), and an associated routine to process messages
* (MessageFunc).
*
* Also, the hook can have extra associated data to be used by the
* routine @c msg_proc.
*
* @see ji_register_widget_type, MessageFunc
*/
struct jhook
{
int type;
MessageFunc msg_proc;
void *data;
};
JHook jhook_new();
void jhook_free(JHook hook);
#endif

View File

@ -0,0 +1,27 @@
// ASEPRITE gui library
// Copyright (C) 2001-2012 David Capello
//
// This source file is ditributed under a BSD-like license, please
// read LICENSE.txt for more information.
#ifndef GUI_INIT_THEME_EVENT_H_INCLUDED
#define GUI_INIT_THEME_EVENT_H_INCLUDED
#include "gui/event.h"
class Theme;
class InitThemeEvent : public Event
{
public:
InitThemeEvent(Component* source, Theme* theme)
: Event(source)
, m_theme(theme){ }
Theme* getTheme() const { return m_theme; }
private:
Theme* m_theme;
};
#endif // GUI_INIT_THEME_EVENT_H_INCLUDED

View File

@ -6,18 +6,18 @@
#include "config.h"
#include <vector>
#include "gui/frame.h"
#include "gui/manager.h"
#include "gui/theme.h"
#include "gui/widget.h"
static std::vector<JWidget>* widgets;
#include <list>
static std::list<Widget*>* widgets;
int _ji_widgets_init()
{
widgets = new std::vector<JWidget>;
widgets = new std::list<Widget*>;
return 0;
}
@ -26,95 +26,43 @@ void _ji_widgets_exit()
delete widgets;
}
JWidget _ji_get_widget_by_id(JID widget_id)
void _ji_add_widget(Widget* widget)
{
ASSERT((widget_id >= 0) && (widget_id < widgets->size()));
return (*widgets)[widget_id];
widgets->push_back(widget);
}
JWidget* _ji_get_widget_array(int* n)
void _ji_remove_widget(Widget* widget)
{
*n = widgets->size();
return &widgets->front();
}
std::list<Widget*>::iterator it =
std::find(widgets->begin(), widgets->end(), widget);
void _ji_add_widget(JWidget widget)
{
JID widget_id;
// first widget
if (widgets->empty()) {
widgets->resize(2);
// id=0 no widget
(*widgets)[0] = NULL;
// id>0 all widgets
(*widgets)[1] = widget;
(*widgets)[1]->id = widget_id = 1;
}
else {
// find a free slot
for (widget_id=1; widget_id<widgets->size(); widget_id++) {
// is it free?
if ((*widgets)[widget_id] == NULL)
break;
}
// we need space for other widget more?
if (widget_id == widgets->size())
widgets->resize(widgets->size()+1);
(*widgets)[widget_id] = widget;
(*widgets)[widget_id]->id = widget_id;
}
}
void _ji_remove_widget(JWidget widget)
{
ASSERT_VALID_WIDGET(widget);
(*widgets)[widget->id] = NULL;
}
bool _ji_is_valid_widget(JWidget widget)
{
return (widget &&
widget->id >= 0 &&
widget->id < widgets->size() &&
(*widgets)[widget->id] &&
(*widgets)[widget->id]->id == widget->id);
if (it != widgets->end())
widgets->erase(it);
}
void _ji_set_font_of_all_widgets(FONT* f)
{
size_t c;
// first of all, we have to set the font to all the widgets
for (c=0; c<widgets->size(); c++)
if (_ji_is_valid_widget((*widgets)[c]))
(*widgets)[c]->setFont(f);
for (std::list<Widget*>::iterator it=widgets->begin(), end=widgets->end();
it != end; ++it) {
(*it)->setFont(f);
}
}
void _ji_reinit_theme_in_all_widgets()
{
size_t c;
// Then we can reinitialize the theme of each widget
for (c=0; c<widgets->size(); c++)
if (_ji_is_valid_widget((*widgets)[c])) {
(*widgets)[c]->setTheme(CurrentTheme::get());
(*widgets)[c]->initTheme();
// Reinitialize the theme of each widget
for (std::list<Widget*>::iterator it=widgets->begin(), end=widgets->end();
it != end; ++it) {
(*it)->setTheme(CurrentTheme::get());
(*it)->initTheme();
}
// Remap the windows
for (c=0; c<widgets->size(); c++)
if (_ji_is_valid_widget((*widgets)[c])) {
if ((*widgets)[c]->type == JI_FRAME)
static_cast<Frame*>((*widgets)[c])->remap_window();
}
for (std::list<Widget*>::iterator it=widgets->begin(), end=widgets->end();
it != end; ++it) {
if ((*it)->type == JI_FRAME)
static_cast<Frame*>(*it)->remap_window();
}
// Redraw the whole screen
gui::Manager::getDefault()->invalidate();

View File

@ -11,17 +11,15 @@
struct FONT;
struct BITMAP;
class Frame;
class Widget;
//////////////////////////////////////////////////////////////////////
// jintern.c
JWidget _ji_get_widget_by_id(JID widget_id);
JWidget *_ji_get_widget_array(int *nwidgets);
void _ji_add_widget(JWidget widget);
void _ji_remove_widget(JWidget widget);
bool _ji_is_valid_widget(JWidget widget);
void _ji_add_widget(Widget* widget);
void _ji_remove_widget(Widget* widget);
void _ji_set_font_of_all_widgets(FONT* f);
void _ji_reinit_theme_in_all_widgets();
@ -37,7 +35,7 @@ bool _jwindow_is_moving();
void _ji_theme_draw_sprite_color(BITMAP *bmp, BITMAP *sprite,
int x, int y, int color);
void _ji_theme_textbox_draw(BITMAP *bmp, JWidget textbox,
void _ji_theme_textbox_draw(BITMAP *bmp, Widget* textbox,
int *w, int *h, int bg, int fg);
//////////////////////////////////////////////////////////////////////

View File

@ -93,7 +93,7 @@ void ListBox::selectChild(Item* item)
}
}
jwidget_emit_signal(this, JI_SIGNAL_LISTBOX_CHANGE);
onChangeSelectedItem();
}
void ListBox::selectIndex(int index)
@ -261,7 +261,7 @@ bool ListBox::onProcessMessage(Message* msg)
break;
case JM_DOUBLECLICK:
jwidget_emit_signal(this, JI_SIGNAL_LISTBOX_SELECT);
onDoubleClickItem();
return true;
}
@ -288,6 +288,16 @@ void ListBox::onPreferredSize(PreferredSizeEvent& ev)
ev.setPreferredSize(Size(w, h));
}
void ListBox::onChangeSelectedItem()
{
ChangeSelectedItem();
}
void ListBox::onDoubleClickItem()
{
DoubleClickItem();
}
void ListBox::layoutListBox(JRect rect)
{
Size reqSize;

View File

@ -8,6 +8,7 @@
#define GUI_LISTBOX_H_INCLUDED
#include "base/compiler_specific.h"
#include "base/signal.h"
#include "gui/widget.h"
class ListBox : public Widget
@ -35,9 +36,14 @@ public:
void centerScroll();
Signal0<void> ChangeSelectedItem;
Signal0<void> DoubleClickItem;
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
virtual bool onProcessMessage(Message* msg) OVERRIDE;
virtual void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
virtual void onChangeSelectedItem();
virtual void onDoubleClickItem();
private:
void layoutListBox(JRect rect);

View File

@ -834,25 +834,23 @@ void Manager::removeMessageFilterFor(JWidget widget)
/* configures the window for begin the loop */
void Manager::_openWindow(Frame* window)
{
Message* msg;
// free all widgets of special states
// Free all widgets of special states.
if (window->is_wantfocus()) {
freeCapture();
freeMouse();
freeFocus();
}
/* add the window to manager */
// Add the window to manager.
jlist_prepend(this->children, window);
window->parent = this;
/* broadcast the open message */
msg = jmessage_new(JM_OPEN);
// Broadcast the open message.
Message* msg = jmessage_new(JM_OPEN);
jmessage_add_dest(msg, window);
enqueueMessage(msg);
/* update the new windows list to show */
// Update the new windows list to show.
jlist_append(new_windows, window);
}
@ -886,7 +884,7 @@ void Manager::_closeWindow(Frame* window, bool redraw_background)
}
}
/* free all widgets of special states */
// Free all widgets of special states.
if (capture_widget != NULL && capture_widget->getRoot() == window)
freeCapture();
@ -896,25 +894,25 @@ void Manager::_closeWindow(Frame* window, bool redraw_background)
if (focus_widget != NULL && focus_widget->getRoot() == window)
freeFocus();
/* hide window */
// Hide window.
window->setVisible(false);
/* close message */
// Close message.
msg = jmessage_new(JM_CLOSE);
jmessage_add_dest(msg, window);
enqueueMessage(msg);
/* update manager list stuff */
// Update manager list stuff.
jlist_remove(this->children, window);
window->parent = NULL;
/* redraw background */
// Redraw background.
if (reg1) {
invalidateRegion(reg1);
jregion_free(reg1);
}
/* maybe the window is in the "new_windows" list */
// Maybe the window is in the "new_windows" list.
jlist_remove(new_windows, window);
}
@ -1072,9 +1070,8 @@ void Manager::pumpQueue()
static char *msg_name[] = {
"JM_OPEN",
"JM_CLOSE",
"JM_DESTROY",
"JM_CLOSE_APP",
"JM_DRAW",
"JM_SIGNAL",
"JM_TIMER",
"JM_REQSIZE",
"JM_SETPOS",
@ -1082,10 +1079,12 @@ void Manager::pumpQueue()
"JM_DEFERREDFREE",
"JM_DIRTYCHILDREN",
"JM_QUEUEPROCESSING",
"JM_KEYPRESSED",
"JM_KEYRELEASED",
"JM_FOCUSENTER",
"JM_FOCUSLEAVE",
"JM_BUTTONPRESSED",
"JM_BUTTONRELEASED",
"JM_DOUBLECLICK",

View File

@ -70,6 +70,32 @@ struct MenuBaseData
};
class CustomizedWindowForMenuBox : public Frame
{
public:
CustomizedWindowForMenuBox(MenuBox* menubox)
: Frame(false, NULL)
{
set_moveable(false); // Can't move the window
addChild(menubox);
remap_window();
}
protected:
bool onProcessMessage(Message* msg) OVERRIDE
{
switch (msg->type) {
case JM_CLOSE:
// Delete this window automatically
deferDelete();
break;
}
return Frame::onProcessMessage(msg);
}
};
static MenuBox* get_base_menubox(Widget* widget);
static MenuBaseData* get_base(Widget* widget);
@ -199,7 +225,7 @@ void MenuItem::setSubmenu(Menu* menu)
* widget (a menu-item).
*
* @warning The specified @a accel will be freed automatically when
* the menu-item'll receive JM_DESTROY message.
* the menu-item is deleted.
*/
void MenuItem::setAccel(JAccel accel)
{
@ -715,20 +741,12 @@ bool MenuItem::onProcessMessage(Message* msg)
JRect old_pos = jwidget_get_rect(this->parent->parent);
// New window and new menu-box
Frame* window = new Frame(false, NULL);
jwidget_add_hook(window, -1, window_msg_proc, NULL);
MenuBox* menubox = new MenuBox();
m_submenu_menubox = menubox;
window->set_moveable(false); // Can't move the window
// Set children
menubox->setMenu(m_submenu);
window->addChild(menubox);
window->remap_window();
// New window and new menu-box
Frame* window = new CustomizedWindowForMenuBox(menubox);
// Menubox position
pos = jwidget_get_rect(window);
@ -881,9 +899,6 @@ bool MenuItem::onProcessMessage(Message* msg)
void MenuItem::onClick()
{
// Fire old JI_SIGNAL_MENUITEM_SELECT signal
jwidget_emit_signal(this, JI_SIGNAL_MENUITEM_SELECT);
// Fire new Click() signal.
Click();
}
@ -1204,18 +1219,6 @@ void MenuItem::executeClick()
gui::Manager::getDefault()->enqueueMessage(msg);
}
static bool window_msg_proc(Widget* widget, Message* msg)
{
switch (msg->type) {
case JM_CLOSE:
widget->deferDelete();
break;
}
return false;
}
static MenuItem* check_for_letter(Menu* menu, int ascii)
{
JLink link;

View File

@ -82,16 +82,6 @@ bool PopupFrame::onProcessMessage(Message* msg)
stopFilteringMessages();
break;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_INIT_THEME) {
this->border_width.l = 3 * jguiscale();
this->border_width.t = 3 * jguiscale();
this->border_width.r = 3 * jguiscale();
this->border_width.b = 3 * jguiscale();
return true;
}
break;
case JM_MOUSELEAVE:
if (m_hot_region == NULL && !is_moveable())
closeWindow(NULL);
@ -196,6 +186,16 @@ void PopupFrame::onPaint(PaintEvent& ev)
g->drawString(getText(), ji_color_foreground(), this->getBgColor(), pos, getAlign());
}
void PopupFrame::onInitTheme(InitThemeEvent& ev)
{
Widget::onInitTheme(ev);
this->border_width.l = 3 * jguiscale();
this->border_width.t = 3 * jguiscale();
this->border_width.r = 3 * jguiscale();
this->border_width.b = 3 * jguiscale();
}
void PopupFrame::startFilteringMessages()
{
if (!m_filtering) {

View File

@ -25,6 +25,7 @@ protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
void onInitTheme(InitThemeEvent& ev) OVERRIDE;
private:
void startFilteringMessages();

View File

@ -35,14 +35,6 @@ bool TextBox::onProcessMessage(Message* msg)
getTheme()->draw_textbox(this, &msg->draw.rect);
return true;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_SET_TEXT) {
View* view = View::getView(this);
if (view)
view->updateView();
}
break;
case JM_KEYPRESSED:
if (hasFocus()) {
View* view = View::getView(this);
@ -183,3 +175,12 @@ void TextBox::onPreferredSize(PreferredSizeEvent& ev)
ev.setPreferredSize(gfx::Size(w, h));
}
void TextBox::onSetText()
{
View* view = View::getView(this);
if (view)
view->updateView();
Widget::onSetText();
}

View File

@ -18,6 +18,7 @@ public:
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onSetText() OVERRIDE;
};
#endif

View File

@ -17,154 +17,136 @@
#include "gui/paint_event.h"
#include "gui/preferred_size_event.h"
#define TOOLTIP_DELAY_MSECS 300
using namespace gfx;
struct TipData
namespace gui {
TooltipManager::TooltipManager()
: Widget(JI_WIDGET)
{
Widget* widget; // Widget that shows the tooltip
Frame* window; // Frame where is the tooltip
std::string text;
UniquePtr<gui::Timer> timer;
int arrowAlign;
};
Manager* manager = Manager::getDefault();
manager->addMessageFilter(JM_MOUSEENTER, this);
manager->addMessageFilter(JM_KEYPRESSED, this);
manager->addMessageFilter(JM_BUTTONPRESSED, this);
manager->addMessageFilter(JM_MOUSELEAVE, this);
static int tip_type();
static bool tip_hook(JWidget widget, Message* msg);
void jwidget_add_tooltip_text(JWidget widget, const char *text, int arrowAlign)
{
TipData* tip = reinterpret_cast<TipData*>(jwidget_get_data(widget, tip_type()));
ASSERT(text != NULL);
if (tip == NULL) {
tip = new TipData;
tip->widget = widget;
tip->window = NULL;
tip->text = text;
tip->arrowAlign = arrowAlign;
jwidget_add_hook(widget, tip_type(), tip_hook, tip);
}
else {
tip->text = text;
}
setVisible(false);
}
/********************************************************************/
/* hook for widgets that want a tool-tip */
static int tip_type()
TooltipManager::~TooltipManager()
{
static int type = 0;
if (!type)
type = ji_register_widget_type();
return type;
Manager* manager = Manager::getDefault();
manager->removeMessageFilterFor(this);
}
/* hook for the widget in which we added a tooltip */
static bool tip_hook(JWidget widget, Message* msg)
void TooltipManager::addTooltipFor(Widget* widget, const char* text, int arrowAlign)
{
TipData* tip = reinterpret_cast<TipData*>(jwidget_get_data(widget, tip_type()));
m_tips[widget] = TipInfo(text, arrowAlign);
}
bool TooltipManager::onProcessMessage(Message* msg)
{
switch (msg->type) {
case JM_DESTROY:
delete tip;
break;
case JM_MOUSEENTER: {
JLink link;
JI_LIST_FOR_EACH_BACK(msg->any.widgets, link) {
Tips::iterator it = m_tips.find((Widget*)link->data);
if (it != m_tips.end()) {
m_target.widget = it->first;
m_target.tipInfo = it->second;
case JM_MOUSEENTER:
if (tip->timer == NULL)
tip->timer.reset(new gui::Timer(widget, 300));
if (m_timer == NULL) {
m_timer.reset(new gui::Timer(this, TOOLTIP_DELAY_MSECS));
m_timer->Tick.connect(&TooltipManager::onTick, this);
}
tip->timer->start();
m_timer->start();
}
}
break;
}
case JM_KEYPRESSED:
case JM_BUTTONPRESSED:
case JM_MOUSELEAVE:
if (tip->window) {
tip->window->closeWindow(NULL);
delete tip->window; // widget
tip->window = NULL;
if (m_tipWindow) {
m_tipWindow->closeWindow(NULL);
m_tipWindow.reset();
}
if (tip->timer != NULL)
tip->timer->stop();
if (m_timer)
m_timer->stop();
break;
case JM_TIMER:
if (msg->timer.timer == tip->timer) {
if (!tip->window) {
TipWindow* window = new TipWindow(tip->text.c_str(), true);
gfx::Rect bounds = tip->widget->getBounds();
int x = jmouse_x(0)+12*jguiscale();
int y = jmouse_y(0)+12*jguiscale();
int w, h;
tip->window = window;
window->setArrowAlign(tip->arrowAlign);
window->remap_window();
w = jrect_w(window->rc);
h = jrect_h(window->rc);
switch (tip->arrowAlign) {
case JI_TOP | JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y + bounds.h;
break;
case JI_TOP | JI_RIGHT:
x = bounds.x - w;
y = bounds.y + bounds.h;
break;
case JI_BOTTOM | JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y - h;
break;
case JI_BOTTOM | JI_RIGHT:
x = bounds.x - w;
y = bounds.y - h;
break;
case JI_TOP:
x = bounds.x + bounds.w/2 - w/2;
y = bounds.y + bounds.h;
break;
case JI_BOTTOM:
x = bounds.x + bounds.w/2 - w/2;
y = bounds.y - h;
break;
case JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y + bounds.h/2 - h/2;
break;
case JI_RIGHT:
x = bounds.x - w;
y = bounds.y + bounds.h/2 - h/2;
break;
}
// if (x+w > JI_SCREEN_W) {
// x = jmouse_x(0) - w - 4*jguiscale();
// y = jmouse_y(0);
// }
window->position_window(MID(0, x, JI_SCREEN_W-w),
MID(0, y, JI_SCREEN_H-h));
window->open_window();
}
tip->timer->stop();
}
break;
}
return false;
return Widget::onProcessMessage(msg);
}
/********************************************************************/
/* TipWindow */
void TooltipManager::onTick()
{
if (!m_tipWindow) {
m_tipWindow.reset(new TipWindow(m_target.tipInfo.text.c_str(), true));
gfx::Rect bounds = m_target.widget->getBounds();
int x = jmouse_x(0)+12*jguiscale();
int y = jmouse_y(0)+12*jguiscale();
int w, h;
m_tipWindow->setArrowAlign(m_target.tipInfo.arrowAlign);
m_tipWindow->remap_window();
w = jrect_w(m_tipWindow->rc);
h = jrect_h(m_tipWindow->rc);
switch (m_target.tipInfo.arrowAlign) {
case JI_TOP | JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y + bounds.h;
break;
case JI_TOP | JI_RIGHT:
x = bounds.x - w;
y = bounds.y + bounds.h;
break;
case JI_BOTTOM | JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y - h;
break;
case JI_BOTTOM | JI_RIGHT:
x = bounds.x - w;
y = bounds.y - h;
break;
case JI_TOP:
x = bounds.x + bounds.w/2 - w/2;
y = bounds.y + bounds.h;
break;
case JI_BOTTOM:
x = bounds.x + bounds.w/2 - w/2;
y = bounds.y - h;
break;
case JI_LEFT:
x = bounds.x + bounds.w;
y = bounds.y + bounds.h/2 - h/2;
break;
case JI_RIGHT:
x = bounds.x - w;
y = bounds.y + bounds.h/2 - h/2;
break;
}
// if (x+w > JI_SCREEN_W) {
// x = jmouse_x(0) - w - 4*jguiscale();
// y = jmouse_y(0);
// }
m_tipWindow->position_window(MID(0, x, JI_SCREEN_W-w),
MID(0, y, JI_SCREEN_H-h));
m_tipWindow->open_window();
}
m_timer->stop();
}
// TipWindow
TipWindow::TipWindow(const char *text, bool close_on_buttonpressed)
: Frame(false, text)
@ -244,19 +226,6 @@ bool TipWindow::onProcessMessage(Message* msg)
}
break;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_INIT_THEME) {
this->border_width.l = 6 * jguiscale();
this->border_width.t = 6 * jguiscale();
this->border_width.r = 6 * jguiscale();
this->border_width.b = 7 * jguiscale();
// Setup the background color.
setBgColor(makecol(255, 255, 200));
return true;
}
break;
case JM_MOUSELEAVE:
if (m_hot_region == NULL)
this->closeWindow(NULL);
@ -334,7 +303,22 @@ void TipWindow::onPreferredSize(PreferredSizeEvent& ev)
ev.setPreferredSize(resultSize);
}
void TipWindow::onInitTheme(InitThemeEvent& ev)
{
Frame::onInitTheme(ev);
this->border_width.l = 6 * jguiscale();
this->border_width.t = 6 * jguiscale();
this->border_width.r = 6 * jguiscale();
this->border_width.b = 7 * jguiscale();
// Setup the background color.
setBgColor(makecol(255, 255, 200));
}
void TipWindow::onPaint(PaintEvent& ev)
{
getTheme()->paintTooltip(ev);
}
} // namespace gui

View File

@ -11,29 +11,70 @@
#include "gui/base.h"
#include "gui/frame.h"
class TipWindow : public Frame
{
public:
TipWindow(const char *text, bool close_on_buttonpressed = false);
~TipWindow();
#include <map>
void set_hotregion(JRegion region);
namespace gui {
int getArrowAlign() const;
void setArrowAlign(int arrowAlign);
class TipWindow;
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
class TooltipManager : public Widget
{
public:
TooltipManager();
~TooltipManager();
private:
bool m_close_on_buttonpressed;
JRegion m_hot_region;
bool m_filtering;
int m_arrowAlign;
};
void addTooltipFor(Widget* widget, const char* text, int arrowAlign = 0);
void jwidget_add_tooltip_text(Widget* widget, const char* text, int arrowAlign = 0);
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
private:
void onTick();
struct TipInfo {
std::string text;
int arrowAlign;
TipInfo() { }
TipInfo(const char* text, int arrowAlign)
: text(text), arrowAlign(arrowAlign) {
}
};
typedef std::map<Widget*, TipInfo> Tips;
Tips m_tips; // All tips.
UniquePtr<TipWindow> m_tipWindow; // Frame to show tooltips.
UniquePtr<gui::Timer> m_timer; // Timer to control the tooltip delay.
struct {
Widget* widget;
TipInfo tipInfo;
} m_target;
};
class TipWindow : public Frame
{
public:
TipWindow(const char *text, bool close_on_buttonpressed = false);
~TipWindow();
void set_hotregion(JRegion region);
int getArrowAlign() const;
void setArrowAlign(int arrowAlign);
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onInitTheme(InitThemeEvent& ev) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
private:
bool m_close_on_buttonpressed;
JRegion m_hot_region;
bool m_filtering;
int m_arrowAlign;
};
} // namespace gui
#endif

View File

@ -19,11 +19,8 @@
#include <allegro.h>
#include "base/memory.h"
#include "gui/graphics.h"
#include "gui/gui.h"
#include "gui/intern.h"
#include "gui/paint_event.h"
#include "gui/preferred_size_event.h"
using namespace gfx;
@ -46,7 +43,6 @@ Widget::Widget(int type)
_ji_add_widget(this);
this->type = type;
this->name = NULL;
this->rc = jrect_new(0, 0, 0, 0);
this->border_width.l = 0;
this->border_width.t = 0;
@ -54,7 +50,6 @@ Widget::Widget(int type)
this->border_width.b = 0;
this->child_spacing = 0;
this->flags = 0;
this->emit_signals = 0;
this->min_w = 0;
this->min_h = 0;
this->max_w = INT_MAX;
@ -62,7 +57,6 @@ Widget::Widget(int type)
this->children = jlist_new();
this->parent = NULL;
this->m_theme = CurrentTheme::get();
this->hooks = jlist_new();
this->m_align = 0;
this->m_text = "";
@ -88,12 +82,6 @@ Widget::Widget(int type)
Widget::~Widget()
{
JLink link, next;
Message* msg;
/* send destroy message */
msg = jmessage_new(JM_DESTROY);
sendMessage(msg);
jmessage_free(msg);
// Break relationship with the manager.
if (this->type != JI_MANAGER) {
@ -116,19 +104,10 @@ Widget::~Widget()
if (m_update_region)
jregion_free(m_update_region);
/* destroy the name */
if (this->name)
base_free(this->name);
/* destroy widget position */
if (this->rc)
jrect_free(this->rc);
/* destroy hooks */
JI_LIST_FOR_EACH(this->hooks, link)
jhook_free(reinterpret_cast<JHook>(link->data));
jlist_free(this->hooks);
// Delete the preferred size
delete m_preferredSize;
@ -143,99 +122,8 @@ void Widget::deferDelete()
void Widget::initTheme()
{
if (m_theme) {
m_theme->init_widget(this);
if (!(flags & JI_INITIALIZED))
flags |= JI_INITIALIZED;
jwidget_emit_signal(this, JI_SIGNAL_INIT_THEME);
}
}
/**********************************************************************/
/* HOOKS */
/**
* Adds a new hook for the widget.
*
* @see jhook
*/
void jwidget_add_hook(JWidget widget, int type,
MessageFunc msg_proc, void *data)
{
JHook hook;
ASSERT_VALID_WIDGET(widget);
hook = jhook_new();
hook->type = type;
hook->msg_proc = msg_proc;
hook->data = data;
jlist_prepend(widget->hooks, hook);
}
/**
* Returns the hook of the specified type.
*/
JHook jwidget_get_hook(JWidget widget, int type)
{
JLink link;
ASSERT_VALID_WIDGET(widget);
JI_LIST_FOR_EACH(widget->hooks, link) {
if (((JHook)link->data)->type == type)
return ((JHook)link->data);
}
return NULL;
}
/**
* Returns the data associated to the specified hook.
*/
void *jwidget_get_data(JWidget widget, int type)
{
register JLink link;
ASSERT_VALID_WIDGET(widget);
JI_LIST_FOR_EACH(widget->hooks, link) {
if (((JHook)link->data)->type == type)
return ((JHook)link->data)->data;
}
return NULL;
}
/**********************************************************************/
/* main properties */
int Widget::getType() const
{
return this->type;
}
const char *Widget::getName() const
{
return this->name;
}
int Widget::getAlign() const
{
return m_align;
}
void Widget::setName(const char *name)
{
if (this->name)
base_free(this->name);
this->name = name ? base_strdup(name) : NULL;
}
void Widget::setAlign(int align)
{
m_align = align;
InitThemeEvent ev(this, m_theme);
onInitTheme(ev);
}
int Widget::getTextInt() const
@ -250,10 +138,8 @@ double Widget::getTextDouble() const
void Widget::setText(const char *text)
{
this->setTextQuiet(text);
jwidget_emit_signal(this, JI_SIGNAL_SET_TEXT);
invalidate();
setTextQuiet(text);
onSetText();
}
void Widget::setTextf(const char *format, ...)
@ -287,7 +173,7 @@ void Widget::setTextQuiet(const char *text)
}
}
FONT *Widget::getFont()
FONT *Widget::getFont() const
{
return m_font;
}
@ -295,8 +181,6 @@ FONT *Widget::getFont()
void Widget::setFont(FONT* f)
{
m_font = f;
jwidget_emit_signal(this, JI_SIGNAL_SET_FONT);
invalidate();
}
@ -318,8 +202,6 @@ void Widget::setVisible(bool state)
if (this->flags & JI_HIDDEN) {
this->flags &= ~JI_HIDDEN;
invalidate();
jwidget_emit_signal(this, JI_SIGNAL_SHOW);
}
}
else {
@ -327,7 +209,6 @@ void Widget::setVisible(bool state)
getManager()->freeWidget(this); // Free from manager
this->flags |= JI_HIDDEN;
jwidget_emit_signal(this, JI_SIGNAL_HIDE);
}
}
}
@ -339,7 +220,7 @@ void Widget::setEnabled(bool state)
this->flags &= ~JI_DISABLED;
invalidate();
jwidget_emit_signal(this, JI_SIGNAL_ENABLE);
onEnable();
}
}
else {
@ -349,7 +230,7 @@ void Widget::setEnabled(bool state)
this->flags |= JI_DISABLED;
invalidate();
jwidget_emit_signal(this, JI_SIGNAL_DISABLE);
onDisable();
}
}
}
@ -361,7 +242,7 @@ void Widget::setSelected(bool state)
this->flags |= JI_SELECTED;
invalidate();
jwidget_emit_signal(this, JI_SIGNAL_SELECT);
onSelect();
}
}
else {
@ -369,7 +250,7 @@ void Widget::setSelected(bool state)
this->flags &= ~JI_SELECTED;
invalidate();
jwidget_emit_signal(this, JI_SIGNAL_DESELECT);
onDeselect();
}
}
}
@ -577,28 +458,28 @@ bool Widget::hasChild(Widget* child)
return jlist_find(this->children, child) != this->children->end ? true: false;
}
Widget* Widget::findChild(const char* name)
Widget* Widget::findChild(const char* id)
{
Widget* child;
JLink link;
JI_LIST_FOR_EACH(this->children, link) {
child = (Widget*)link->data;
if (child->name != NULL && strcmp(child->name, name) == 0)
if (child->getId() == id)
return child;
}
JI_LIST_FOR_EACH(this->children, link) {
if ((child = ((Widget*)link->data)->findChild(name)))
if ((child = ((Widget*)link->data)->findChild(id)))
return child;
}
return 0;
}
Widget* Widget::findSibling(const char* name)
Widget* Widget::findSibling(const char* id)
{
return getRoot()->findChild(name);
return getRoot()->findChild(id);
}
void Widget::addChild(Widget* child)
@ -608,8 +489,6 @@ void Widget::addChild(Widget* child)
jlist_append(children, child);
child->parent = this;
jwidget_emit_signal(this, JI_SIGNAL_ADD_CHILD);
}
void Widget::removeChild(Widget* child)
@ -636,8 +515,6 @@ void Widget::replaceChild(Widget* oldChild, Widget* newChild)
jlist_insert_before(children, before, newChild);
newChild->parent = this;
jwidget_emit_signal(this, JI_SIGNAL_ADD_CHILD);
}
void Widget::insertChild(int index, Widget* child)
@ -647,8 +524,6 @@ void Widget::insertChild(int index, Widget* child)
jlist_insert(children, child, index);
child->parent = this;
jwidget_emit_signal(this, JI_SIGNAL_ADD_CHILD);
}
// ===============================================================
@ -855,7 +730,7 @@ int jwidget_get_bg_color(JWidget widget)
return widget->getBgColor();
}
int jwidget_get_text_length(JWidget widget)
int jwidget_get_text_length(const Widget* widget)
{
#if 1
return ji_font_text_len(widget->getFont(), widget->getText());
@ -864,7 +739,7 @@ int jwidget_get_text_length(JWidget widget)
#endif
}
int jwidget_get_text_height(JWidget widget)
int jwidget_get_text_height(const Widget* widget)
{
ASSERT_VALID_WIDGET(widget);
@ -1182,79 +1057,14 @@ void Widget::scrollRegion(JRegion region, int dx, int dy)
}
}
/**********************************************************************/
/* signal handle */
void jwidget_signal_on(JWidget widget)
{
ASSERT_VALID_WIDGET(widget);
widget->emit_signals--;
}
void jwidget_signal_off(JWidget widget)
{
ASSERT_VALID_WIDGET(widget);
widget->emit_signals++;
}
bool jwidget_emit_signal(JWidget widget, int signal_num)
{
ASSERT_VALID_WIDGET(widget);
if (!widget->emit_signals) {
Message* msg;
bool ret;
#ifdef REPORT_SIGNALS
printf("Signal: %d (%d)\n", signal_num, widget->id);
#endif
msg = jmessage_new(JM_SIGNAL);
msg->signal.num = signal_num;
msg->signal.from = widget;
ret = widget->sendMessage(msg);
/* send the signal to the window too */
if (!ret && widget->type != JI_FRAME) {
Frame* window = widget->getRoot();
if (window)
ret = window->sendMessage(msg);
}
jmessage_free(msg);
return ret;
}
else
return false;
}
/**********************************************************************/
/* manager handler */
// ===============================================================
// GUI MANAGER
// ===============================================================
bool Widget::sendMessage(Message* msg)
{
bool done = false;
JHook hook;
JLink link;
ASSERT(msg != NULL);
JI_LIST_FOR_EACH(this->hooks, link) {
hook = reinterpret_cast<JHook>(link->data);
if (hook->msg_proc) {
done = (*hook->msg_proc)(this, msg);
if (done)
break;
}
}
if (!done)
done = this->onProcessMessage(msg);
return done;
return onProcessMessage(msg);
}
void Widget::closeWindow()
@ -1444,7 +1254,7 @@ bool Widget::onProcessMessage(Message* msg)
case JM_WINMOVE: {
JLink link;
/* broadcast the message to the children */
// Broadcast the message to the children.
JI_LIST_FOR_EACH(widget->children, link)
reinterpret_cast<JWidget>(link->data)->sendMessage(msg);
break;
@ -1500,7 +1310,7 @@ bool Widget::onProcessMessage(Message* msg)
jrect_copy(widget->rc, &msg->setpos.rect);
cpos = jwidget_get_child_rect(widget);
/* set all the children to the same "cpos" */
// Set all the children to the same "cpos".
JI_LIST_FOR_EACH(widget->children, link)
jwidget_set_rect(reinterpret_cast<JWidget>(link->data), cpos);
@ -1522,12 +1332,12 @@ bool Widget::onProcessMessage(Message* msg)
if (msg->key.propagate_to_children) {
JLink link;
/* broadcast the message to the children */
// Broadcast the message to the children.
JI_LIST_FOR_EACH(widget->children, link)
reinterpret_cast<JWidget>(link->data)->sendMessage(msg);
}
/* propagate the message to the parent */
// Propagate the message to the parent.
if (msg->key.propagate_to_parent && widget->parent != NULL)
return widget->parent->sendMessage(msg);
else
@ -1538,14 +1348,14 @@ bool Widget::onProcessMessage(Message* msg)
case JM_DOUBLECLICK:
case JM_MOTION:
case JM_WHEEL:
/* propagate the message to the parent */
// Propagate the message to the parent.
if (widget->parent != NULL)
return widget->parent->sendMessage(msg);
else
break;
case JM_SETCURSOR:
/* propagate the message to the parent */
// Propagate the message to the parent.
if (widget->parent != NULL)
return widget->parent->sendMessage(msg);
else {
@ -1615,3 +1425,38 @@ void Widget::onBroadcastMouseMessage(WidgetsList& targets)
{
// Do nothing
}
void Widget::onInitTheme(InitThemeEvent& ev)
{
if (m_theme) {
m_theme->init_widget(this);
if (!(flags & JI_INITIALIZED))
flags |= JI_INITIALIZED;
}
}
void Widget::onEnable()
{
// Do nothing
}
void Widget::onDisable()
{
// Do nothing
}
void Widget::onSelect()
{
// Do nothing
}
void Widget::onDeselect()
{
// Do nothing
}
void Widget::onSetText()
{
invalidate();
}

View File

@ -14,20 +14,16 @@
#include "gfx/size.h"
#include "gui/base.h"
#include "gui/component.h"
#include "gui/list.h"
#include "gui/rect.h"
#include "gui/widgets_list.h"
class PaintEvent;
class PreferredSizeEvent;
class InitThemeEvent;
namespace gui { class Manager; }
#ifndef NDEBUG
#include "gui/intern.h"
#define ASSERT_VALID_WIDGET(widget) ASSERT((widget) != NULL && \
_ji_is_valid_widget((widget)))
#else
#define ASSERT_VALID_WIDGET(widget) ((void)0)
#endif
#define ASSERT_VALID_WIDGET(widget) ASSERT((widget) != NULL)
struct FONT;
struct BITMAP;
@ -38,22 +34,15 @@ typedef std::vector<Widget*> WidgetsList;
int ji_register_widget_type();
/* hooks */
void jwidget_add_hook(JWidget widget, int type,
MessageFunc msg_proc, void *data);
JHook jwidget_get_hook(JWidget widget, int type);
void *jwidget_get_data(JWidget widget, int type);
/* position and geometry */
// Position and geometry
JRect jwidget_get_rect(JWidget widget);
JRect jwidget_get_child_rect(JWidget widget);
JRegion jwidget_get_region(JWidget widget);
JRegion jwidget_get_drawable_region(JWidget widget, int flags);
int jwidget_get_bg_color(JWidget widget);
int jwidget_get_text_length(JWidget widget);
int jwidget_get_text_height(JWidget widget);
int jwidget_get_text_length(const Widget* widget);
int jwidget_get_text_height(const Widget* widget);
void jwidget_get_texticon_info(JWidget widget,
JRect box, JRect text, JRect icon,
int icon_align, int icon_w, int icon_h);
@ -66,22 +55,13 @@ void jwidget_set_min_size(JWidget widget, int w, int h);
void jwidget_set_max_size(JWidget widget, int w, int h);
void jwidget_set_bg_color(JWidget widget, int color);
/* signal handle */
void jwidget_signal_on(JWidget widget);
void jwidget_signal_off(JWidget widget);
bool jwidget_emit_signal(JWidget widget, int signal_num);
//////////////////////////////////////////////////////////////////////
class Widget : public Component
{
public:
JID id; /* identify code */
int type; /* widget's type */
char *name; /* widget's name */
JRect rc; /* position rectangle */
struct {
int l, t, r, b;
@ -90,7 +70,6 @@ public:
/* flags */
int flags;
int emit_signals; /* emit signal counter */
/* widget size limits */
int min_w, min_h;
@ -100,10 +79,8 @@ public:
JList children; /* sub-objects */
JWidget parent; /* who is the parent? */
/* virtual properties */
JList hooks; /* hooks with msg_proc and specific data */
private:
std::string m_id; // Widget's id
Theme* m_theme; // Widget's theme
int m_align; // Widget alignment
std::string m_text; // Widget text
@ -129,16 +106,17 @@ public:
// queue anymore.
void deferDelete();
// main properties
// Main properties.
int getType() const;
const char* getName() const;
int getAlign() const;
int getType() const { return this->type; }
void setName(const char* name);
void setAlign(int align);
const std::string& getId() const { return m_id; }
void setId(const char* id) { m_id = id; }
// text property
int getAlign() const { return m_align; }
void setAlign(int align) { m_align = align; }
// Text property.
bool hasText() const { return flags & JI_NOTEXT ? false: true; }
@ -191,7 +169,7 @@ public:
// LOOK & FEEL
// ===============================================================
FONT* getFont();
FONT* getFont() const;
void setFont(FONT* font);
// Gets the background color of the widget.
@ -234,16 +212,27 @@ public:
Widget* pick(int x, int y);
bool hasChild(Widget* child);
Widget* findChild(const char* name);
Widget* findChild(const char* id);
// Returns a widget in the same window that is located "sibling".
Widget* findSibling(const char* name);
Widget* findSibling(const char* id);
// Finds a child with the specified name and dynamic-casts it to
// type T.
// Finds a child with the specified ID and dynamic-casts it to type
// T.
template<class T>
T* findChildT(const char* name) {
return dynamic_cast<T*>(findChild(name));
T* findChildT(const char* id) {
return dynamic_cast<T*>(findChild(id));
}
template<class T>
T* findFirstChildByType() {
JLink link;
JI_LIST_FOR_EACH(children, link) {
Widget* child = (Widget*)link->data;
if (T* specificChild = dynamic_cast<T*>(child))
return specificChild;
}
return NULL;
}
void addChild(Widget* child);
@ -337,6 +326,12 @@ protected:
virtual void onPreferredSize(PreferredSizeEvent& ev);
virtual void onPaint(PaintEvent& ev);
virtual void onBroadcastMouseMessage(WidgetsList& targets);
virtual void onInitTheme(InitThemeEvent& ev);
virtual void onEnable();
virtual void onDisable();
virtual void onSelect();
virtual void onDeselect();
virtual void onSetText();
private:
gfx::Size* m_preferredSize;

View File

@ -34,6 +34,7 @@
#include "widgets/editor/editor_customization_delegate.h"
#include "widgets/editor/editor_view.h"
#include "widgets/popup_frame_pin.h"
#include "skin/skin_theme.h"
#include "widgets/statebar.h"
#include <algorithm>
@ -67,8 +68,6 @@ Editor* current_editor = NULL;
Widget* box_editors = NULL;
static EditorList editors;
static Frame* mini_editor_frame = NULL;
static bool mini_editor_enabled = true; // True if the user wants to use the mini editor
static Editor* mini_editor = NULL;
@ -80,7 +79,6 @@ static int count_parents(Widget* widget);
static void create_mini_editor_frame();
static void hide_mini_editor_frame();
static void update_mini_editor_frame(Editor* editor);
static void on_mini_editor_frame_close(CloseEvent& ev);
class WrappedEditor : public Editor,
public EditorListener,
@ -165,6 +163,35 @@ public:
}
};
class MiniEditorFrame : public Frame
{
public:
// Create mini-editor
MiniEditorFrame() : Frame(false, "Mini-Editor") {
child_spacing = 0;
set_autoremap(false);
set_wantfocus(false);
}
protected:
void onClose(CloseEvent& ev) OVERRIDE {
Button* closeButton = dynamic_cast<Button*>(ev.getSource());
if (closeButton != NULL &&
closeButton->getId() == SkinTheme::kThemeCloseButtonId) {
// Here we don't use "enable_mini_editor" to change the state of
// "mini_editor_enabled" because we're coming from a close event
// of the frame.
mini_editor_enabled = false;
// Redraw the tool bar because it shows the mini editor enabled state.
// TODO abstract this event
app_get_toolbar()->invalidate();
}
}
};
static MiniEditorFrame* mini_editor_frame = NULL;
int init_module_editors()
{
mini_editor_enabled = get_config_bool("MiniEditor", "Enabled", true);
@ -603,13 +630,7 @@ static int count_parents(Widget* widget)
static void create_mini_editor_frame()
{
// Create mini-editor
mini_editor_frame = new Frame(false, "Mini-Editor");
mini_editor_frame->child_spacing = 0;
mini_editor_frame->set_autoremap(false);
mini_editor_frame->set_wantfocus(false);
// Hook Close button to disable mini-editor when the frame is closed.
mini_editor_frame->Close.connect(&on_mini_editor_frame_close);
mini_editor_frame = new MiniEditorFrame();
// Create the new for the mini editor
View* newView = new EditorView(EditorView::AlwaysSelected);
@ -680,17 +701,3 @@ static void update_mini_editor_frame(Editor* editor)
hide_mini_editor_frame();
}
}
static void on_mini_editor_frame_close(CloseEvent& ev)
{
if (ev.getTrigger() == CloseEvent::ByUser) {
// Here we don't use "enable_mini_editor" to change the state of
// "mini_editor_enabled" because we're coming from a close event
// of the frame.
mini_editor_enabled = false;
// Redraw the tool bar because it shows the mini editor enabled state.
// TODO abstract this event
app_get_toolbar()->invalidate();
}
}

View File

@ -38,7 +38,6 @@
#include "modules/palettes.h"
#include "modules/rootmenu.h"
#include "raster/sprite.h"
#include "resource_finder.h"
#include "skin/button_icon_impl.h"
#include "skin/skin_property.h"
#include "skin/skin_theme.h"
@ -48,7 +47,6 @@
#include "widgets/editor/editor.h"
#include "widgets/statebar.h"
#include "widgets/toolbar.h"
#include "xml_widgets.h"
#include <algorithm>
#include <allegro.h>
@ -140,7 +138,13 @@ struct Monitor
//////////////////////////////////////////////////////////////////////
static gui::Manager* manager = NULL;
class CustomizedGuiManager : public gui::Manager
{
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
};
static CustomizedGuiManager* manager = NULL;
static Theme* ase_theme = NULL;
static UniquePtr<gui::Timer> monitor_timer;
@ -165,7 +169,6 @@ static void load_gui_config(int& w, int& h, int& bpp, bool& fullscreen, bool& ma
static void save_gui_config();
static bool button_with_icon_msg_proc(JWidget widget, Message* msg);
static bool manager_msg_proc(JWidget widget, Message* msg);
static void on_palette_change_signal();
@ -296,8 +299,7 @@ int init_module_gui()
gfx_done:;
// Create the default-manager
manager = new gui::Manager();
jwidget_add_hook(manager, JI_WIDGET, manager_msg_proc, NULL);
manager = new CustomizedGuiManager();
// Setup the GUI theme for all widgets
CurrentTheme::set(ase_theme = new SkinTheme());
@ -640,136 +642,6 @@ void save_window_pos(JWidget window, const char *section)
set_config_rect(section, "WindowPos", window->getBounds());
}
Widget* load_widget(const char* filename, const char* name)
{
Widget* widget;
char buf[512];
bool found = false;
ResourceFinder rf;
rf.addPath(filename);
usprintf(buf, "widgets/%s", filename);
rf.findInDataDir(buf);
while (const char* path = rf.next()) {
if (exists(path)) {
ustrcpy(buf, path);
found = true;
break;
}
}
if (!found)
throw widget_file_not_found(filename);
widget = load_widget_from_xmlfile(buf, name);
if (!widget)
throw widget_not_found(name);
return widget;
}
JWidget find_widget(JWidget widget, const char *name)
{
Widget* child = widget->findChild(name);
if (!child)
throw widget_not_found(name);
return child;
}
//////////////////////////////////////////////////////////////////////
// Hook signals
typedef struct HookData {
int signal_num;
bool (*signal_handler)(JWidget widget, void *data);
void *data;
} HookData;
static int hook_type()
{
static int type = 0;
if (!type)
type = ji_register_widget_type();
return type;
}
static bool hook_msg_proc(JWidget widget, Message* msg)
{
switch (msg->type) {
case JM_DESTROY: {
HookData* hook_data = reinterpret_cast<HookData*>(jwidget_get_data(widget, hook_type()));
delete hook_data;
break;
}
case JM_SIGNAL: {
HookData* hook_data = reinterpret_cast<HookData*>(jwidget_get_data(widget, hook_type()));
if (hook_data &&
hook_data->signal_num == msg->signal.num) {
return (*hook_data->signal_handler)(widget, hook_data->data);
}
break;
}
}
return false;
}
// @warning You can't use this function for the same widget two times.
void hook_signal(JWidget widget,
int signal_num,
bool (*signal_handler)(JWidget widget, void* data),
void* data)
{
ASSERT(widget != NULL);
ASSERT(jwidget_get_data(widget, hook_type()) == NULL);
HookData* hook_data = new HookData;
hook_data->signal_num = signal_num;
hook_data->signal_handler = signal_handler;
hook_data->data = data;
jwidget_add_hook(widget, hook_type(), hook_msg_proc, hook_data);
}
/**
* Utility routine to get various widgets by name.
*
* @code
* if (!get_widgets(wnd,
* "name1", &widget1,
* "name2", &widget2,
* "name3", &widget3,
* NULL)) {
* ...
* }
* @endcode
*/
void get_widgets(JWidget window, ...)
{
JWidget *widget;
char *name;
va_list ap;
va_start(ap, window);
while ((name = va_arg(ap, char *))) {
widget = va_arg(ap, JWidget *);
if (!widget)
break;
*widget = window->findChild(name);
if (!*widget)
throw widget_not_found(name);
}
va_end(ap);
}
void setup_mini_look(Widget* widget)
{
setup_look(widget, MiniLook);
@ -1139,7 +1011,7 @@ void* get_monitor_data(Monitor* monitor)
}
// Manager event handler.
static bool manager_msg_proc(JWidget widget, Message* msg)
bool CustomizedGuiManager::onProcessMessage(Message* msg)
{
switch (msg->type) {
@ -1185,7 +1057,7 @@ static bool manager_msg_proc(JWidget widget, Message* msg)
break;
case JM_KEYPRESSED: {
Frame* toplevel_frame = widget->getManager()->getTopFrame();
Frame* toplevel_frame = getTopFrame();
// If there is a foreground window as top level...
if (toplevel_frame &&
@ -1254,7 +1126,7 @@ static bool manager_msg_proc(JWidget widget, Message* msg)
// Commands are executed only when the main window is
// the current window running at foreground.
JLink link;
JI_LIST_FOR_EACH(widget->children, link) {
JI_LIST_FOR_EACH(this->children, link) {
Frame* child = reinterpret_cast<Frame*>(link->data);
// There are a foreground window executing?
@ -1287,7 +1159,7 @@ static bool manager_msg_proc(JWidget widget, Message* msg)
}
return false;
return gui::Manager::onProcessMessage(msg);
}
// Slot for App::PaletteChange to regenerate graphics when the App palette is changed

View File

@ -22,7 +22,6 @@
#include <string>
#include <list>
#include "base/exception.h"
#include "base/unique_ptr.h"
#include "gui/base.h"
#include "gui/accel.h"
#include "skin/skin_property.h"
@ -38,31 +37,6 @@ class Widget;
namespace tools { class Tool; }
//////////////////////////////////////////////////////////////////////
class widget_file_not_found : public base::Exception
{
public:
widget_file_not_found(const char* file_name) throw()
: base::Exception("Cannot load file: %s\nPlease reinstall %s", file_name, PACKAGE) { }
};
/**
* Exception thrown by find_widget() if a widget is not found.
*/
class widget_not_found : public base::Exception
{
public:
widget_not_found(const char* widget_name) throw()
: base::Exception("A data file is corrupted.\nPlease reinstall %s\n\n"
"Details: Widget not found: %s", PACKAGE, widget_name) { }
};
//////////////////////////////////////////////////////////////////////
#define HOOK(widget, signal, signal_handler, data) \
hook_signal((widget), (signal), (signal_handler), (void *)(data))
class Sprite;
struct Monitor;
typedef std::list<Monitor*> MonitorList;
@ -83,16 +57,6 @@ void gui_setup_screen(bool reload_font);
void load_window_pos(Widget* window, const char *section);
void save_window_pos(Widget* window, const char *section);
Widget* load_widget(const char *filename, const char *name);
Widget* find_widget(Widget* widget, const char *name);
void hook_signal(Widget* widget,
int signal_num,
bool (*signal_handler)(Widget* widget, void *data),
void *data);
void get_widgets(Widget* window, ...);
void setup_mini_look(Widget* widget);
void setup_look(Widget* widget, LookType lookType);
void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4);
@ -130,10 +94,4 @@ Monitor* add_gui_monitor(void (*proc)(void*),
void remove_gui_monitor(Monitor* monitor);
void* get_monitor_data(Monitor* monitor);
//////////////////////////////////////////////////////////////////////
// Smart Widget* pointer
typedef UniquePtr<Widget> WidgetPtr;
typedef UniquePtr<Frame> FramePtr;
#endif

View File

@ -53,6 +53,57 @@
static std::map<std::string, int> sheet_mapping;
const char* SkinTheme::kThemeCloseButtonId = "theme_close_button";
// Controls the "X" button in a window to close it.
class WindowCloseButton : public Button
{
public:
WindowCloseButton() : Button("") {
setup_bevels(this, 0, 0, 0, 0);
setDecorative(true);
setId(SkinTheme::kThemeCloseButtonId);
}
protected:
void onClick(Event& ev) OVERRIDE {
Button::onClick(ev);
closeWindow();
}
bool onProcessMessage(Message* msg) OVERRIDE {
switch (msg->type) {
case JM_SETCURSOR:
jmouse_set_cursor(JI_CURSOR_NORMAL);
return true;
case JM_DRAW:
static_cast<SkinTheme*>(getTheme())->draw_frame_button(this, &msg->draw.rect);
return true;
case JM_KEYPRESSED:
if (msg->key.scancode == KEY_ESC) {
setSelected(true);
return true;
}
break;
case JM_KEYRELEASED:
if (msg->key.scancode == KEY_ESC) {
if (isSelected()) {
setSelected(false);
closeWindow();
return true;
}
}
break;
}
return Button::onProcessMessage(msg);
}
};
static struct
{
const char* id;
@ -648,18 +699,10 @@ void SkinTheme::init_widget(JWidget widget)
BORDER4(6 * scale, (4+6) * scale, 6 * scale, 6 * scale);
widget->border_width.t += jwidget_get_text_height(widget);
#if 1 /* add close button */
if (!(widget->flags & JI_INITIALIZED)) {
Button* button = new Button("");
setup_bevels(button, 0, 0, 0, 0);
jwidget_add_hook(button, JI_WIDGET,
&SkinTheme::theme_frame_button_msg_proc, NULL);
button->setDecorative(true);
Button* button = new WindowCloseButton();
widget->addChild(button);
button->setName("theme_close_button");
button->Click.connect(Bind<void>(&Frame::closeWindow, (Frame*)widget, button));
}
#endif
}
else {
BORDER(3 * scale);
@ -684,8 +727,7 @@ JRegion SkinTheme::get_window_mask(JWidget widget)
void SkinTheme::map_decorative_widget(JWidget widget)
{
if (widget->name != NULL &&
strcmp(widget->name, "theme_close_button") == 0) {
if (widget->getId() == kThemeCloseButtonId) {
JWidget window = widget->parent;
JRect rect = jrect_new(0, 0, 0, 0);
@ -1593,7 +1635,7 @@ void SkinTheme::draw_frame_button(ButtonBase* widget, JRect clip)
void SkinTheme::paintTooltip(PaintEvent& ev)
{
TipWindow* widget = static_cast<TipWindow*>(ev.getSource());
gui::TipWindow* widget = static_cast<gui::TipWindow*>(ev.getSource());
Graphics* g = ev.getGraphics();
gfx::Rect rc = widget->getClientBounds();
int bg = makecol(255, 255, 125);
@ -2079,46 +2121,6 @@ void SkinTheme::paintIcon(Widget* widget, Graphics* g, IButtonIcon* iconInterfac
g->drawAlphaBitmap(icon_bmp, x, y);
}
/* controls the "X" button in a window to close it */
bool SkinTheme::theme_frame_button_msg_proc(JWidget widget, Message* msg)
{
switch (msg->type) {
case JM_SETCURSOR:
jmouse_set_cursor(JI_CURSOR_NORMAL);
return true;
case JM_DRAW:
{
ButtonBase* button = dynamic_cast<ButtonBase*>(widget);
ASSERT(button && "theme_frame_button_msg_proc() must be hooked in a ButtonBase widget");
((SkinTheme*)button->getTheme())
->draw_frame_button(button, &msg->draw.rect);
}
return true;
case JM_KEYPRESSED:
if (msg->key.scancode == KEY_ESC) {
widget->setSelected(true);
return true;
}
break;
case JM_KEYRELEASED:
if (msg->key.scancode == KEY_ESC) {
if (widget->isSelected()) {
widget->setSelected(false);
widget->closeWindow();
return true;
}
}
break;
}
return false;
}
FONT* SkinTheme::loadFont(const char* userFont, const std::string& path)
{
// Directories

View File

@ -45,6 +45,8 @@ class SkinTheme : public Theme
FONT* m_minifont;
public:
static const char* kThemeCloseButtonId;
SkinTheme();
~SkinTheme();
@ -179,9 +181,6 @@ private:
void paintIcon(Widget* widget, Graphics* g, IButtonIcon* iconInterface, int x, int y);
static bool theme_frame_button_msg_proc(JWidget widget, Message* msg);
static bool theme_combobox_button_msg_proc(JWidget widget, Message* msg);
static FONT* loadFont(const char* userFont, const std::string& path);
};

View File

@ -24,7 +24,6 @@
#include "base/bind.h"
#include "gui/box.h"
#include "gui/button.h"
#include "gui/hook.h"
#include "gui/list.h"
#include "gui/system.h"
#include "gui/theme.h"
@ -78,7 +77,7 @@ ButtonSet::ButtonSet(int w, int h, int firstSelected, ...)
icon = va_arg(ap, int);
Item* item = new Item(c,
this->id + 0x1000,
reinterpret_cast<int>(this),
x == 0 && y == 0 ? 2: 0,
x == w-1 && y == 0 ? 2: 0,
x == 0 && y == h-1 ? 2: 0,
@ -87,7 +86,7 @@ ButtonSet::ButtonSet(int w, int h, int firstSelected, ...)
m_items.push_back(item);
usprintf(buf, "radio%d", c);
item->setName(buf);
item->setId(buf);
if (icon >= 0)
set_gfxicon_to_button(item, icon, icon+1, icon, JI_CENTER | JI_MIDDLE);

View File

@ -106,21 +106,6 @@ bool ColorButton::onProcessMessage(Message* msg)
app_get_statusbar()->clearText();
break;
case JM_SIGNAL:
if (msg->signal.num == JI_SIGNAL_BUTTON_SELECT) {
// If the popup window was not created or shown yet..
if (m_frame == NULL || !m_frame->isVisible()) {
// Open it
openSelectorDialog();
}
else if (!m_frame->is_moveable()) {
// If it is visible, close it
closeSelectorDialog();
}
return true;
}
break;
case JM_MOTION:
if (hasCapture()) {
Widget* picked = getManager()->pick(msg->mouse.x, msg->mouse.y);
@ -227,6 +212,21 @@ void ColorButton::onPaint(PaintEvent& ev) // TODO use "ev.getGraphics()"
textcolor, -1, false, jguiscale());
}
void ColorButton::onClick(Event& ev)
{
ButtonBase::onClick(ev);
// If the popup window was not created or shown yet..
if (m_frame == NULL || !m_frame->isVisible()) {
// Open it
openSelectorDialog();
}
else if (!m_frame->is_moveable()) {
// If it is visible, close it
closeSelectorDialog();
}
}
void ColorButton::openSelectorDialog()
{
int x, y;

View File

@ -47,6 +47,7 @@ protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
void onClick(Event& ev) OVERRIDE;
private:
void openSelectorDialog();

View File

@ -18,13 +18,12 @@
#include "config.h"
#include "widgets/fileview.h"
#include "widgets/file_list.h"
#include "app.h"
#include "base/thread.h"
#include "commands/commands.h"
#include "console.h"
#include "dialogs/filesel.h"
#include "document.h"
#include "file/file.h"
#include "gui/gui.h"
@ -46,201 +45,118 @@
using namespace gfx;
struct FileView
{
IFileItem* current_folder;
FileItemList list;
bool req_valid;
int req_w, req_h;
IFileItem* selected;
base::string exts;
/* incremental-search */
char isearch[256];
int isearch_clock;
/* thumbnail generation process */
IFileItem* item_to_generate_thumbnail;
gui::Timer timer;
MonitorList monitors; // list of monitors watching threads
FileView(Widget* widget)
: timer(widget, 200) { }
};
namespace widgets {
struct ThumbnailData
{
Monitor* monitor;
FileOp* fop;
IFileItem* fileitem;
JWidget fileview;
FileList* fileview;
Image* thumbnail;
base::thread* thread;
Palette* palette;
};
static FileView* fileview_data(JWidget widget);
static bool fileview_msg_proc(JWidget widget, Message* msg);
static void fileview_get_fileitem_size(JWidget widget, IFileItem* fi, int *w, int *h);
static void fileview_make_selected_fileitem_visible(JWidget widget);
static void fileview_regenerate_list(JWidget widget);
static int fileview_get_selected_index(JWidget widget);
static void fileview_select_index(JWidget widget, int index);
static void fileview_generate_preview_of_selected_item(JWidget widget);
static bool fileview_generate_thumbnail(JWidget widget, IFileItem* fileitem);
static void fileview_stop_threads(FileView* fileview);
static void openfile_bg(ThumbnailData* data);
static void monitor_thumbnail_generation(void *data);
static void monitor_free_thumbnail_generation(void *data);
JWidget fileview_new(IFileItem* start_folder, const base::string& exts)
FileList::FileList()
: Widget(JI_WIDGET)
, m_timer(this, 200)
{
Widget* widget = new Widget(fileview_type());
FileView* fileview = new FileView(widget);
setFocusStop(true);
if (!start_folder)
start_folder = FileSystemModule::instance()->getRootFileItem();
else {
while (!start_folder->isFolder() &&
start_folder->getParent() != NULL) {
start_folder = start_folder->getParent();
}
}
m_currentFolder = FileSystemModule::instance()->getRootFileItem();
m_req_valid = false;
m_selected = NULL;
m_isearchClock = 0;
jwidget_add_hook(widget, fileview_type(),
fileview_msg_proc, fileview);
widget->setFocusStop(true);
m_itemToGenerateThumbnail = NULL;
fileview->current_folder = start_folder;
fileview->req_valid = false;
fileview->selected = NULL;
fileview->exts = exts;
ustrcpy(fileview->isearch, empty_string);
fileview->isearch_clock = 0;
fileview->item_to_generate_thumbnail = NULL;
fileview_regenerate_list(widget);
return widget;
regenerateList();
}
int fileview_type()
FileList::~FileList()
{
static int type = 0;
if (!type)
type = ji_register_widget_type();
return type;
stopThreads();
// at this point, can't be threads running in background
ASSERT(m_monitors.empty());
}
IFileItem* fileview_get_current_folder(JWidget widget)
void FileList::setExtensions(const char* extensions)
{
return fileview_data(widget)->current_folder;
m_exts = extensions;
}
IFileItem* fileview_get_selected(JWidget widget)
void FileList::setCurrentFolder(IFileItem* folder)
{
return fileview_data(widget)->selected;
}
void fileview_set_current_folder(JWidget widget, IFileItem* folder)
{
FileView* fileview = fileview_data(widget);
ASSERT(folder != NULL);
ASSERT(folder->isBrowsable());
fileview->current_folder = folder;
fileview->req_valid = false;
fileview->selected = NULL;
m_currentFolder = folder;
m_req_valid = false;
m_selected = NULL;
fileview_regenerate_list(widget);
regenerateList();
// select first folder
if (!fileview->list.empty() && fileview->list.front()->isBrowsable())
fileview_select_index(widget, 0);
if (!m_list.empty() && m_list.front()->isBrowsable())
selectIndex(0);
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_CURRENT_FOLDER_CHANGED);
// Emit "CurrentFolderChanged" event.
onCurrentFolderChanged();
widget->invalidate();
View::getView(widget)->updateView();
invalidate();
View::getView(this)->updateView();
}
const FileItemList& fileview_get_filelist(JWidget widget)
void FileList::goUp()
{
FileView* fileview = fileview_data(widget);
return fileview->list;
}
void fileview_goup(JWidget widget)
{
FileView* fileview = fileview_data(widget);
IFileItem* folder = fileview->current_folder;
IFileItem* folder = m_currentFolder;
IFileItem* parent = folder->getParent();
if (parent) {
fileview_set_current_folder(widget, parent);
fileview->selected = folder;
setCurrentFolder(parent);
m_selected = folder;
/* make the selected item visible */
fileview_make_selected_fileitem_visible(widget);
// Make the selected item visible.
makeSelectedFileitemVisible();
}
}
static FileView* fileview_data(JWidget widget)
bool FileList::onProcessMessage(Message* msg)
{
return reinterpret_cast<FileView*>(jwidget_get_data(widget, fileview_type()));
}
static bool fileview_msg_proc(JWidget widget, Message* msg)
{
FileView* fileview = fileview_data(widget);
switch (msg->type) {
case JM_DESTROY:
fileview_stop_threads(fileview);
// at this point, can't be threads running in background
ASSERT(fileview->monitors.empty());
delete fileview;
break;
case JM_REQSIZE:
if (!fileview->req_valid) {
int w, h, iw, ih;
w = 0;
h = 0;
if (!m_req_valid) {
gfx::Size reqSize(0, 0);
// rows
for (FileItemList::iterator
it=fileview->list.begin();
it!=fileview->list.end(); ++it) {
it=m_list.begin();
it!=m_list.end(); ++it) {
IFileItem* fi = *it;
fileview_get_fileitem_size(widget, fi, &iw, &ih);
w = MAX(w, iw);
h += ih;
gfx::Size itemSize = getFileItemSize(fi);
reqSize.w = MAX(reqSize.w, itemSize.w);
reqSize.h += itemSize.h;
}
fileview->req_valid = true;
fileview->req_w = w;
fileview->req_h = h;
m_req_valid = true;
m_req_w = reqSize.w;
m_req_h = reqSize.h;
}
msg->reqsize.w = fileview->req_w;
msg->reqsize.h = fileview->req_h;
msg->reqsize.w = m_req_w;
msg->reqsize.h = m_req_h;
return true;
case JM_DRAW: {
View* view = View::getView(widget);
View* view = View::getView(this);
gfx::Rect vp = view->getViewportBounds();
int iw, ih;
int th = jwidget_get_text_height(widget);
int x, y = widget->rc->y1;
int th = jwidget_get_text_height(this);
int x, y = this->rc->y1;
int row = 0;
int bgcolor;
int fgcolor;
@ -249,12 +165,12 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
// rows
for (FileItemList::iterator
it=fileview->list.begin();
it!=fileview->list.end(); ++it) {
it=m_list.begin();
it!=m_list.end(); ++it) {
IFileItem* fi = *it;
fileview_get_fileitem_size(widget, fi, &iw, &ih);
gfx::Size itemSize = getFileItemSize(fi);
if (fi == fileview->selected) {
if (fi == m_selected) {
bgcolor = ji_color_selected();
fgcolor = ji_color_background();
}
@ -268,20 +184,20 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
ji_color_foreground();
}
x = widget->rc->x1+2;
x = this->rc->x1+2;
if (fi->isFolder()) {
int icon_w = ji_font_text_len(widget->getFont(), "[+]");
int icon_h = ji_font_get_size(widget->getFont());
int icon_w = ji_font_text_len(getFont(), "[+]");
int icon_h = ji_font_get_size(getFont());
jdraw_text(ji_screen, widget->getFont(),
jdraw_text(ji_screen, getFont(),
"[+]", x, y+2,
fgcolor, bgcolor, true, jguiscale());
// background for the icon
jrectexclude(ji_screen,
/* rectangle to fill */
widget->rc->x1, y,
this->rc->x1, y,
x+icon_w+2-1, y+2+th+2-1,
/* exclude where is the icon located */
x, y+2,
@ -295,13 +211,13 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
else {
// background for the left side of the item
rectfill(ji_screen,
widget->rc->x1, y,
this->rc->x1, y,
x-1, y+2+th+2-1,
bgcolor);
}
// item name
jdraw_text(ji_screen, widget->getFont(),
jdraw_text(ji_screen, getFont(),
fi->getDisplayName().c_str(), x, y+2,
fgcolor, bgcolor, true, jguiscale());
@ -309,20 +225,20 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
jrectexclude(ji_screen,
/* rectangle to fill */
x, y,
widget->rc->x2-1, y+2+th+2-1,
this->rc->x2-1, y+2+th+2-1,
/* exclude where is the text located */
x, y+2,
x+ji_font_text_len(widget->getFont(),
x+ji_font_text_len(this->getFont(),
fi->getDisplayName().c_str())-1,
y+2+ji_font_get_size(widget->getFont())-1,
y+2+ji_font_get_size(getFont())-1,
/* fill with the background color */
bgcolor);
// draw progress bar
if (!fileview->monitors.empty()) {
if (!m_monitors.empty()) {
for (MonitorList::iterator
it2 = fileview->monitors.begin();
it2 != fileview->monitors.end(); ++it2) {
it2 = m_monitors.begin();
it2 != m_monitors.end(); ++it2) {
Monitor* monitor = *it2;
ThumbnailData* data = (ThumbnailData*)get_monitor_data(monitor);
@ -334,8 +250,8 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
float progress = fop_get_progress(data->fop);
draw_progress_bar(ji_screen,
widget->rc->x2-2-64, y+ih/2-3,
widget->rc->x2-2, y+ih/2+3,
this->rc->x2-2-64, y+itemSize.h/2-3,
this->rc->x2-2, y+itemSize.h/2+3,
progress);
}
break;
@ -344,20 +260,20 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
}
// thumbnail position
if (fi == fileview->selected) {
if (fi == m_selected) {
thumbnail = fi->getThumbnail();
if (thumbnail)
thumbnail_y = y + ih/2;
thumbnail_y = y + itemSize.h/2;
}
y += ih;
y += itemSize.h;
row ^= 1;
}
if (y < widget->rc->y2-1)
if (y < this->rc->y2-1)
rectfill(ji_screen,
widget->rc->x1, y,
widget->rc->x2-1, widget->rc->y2-1,
this->rc->x1, y,
this->rc->x2-1, this->rc->y2-1,
ji_color_background());
/* draw the thumbnail */
@ -373,60 +289,61 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
}
// is the current folder empty?
if (fileview->list.empty())
if (m_list.empty())
draw_emptyset_symbol(ji_screen, vp, makecol(194, 194, 194));
return true;
}
case JM_BUTTONPRESSED:
widget->captureMouse();
captureMouse();
case JM_MOTION:
if (widget->hasCapture()) {
int iw, ih;
int th = jwidget_get_text_height(widget);
int y = widget->rc->y1;
IFileItem* old_selected = fileview->selected;
fileview->selected = NULL;
if (hasCapture()) {
int th = jwidget_get_text_height(this);
int y = this->rc->y1;
IFileItem* old_selected = m_selected;
m_selected = NULL;
// rows
for (FileItemList::iterator
it=fileview->list.begin();
it!=fileview->list.end(); ++it) {
it=m_list.begin();
it!=m_list.end(); ++it) {
IFileItem* fi = *it;
fileview_get_fileitem_size(widget, fi, &iw, &ih);
gfx::Size itemSize = getFileItemSize(fi);
if (((msg->mouse.y >= y) && (msg->mouse.y < y+2+th+2)) ||
(it == fileview->list.begin() && msg->mouse.y < y) ||
(it == fileview->list.end()-1 && msg->mouse.y >= y+2+th+2)) {
fileview->selected = fi;
fileview_make_selected_fileitem_visible(widget);
(it == m_list.begin() && msg->mouse.y < y) ||
(it == m_list.end()-1 && msg->mouse.y >= y+2+th+2)) {
m_selected = fi;
makeSelectedFileitemVisible();
break;
}
y += ih;
y += itemSize.h;
}
if (old_selected != fileview->selected) {
fileview_generate_preview_of_selected_item(widget);
if (old_selected != m_selected) {
generatePreviewOfSelectedItem();
widget->invalidate();
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
invalidate();
// Emit "FileSelected" event.
onFileSelected();
}
}
break;
case JM_BUTTONRELEASED:
if (widget->hasCapture()) {
widget->releaseMouse();
if (hasCapture()) {
releaseMouse();
}
break;
case JM_KEYPRESSED:
if (widget->hasFocus()) {
int select = fileview_get_selected_index(widget);
View* view = View::getView(widget);
int bottom = fileview->list.size();
if (hasFocus()) {
int select = getSelectedIndex();
View* view = View::getView(this);
int bottom = m_list.size();
switch (msg->key.scancode) {
case KEY_UP:
@ -453,7 +370,7 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
gfx::Rect vp = view->getViewportBounds();
if (select < 0)
select = 0;
select += sgn * vp.h / (2+jwidget_get_text_height(widget)+2);
select += sgn * vp.h / (2+jwidget_get_text_height(this)+2);
break;
}
case KEY_LEFT:
@ -467,25 +384,25 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
}
break;
case KEY_ENTER:
if (fileview->selected) {
if (fileview->selected->isBrowsable()) {
fileview_set_current_folder(widget, fileview->selected);
if (m_selected) {
if (m_selected->isBrowsable()) {
setCurrentFolder(m_selected);
return true;
}
if (fileview->selected->isFolder()) {
// do nothing (is a folder but not browseable
if (m_selected->isFolder()) {
// Do nothing (is a folder but not browseable.
return true;
}
else {
// a file was selected
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_ACCEPT);
// Emit "FileAccepted" event.
onFileAccepted();
return true;
}
}
else
return false;
return Widget::onProcessMessage(msg);
case KEY_BACKSPACE:
fileview_goup(widget);
goUp();
return true;
default:
if (msg->key.ascii == ' ' ||
@ -493,58 +410,56 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
utolower(msg->key.ascii) <= 'z') ||
(utolower(msg->key.ascii) >= '0' &&
utolower(msg->key.ascii) <= '9')) {
if (ji_clock - fileview->isearch_clock > ISEARCH_KEYPRESS_INTERVAL_MSECS)
ustrcpy(fileview->isearch, empty_string);
if (ji_clock - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS)
m_isearch.clear();
usprintf(fileview->isearch+ustrsize(fileview->isearch),
"%c", msg->key.ascii);
m_isearch.push_back(msg->key.ascii);
{
int i, chrs = ustrlen(fileview->isearch);
FileItemList::iterator
link = fileview->list.begin() + ((select >= 0) ? select: 0);
int i, chrs = m_isearch.size();
FileItemList::iterator
link = m_list.begin() + ((select >= 0) ? select: 0);
for (i=MAX(select, 0); i<bottom; ++i, ++link) {
IFileItem* fi = *link;
if (ustrnicmp(fi->getDisplayName().c_str(),
fileview->isearch,
chrs) == 0) {
select = i;
break;
}
for (i=MAX(select, 0); i<bottom; ++i, ++link) {
IFileItem* fi = *link;
if (ustrnicmp(fi->getDisplayName().c_str(),
m_isearch.c_str(),
chrs) == 0) {
select = i;
break;
}
}
fileview->isearch_clock = ji_clock;
/* go to fileview_select_index... */
m_isearchClock = ji_clock;
// Go to selectIndex...
}
else
return false;
return Widget::onProcessMessage(msg);
}
if (bottom > 0)
fileview_select_index(widget, MID(0, select, bottom-1));
selectIndex(MID(0, select, bottom-1));
return true;
}
break;
case JM_WHEEL: {
View* view = View::getView(widget);
View* view = View::getView(this);
if (view) {
gfx::Point scroll = view->getViewScroll();
scroll.y += (jmouse_z(1)-jmouse_z(0)) * 3*(2+jwidget_get_text_height(widget)+2);
scroll.y += (jmouse_z(1)-jmouse_z(0)) * 3*(2+jwidget_get_text_height(this)+2);
view->setViewScroll(scroll);
}
break;
}
case JM_DOUBLECLICK:
if (fileview->selected) {
if (fileview->selected->isBrowsable()) {
fileview_set_current_folder(widget, fileview->selected);
if (m_selected) {
if (m_selected->isBrowsable()) {
setCurrentFolder(m_selected);
return true;
}
else {
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_ACCEPT);
onFileAccepted(); // Emit "FileAccepted" event.
return true;
}
}
@ -552,88 +467,93 @@ static bool fileview_msg_proc(JWidget widget, Message* msg)
case JM_TIMER:
/* is time to generate the thumbnail? */
if (msg->timer.timer == &fileview->timer) {
if (msg->timer.timer == &m_timer) {
IFileItem* fileitem;
fileview->timer.stop();
m_timer.stop();
fileitem = fileview->item_to_generate_thumbnail;
fileview_generate_thumbnail(widget, fileitem);
fileitem = m_itemToGenerateThumbnail;
generateThumbnail(fileitem);
}
break;
}
return false;
return Widget::onProcessMessage(msg);
}
static void fileview_get_fileitem_size(JWidget widget, IFileItem* fi, int *w, int *h)
void FileList::onFileSelected()
{
FileSelected();
}
void FileList::onFileAccepted()
{
FileAccepted();
}
void FileList::onCurrentFolderChanged()
{
CurrentFolderChanged();
}
gfx::Size FileList::getFileItemSize(IFileItem* fi) const
{
/* char buf[512]; */
int len = 0;
if (fi->isFolder()) {
len += ji_font_text_len(widget->getFont(), "[+]")+2;
len += ji_font_text_len(getFont(), "[+]")+2;
}
len += ji_font_text_len(widget->getFont(),
fi->getDisplayName().c_str());
len += ji_font_text_len(getFont(), fi->getDisplayName().c_str());
/* if (!fileitem_is_folder(fi)) { */
/* len += 2+ji_font_text_len(widget->text_font, buf); */
/* } */
*w = 2+len+2;
*h = 2+jwidget_get_text_height(widget)+2;
return gfx::Size(2+len+2,
2+jwidget_get_text_height(this)+2);
}
static void fileview_make_selected_fileitem_visible(JWidget widget)
void FileList::makeSelectedFileitemVisible()
{
FileView* fileview = fileview_data(widget);
View* view = View::getView(widget);
View* view = View::getView(this);
gfx::Rect vp = view->getViewportBounds();
gfx::Point scroll = view->getViewScroll();
int iw, ih;
int th = jwidget_get_text_height(widget);
int y = widget->rc->y1;
int th = jwidget_get_text_height(this);
int y = this->rc->y1;
// rows
for (FileItemList::iterator
it=fileview->list.begin();
it!=fileview->list.end(); ++it) {
it=m_list.begin();
it!=m_list.end(); ++it) {
IFileItem* fi = *it;
fileview_get_fileitem_size(widget, fi, &iw, &ih);
gfx::Size itemSize = getFileItemSize(fi);
if (fi == fileview->selected) {
if (fi == m_selected) {
if (y < vp.y)
scroll.y = y - widget->rc->y1;
scroll.y = y - this->rc->y1;
else if (y > vp.y + vp.h - (2+th+2))
scroll.y = y - widget->rc->y1 - vp.h + (2+th+2);
scroll.y = y - this->rc->y1 - vp.h + (2+th+2);
view->setViewScroll(scroll);
break;
}
y += ih;
y += itemSize.h;
}
}
static void fileview_regenerate_list(JWidget widget)
void FileList::regenerateList()
{
FileView* fileview = fileview_data(widget);
// get the children of the current folder
fileview->list = fileview->current_folder->getChildren();
m_list = m_currentFolder->getChildren();
// filter the list by the available extensions
if (!fileview->exts.empty()) {
if (!m_exts.empty()) {
for (FileItemList::iterator
it=fileview->list.begin();
it!=fileview->list.end(); ) {
it=m_list.begin();
it!=m_list.end(); ) {
IFileItem* fileitem = *it;
if (!fileitem->isFolder() &&
!fileitem->hasExtension(fileview->exts.c_str())) {
it = fileview->list.erase(it);
!fileitem->hasExtension(m_exts.c_str())) {
it = m_list.erase(it);
}
else
++it;
@ -641,55 +561,50 @@ static void fileview_regenerate_list(JWidget widget)
}
}
static int fileview_get_selected_index(JWidget widget)
int FileList::getSelectedIndex()
{
FileView* fileview = fileview_data(widget);
for (FileItemList::iterator
it = fileview->list.begin();
it != fileview->list.end(); ++it) {
if (*it == fileview->selected)
return it - fileview->list.begin();
it = m_list.begin();
it != m_list.end(); ++it) {
if (*it == m_selected)
return it - m_list.begin();
}
return -1;
}
static void fileview_select_index(JWidget widget, int index)
void FileList::selectIndex(int index)
{
FileView* fileview = fileview_data(widget);
IFileItem* old_selected = fileview->selected;
IFileItem* old_selected = m_selected;
fileview->selected = fileview->list.at(index);
if (old_selected != fileview->selected) {
fileview_make_selected_fileitem_visible(widget);
m_selected = m_list.at(index);
if (old_selected != m_selected) {
makeSelectedFileitemVisible();
widget->invalidate();
jwidget_emit_signal(widget, SIGNAL_FILEVIEW_FILE_SELECTED);
invalidate();
// Emit "FileSelected" event.
onFileSelected();
}
fileview_generate_preview_of_selected_item(widget);
generatePreviewOfSelectedItem();
}
/**
* Puts the selected file-item as the next item to be processed by the
* round-robin that generate thumbnails
*/
static void fileview_generate_preview_of_selected_item(JWidget widget)
// Puts the selected file-item as the next item to be processed by the
// round-robin that generate thumbnails
void FileList::generatePreviewOfSelectedItem()
{
FileView* fileview = fileview_data(widget);
if (fileview->selected &&
!fileview->selected->isFolder() &&
!fileview->selected->getThumbnail())
if (m_selected &&
!m_selected->isFolder() &&
!m_selected->getThumbnail())
{
fileview->item_to_generate_thumbnail = fileview->selected;
fileview->timer.start();
m_itemToGenerateThumbnail = m_selected;
m_timer.start();
}
}
/* returns true if it does some hard work like access to the disk */
static bool fileview_generate_thumbnail(JWidget widget, IFileItem* fileitem)
// Returns true if it does some hard work like access to the disk.
bool FileList::generateThumbnail(IFileItem* fileitem)
{
if (fileitem->isBrowsable() ||
fileitem->getThumbnail() != NULL)
@ -710,7 +625,7 @@ static bool fileview_generate_thumbnail(JWidget widget, IFileItem* fileitem)
data->fop = fop;
data->fileitem = fileitem;
data->fileview = widget;
data->fileview = this;
data->thumbnail = NULL;
data->thread = new base::thread(&openfile_bg, data);
@ -719,8 +634,8 @@ static bool fileview_generate_thumbnail(JWidget widget, IFileItem* fileitem)
data->monitor = add_gui_monitor(monitor_thumbnail_generation,
monitor_free_thumbnail_generation, data);
fileview_data(widget)->monitors.push_back(data->monitor);
widget->invalidate();
m_monitors.push_back(data->monitor);
invalidate();
}
else {
fop_free(fop);
@ -731,22 +646,22 @@ static bool fileview_generate_thumbnail(JWidget widget, IFileItem* fileitem)
return true;
}
static void fileview_stop_threads(FileView* fileview)
void FileList::stopThreads()
{
// stop the generation of threads
fileview->timer.stop();
m_timer.stop();
// join all threads (removing all monitors)
for (MonitorList::iterator
it = fileview->monitors.begin();
it != fileview->monitors.end(); ) {
it = m_monitors.begin();
it != m_monitors.end(); ) {
Monitor* monitor = *it;
++it;
remove_gui_monitor(monitor);
}
// clear the list of monitors
fileview->monitors.clear();
m_monitors.clear();
}
// Thread to do the hard work: load the file from the disk (in
@ -834,7 +749,7 @@ static void monitor_thumbnail_generation(void *_data)
data->fileitem->setThumbnail(bmp);
/* is the selected file-item the one that now has a thumbnail? */
if (fileview_get_selected(data->fileview) == data->fileitem) {
if (data->fileview->getSelectedFileItem() == data->fileitem) {
/* we have to dirty the file-view to show the thumbnail */
data->fileview->invalidate();
}
@ -859,14 +774,10 @@ static void monitor_free_thumbnail_generation(void *_data)
data->thread->join();
delete data->thread;
// remove the monitor from the list
MonitorList& monitors(fileview_data(data->fileview)->monitors);
MonitorList::iterator it =
std::find(monitors.begin(), monitors.end(), data->monitor);
ASSERT(it != monitors.end());
monitors.erase(it);
// Remove the monitor from the FileList.
data->fileview->removeMonitor(data->monitor);
// destroy the thumbnail
// Destroy the thumbnail
if (data->thumbnail) {
image_free(data->thumbnail);
data->thumbnail = NULL;
@ -875,3 +786,12 @@ static void monitor_free_thumbnail_generation(void *_data)
fop_free(fop);
delete data;
}
void FileList::removeMonitor(Monitor* monitor)
{
MonitorList::iterator it = std::find(m_monitors.begin(), m_monitors.end(), monitor);
ASSERT(it != m_monitors.end());
m_monitors.erase(it);
}
} // namespace widgets

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