initial version
authordarco <darco@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 24 Mar 2005 21:38:25 +0000 (21:38 +0000)
committerdarco <darco@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 24 Mar 2005 21:38:25 +0000 (21:38 +0000)
git-svn-id: http://svn.voria.com/code@8 1f10aa63-cdf2-0310-b900-c93c546f37ac

484 files changed:
synfig-studio/trunk/ChangeLog [new file with mode: 0644]
synfig-studio/trunk/INSTALL [new file with mode: 0644]
synfig-studio/trunk/Makefile.am [new file with mode: 0644]
synfig-studio/trunk/NEWS [new file with mode: 0644]
synfig-studio/trunk/README [new file with mode: 0644]
synfig-studio/trunk/alphalicense.txt [new file with mode: 0644]
synfig-studio/trunk/bootstrap [new file with mode: 0755]
synfig-studio/trunk/config/ETL.m4 [new file with mode: 0755]
synfig-studio/trunk/config/build.cfg [new file with mode: 0644]
synfig-studio/trunk/config/configure.ac [new file with mode: 0755]
synfig-studio/trunk/config/cxx_macros.m4 [new file with mode: 0755]
synfig-studio/trunk/config/gnome.m4 [new file with mode: 0755]
synfig-studio/trunk/config/libxml.m4 [new file with mode: 0755]
synfig-studio/trunk/config/project.spec.in [new file with mode: 0755]
synfig-studio/trunk/config/sinfg.m4 [new file with mode: 0755]
synfig-studio/trunk/config/subs.m4 [new file with mode: 0755]
synfig-studio/trunk/debugcrash [new file with mode: 0755]
synfig-studio/trunk/fixer [new file with mode: 0755]
synfig-studio/trunk/images/Makefile.am [new file with mode: 0644]
synfig-studio/trunk/images/Makefile.inc [new file with mode: 0644]
synfig-studio/trunk/images/about_dialog.sif [new file with mode: 0644]
synfig-studio/trunk/images/about_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/angle_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/bline_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/blinepoint_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/bool_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/canvas_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/canvas_pointer_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/children_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/circle_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/clear_redo_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/clear_undo_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/color_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/draw_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/duplicate_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/eyedrop_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/fill_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/gradient_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/group_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/info_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/integer_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/keyframe_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/keyframe_lock_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/layer_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/list_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/logo.sif [new file with mode: 0644]
synfig-studio/trunk/images/meta_data_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/mirror_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/navigator_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/normal_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/pastecanvas_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/polygon_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/real_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/rectangle_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/rotate_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/saveall_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/scale_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/segment_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/sif_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/sinfg_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/sketch_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/smooth_move_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/string_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/swap_colors_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/time_track_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/valuenode_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/vector_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/wallpaper.sif [new file with mode: 0644]
synfig-studio/trunk/images/width_icon.sif [new file with mode: 0644]
synfig-studio/trunk/images/zoom_icon.sif [new file with mode: 0644]
synfig-studio/trunk/sinfgstudio.desktop.in [new file with mode: 0644]
synfig-studio/trunk/sinfgstudio.keys.in [new file with mode: 0644]
synfig-studio/trunk/sinfgstudio.mime.in [new file with mode: 0644]
synfig-studio/trunk/src/Makefile.am [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/Makefile.am [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/about.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/about.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/adjust_window.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/adjust_window.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/app.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/app.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/asyncrenderer.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/audiocontainer.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/audiocontainer.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/autorecover.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/autorecover.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasoptions.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasoptions.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasproperties.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasproperties.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvastreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvastreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasview.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/canvasview.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_time.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_time.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_value.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/cellrenderer_value.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/childrentree.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/childrentree.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/childrentreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/childrentreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/compview.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/compview.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/devicetracker.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/devicetracker.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_color.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_color.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_gradient.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_gradient.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_keyframe.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_keyframe.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_preview.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_preview.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_setup.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_setup.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_soundselect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_soundselect.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_tooloptions.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_tooloptions.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_waypoint.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialog_waypoint.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialogsettings.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dialogsettings.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_canvases.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_canvases.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_canvasspecific.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_canvasspecific.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_children.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_children.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_curves.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_curves.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_history.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_history.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_info.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_info.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_keyframes.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_keyframes.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_layergroups.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_layergroups.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_layers.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_layers.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_metadata.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_metadata.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_navigator.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_navigator.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_params.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_params.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_timetrack.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dock_timetrack.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockable.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockable.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockbook.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockbook.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockdialog.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockdialog.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockmanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/dockmanager.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/duck.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/duck.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/duckmatic.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/duckmatic.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/ducktransform_rotate.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/ducktransform_scale.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/ducktransform_translate.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/event_layerclick.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/event_mouse.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/eventkey.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/groupactionmanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/groupactionmanager.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/historytreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/historytreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/iconcontroler.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/iconcontroler.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/instance.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/instance.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/ipc.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/ipc.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframeactionmanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframeactionmanager.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframetree.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframetree.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframetreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keyframetreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keymapsettings.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/keymapsettings.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layeractionmanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layeractionmanager.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layergrouptree.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layergrouptree.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layergrouptreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layergrouptreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layerparamtreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layerparamtreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layertree.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layertree.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layertreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/layertreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/main.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/metadatatreestore.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/metadatatreestore.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/module.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/module.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/onemoment.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/onemoment.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/preview.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/preview.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renddesc.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renddesc.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/render.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/render.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_bbox.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_bbox.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_canvas.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_canvas.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_dragbox.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_dragbox.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_ducks.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_grid.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_grid.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_guides.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_guides.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_timecode.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/renderer_timecode.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/smach.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_bline.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_bline.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_circle.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_circle.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_draw.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_draw.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_eyedrop.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_eyedrop.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_fill.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_fill.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_gradient.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_gradient.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_normal.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_normal.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_polygon.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_polygon.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_rectangle.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_rectangle.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_rotate.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_rotate.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_scale.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_scale.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_sketch.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_sketch.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_smoothmove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_smoothmove.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_stroke.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_stroke.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_width.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_width.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_zoom.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/state_zoom.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/statemanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/statemanager.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/toolbox.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/toolbox.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/valuelink.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/valuelink.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_canvaschooser.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_color.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_color.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_coloredit.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_coloredit.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_compselect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_compselect.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_curves.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_curves.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_defaults.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_defaults.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_distance.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_distance.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_enum.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_enum.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_filename.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_filename.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_gradient.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_gradient.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_sound.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_sound.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_time.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_time.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_timeslider.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_timeslider.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_value.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_value.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_vector.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_vector.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_waypoint.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_waypoint.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_waypointmodel.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/widget_waypointmodel.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/workarea.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/workarea.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/workarearenderer.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/workarearenderer.h [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/zoomdial.cpp [new file with mode: 0644]
synfig-studio/trunk/src/gtkmm/zoomdial.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/Makefile.am [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action_param.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action_param.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action_system.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/action_system.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointseton.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointseton.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/colorset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/colorset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/editmodeset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/editmodeset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/gradientset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/gradientset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/grouprename.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/grouprename.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframeset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layeractivate.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layeractivate.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layeradd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layeradd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerlower.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerlower.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layermove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layermove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerparamset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerraise.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerraise.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layerremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuedescset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointremove.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointremove.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointset.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointset.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/blineconvert.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/blineconvert.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/canvasinterface.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/canvasinterface.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/cvs.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/cvs.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/editmode.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/inputdevice.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/inputdevice.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/instance.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/instance.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/main.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/main.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/selectionmanager.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/settings.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/settings.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/timegather.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/timegather.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/uimanager.cpp [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/uimanager.h [new file with mode: 0644]
synfig-studio/trunk/src/sinfgapp/value_desc.h [new file with mode: 0644]
synfig-studio/trunk/src/template.cpp [new file with mode: 0644]
synfig-studio/trunk/src/template.h [new file with mode: 0644]
synfig-studio/trunk/studio.kdevprj [new file with mode: 0644]
synfig-studio/trunk/studio.pbproj/project.pbxproj [new file with mode: 0755]
synfig-studio/trunk/studio.prj [new file with mode: 0644]
synfig-studio/trunk/win32build.sh [new file with mode: 0755]
synfig-studio/trunk/win32inst.nsi.in [new file with mode: 0644]

diff --git a/synfig-studio/trunk/ChangeLog b/synfig-studio/trunk/ChangeLog
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/synfig-studio/trunk/INSTALL b/synfig-studio/trunk/INSTALL
new file mode 100644 (file)
index 0000000..abd5c1b
--- /dev/null
@@ -0,0 +1,3 @@
+$Id: INSTALL,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+Just a placeholder for now.
+
diff --git a/synfig-studio/trunk/Makefile.am b/synfig-studio/trunk/Makefile.am
new file mode 100644 (file)
index 0000000..4fdd09f
--- /dev/null
@@ -0,0 +1,87 @@
+# $Header: /opt/voria/cvs/studio/Makefile.am,v 1.2 2005/01/17 06:25:42 darco Exp $
+
+AUTOMAKE_OPTIONS=dist-zip dist-shar dist-bzip2
+
+MAINTAINERCLEANFILES=config/config.guess config/config.sub config/ltmain.sh config/install-sh config/mkinstalldirs config/aclocal.m4 config/missing config/texinfo.tex config/depcomp aclocal.m4 config.h.in configure stamp-h.in Makefile.in config.log config.status .doc_stamp .DS_Store @PACKAGE_TARNAME@-@VERSION@.spec
+
+SUBDIRS=images src
+
+EXTRA_DIST=bootstrap config/depcomp config/cxx_macros.m4 @PACKAGE_TARNAME@-@VERSION@.spec config/project.spec.in config/build.cfg sinfg.kdevprj config/ETL.m4
+
+# Desktop entry
+#desktopdir              = $(datadir)/gnome/apps/Graphics
+desktopdir              = $(prefix)/share/applications
+desktop_DATA            = sinfgstudio.desktop
+#desktop_in_files        = sinfgstudio.desktop.in
+#desktop_DATA            = $(desktop_in_files:.desktop.in=.desktop)
+
+# @INTLTOOL_DESKTOP_RULE@
+
+mimedir              = $(prefix)/share/mime-info
+mime_DATA            = sinfgstudio.keys sinfgstudio.mime
+
+# Icon
+icondir                 = $(datadir)/pixmaps
+icon_DATA               = images/sinfg_icon.png images/sif_icon.png
+
+
+CVS=cvs
+GREP=grep
+PRINTF=printf
+SH=sh
+DOXYGEN=doxygen
+
+stats:
+       -@echo
+       -@echo  -- Stats
+       -@echo
+       -@$(PRINTF) "Total lines: "
+       -@wc -l $(shell find $(top_srcdir)/src -name '*.[ch]*' | $(GREP) -v libavcodec) | $(GREP) total
+       -@$(PRINTF) "Total size: "
+       -@du -hcs $(shell find $(top_srcdir)/src -name '*.[ch]*' | $(GREP) -v libavcodec) | $(GREP) total
+       -@echo 
+
+tagstable:
+       $(CVS) tag -F stable
+
+tagrelease:
+       $(CVS) tag -F @PACKAGE_TARNAME@_@VERSION_MAJ@_@VERSION_MIN@_@VERSION_REV@
+
+listfixmes:
+       -@echo
+       -@echo  -- List of pending FIXMEs
+       -@echo
+       -@$(GREP) FIXME -n $(shell find $(top_srcdir) -name '*.[ch]*')
+       -@echo
+
+listhacks:
+       -@echo
+       -@echo  -- List of pending HACKs
+       -@echo
+       -@$(GREP) HACK -n $(shell find $(top_srcdir) -name '*.[ch]*')
+       -@echo
+
+run: check
+
+$(srcdir)/configure:  $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       $(srcdir)/bootstrap
+
+.doc_stamp: doxygen.cfg
+       $(DOXYGEN) doxygen.cfg
+       touch .doc_stamp
+
+win32inst.nsi: win32inst.nsi.in
+       ./config.status win32inst.nsi
+
+installer: all win32inst.nsi
+       convert images/about_dialog.png images/about_dialog.bmp
+       make -C images sif_icon.ico
+       makensis win32inst.nsi
+
+html: .doc_stamp
+
+rtf: .doc_stamp
+
+docs: pdf html
+
+.PHONY: stats tagstable tagrelease listfixmes listhacks check docs pdf html rtf
diff --git a/synfig-studio/trunk/NEWS b/synfig-studio/trunk/NEWS
new file mode 100644 (file)
index 0000000..7209de9
--- /dev/null
@@ -0,0 +1,336 @@
+2004-04-26 (darco): Delete button now deletes layers
+2004-04-21 (darco): Various improvements to the dock/dialog system
+2004-04-19 (adruab): Added Zoom out to the zoom tool using the Ctrl key
+2004-04-16 (adruab): Added basic zoom tool
+2004-04-15 (darco): Added meta data stuff to properties dialog
+2004-04-12 (darco): Dockable Dialog madness!
+2004-04-08 (darco): Changed "Select All Ducks" from CTRL-F to CTRL-G
+2004-04-08 (darco): Added search capability to layer tree. (Ctrl-F)
+2004-04-08 (darco): The order of the layers is now accurate for a given moment in time
+2004-04-07 (darco): Foldy... Powers?
+2004-04-07 (darco): Added the length field to keyframe tab
+2004-04-02 (adruab): Added a preview thing... it's cool
+2004-04-02 (darco): The rulers now adhere to the default unit system
+2004-04-02 (darco): Improved defaults display
+2004-04-01 (darco): Different units now supported
+2004-03-31 (darco): Tweaks now preserved!
+2004-03-30 (darco): Checkerboard pattern now used to convey alpha
+2004-03-30 (darco): got rid of stupid negative zero thing in color selection dialog
+2004-03-30 (darco): Adjustments to color dialog to reduce crashes (hopefully)
+2004-03-30 (darco): Changed default frame rate from 30 to 24 FPS
+2004-03-30 (darco): Fixed keyframe weirdness
+2004-03-25 (darco): fixed the zillion dialog box bug
+2004-03-25 (darco): Minor improvements to parameter view
+2004-03-25 (darco): Added "Select all children" option for layers
+2004-03-24 (darco): Added hack to make connecting and disconnecting BLinePoints(vertices) easier
+2004-03-22 (darco): Improved grid snap
+2004-03-18 (darco): You can now rotate the order of the items in a list!
+2004-03-17 (darco): Linking!
+2004-03-16 (darco): You can now rename layers with a single click
+2004-03-16 (darco): You can now edit parameters even when you have multiple layers selected (Useful!)
+2004-03-15 (darco): Added the ability to jump around on the history tab
+2004-03-15 (darco): You can now right-click on ducks to edit waypoints! Group selection even!
+2004-03-08 (darco): Improved vertex addition/removal
+2004-03-05 (darco): Fixed weird tangent bug in BLine tool
+2004-03-05 (darco): You can now change all of the waypoints in a keyframe rather easily by right clicking on the keyframe in the keyframe tab and selecting "Properties".
+2004-03-05 (darco): Keyframe manipulation now much faster
+2004-03-04 (darco): BLine tool will now automaticly create if you leave the tool with something in it
+2004-03-04 (darco): You can now close polygons in the polygon tool by clicking on the first point in the polygon
+2004-03-04 (darco): Improved grid snap stuff
+2004-03-02 (darco): Fixed weird selection box when using fill tool
+2004-03-02 (darco): Fixed crash on undo stroke from sketch tool
+2004-03-02 (darco): Added Rotate Tool
+2004-03-02 (darco): Improved the performance of the duck manipulation tools
+2004-03-01 (darco): minor adjustment for deleting waypoints
+2004-03-01 (darco): Fixed a crash bug on waypoint manipulation
+2004-02-20 (darco): Changed the way the BLine tool operates
+2004-02-20 (darco): Added "Clear History" button to the "history" tab
+2004-02-18 (darco): Added palette dialog
+2004-02-18 (darco): Menus no longer activate the first item in the menu when you click to open it
+2004-02-16 (darco): slight improvement to the way gradients are handled
+2004-02-16 (darco): Added "Apply Deafult Gradient" action for gradient parameters. (just right click on them)
+2004-02-16 (darco): The mouse pointer will now change depending on the currently selected tool.
+2004-02-16 (darco): Moved icons around
+2004-02-16 (darco): File selection dialog box now remembers previous path
+2004-02-13 (darco): Added box select
+2004-02-12 (darco): Added Scale tool!
+2004-02-12 (darco): Added SmoothMove tool!
+2004-02-11 (darco): You can now drag sketch files into canvases to load the sketch
+2004-02-11 (adruab): Added rect tool and futzed with the tool options for the draw tool.
+2004-02-11 (darco) : Fixed crash-on-exit bug
+2004-02-11 (darco) : Added "File->Revert" menu option
+2004-02-10 (darco) : Crash on "CVS-Update" bug fixed
+2004-02-10 (darco) : Fixed layer-click problem after using the gradient tool
+2004-02-10 (darco) : Added "Grab" button
+2004-02-10 (darco) : Draw, Gradient, and BLine tool now add layers "in place"
+2004-02-09 (darco) : Added preliminary gradient support
+2004-02-09 (darco) : Added "CTRL-D" to unselect all layers
+2004-02-09 (darco) : Added feather option to the draw and bline tools.
+2004-02-09 (darco) : Polygon tool is now implemented correctly
+2004-02-09 (darco) : Increased the size of the "One moment please..." font.
+2004-02-09 (darco) : Negative color values are now clamped off.
+2004-02-07 (darco) : Auto recovery now no longer saves the recovery files in the same directory, which should lead to a more tidy filesystem.
+2004-02-06 (darco) : You can now move multiple layers at once
+2004-02-06 (darco) : Layer heirarchies are now less likely to collapse when moving layers.
+2004-02-06 (darco) : Raising multiple layers at the same time now works correctly
+2004-02-06 (darco) : Encapsulating no longer puts the encapsulated layer at the top
+2004-02-06 (darco) : Gradient previews are now antialiased
+2004-02-06 (darco) : Fixed odd positioning of dialogs
+2004-02-06 (darco) : Changed the BLine tool to have a more consistant user interface
+2004-02-05 (darco) : Fixed a bug in the text layer regarding the size duck
+2004-01-27 (darco) : Strokes in the draw tool should now draw better and undo better.
+2004-01-27 (darco) : Added "fill last stroke" button to draw tool options
+2004-01-27 (darco) : Auto crash-recovery feature now implemented!
+2004-01-27 (darco) : Canvas should now only redraw when a value is truly changed. (ie: just opening a parameter and not changing it will now no longer force a redraw, or add a new action)
+2004-01-24 (darco) : Improved consistancy of tool options dialog when working with several canvases at the same time
+2004-01-24 (darco) : Fixed a bug with loading sketches where the loaded sketch would dissapear.
+2004-01-23 (darco) : Fixed width duck size bug
+2004-01-23 (darco) : Improved existing icons
+2004-01-23 (darco) : Added new icons
+2004-01-23 (darco) : Fixed bug where studio would ask you to commit file not in repository or sandbox
+2004-01-22 (darco) : Initial version of the split layer tab
+2004-01-21 (darco) : Changed the "default width" to "0.01" and the default increment to "0.005"
+2004-01-21 (darco) : SINFG Studio will now ask you to commit your file to CVS upon exit if you haven't already.
+2004-01-21 (darco) : Fixed bug where the color sliders in the gradient editor didn't work.
+2004-01-21 (darco) : You can now load and save sketches
+2004-01-19 (darco) : Minor fix for remembering settings
+2004-01-19 (darco) : Added "Auto Loop" and "Auto Connect" toggles to the tool options for the draw tool.
+2004-01-19 (darco) : Tool options for the draw tool are now retained between sessions. Tool options can also be customized for specific input devices.(that last part may be slightly buggy)
+2004-01-19 (darco) : Added a "show sketch" toggle to the tool options for the scribble tool. This allows you to temporarily hide the sketch.
+2004-01-19 (darco) : changed default grid size from 0.2,0.2 to 0.25,0.25
+2004-01-17 (darco) : Individual input devices should now remember their associated settings
+2004-01-17 (darco) : Dialogs should now remember their positions
+2004-01-17 (darco) : Added some tool options for draw tool
+2004-01-16 (darco) : Tool Options dialog has been implemented. Currently the only tool that supports it is the sketch tool
+2004-01-16 (darco) : You can now clear the sketch area via the tool options dialog when the sketch tool is selected
+2004-01-16 (darco) : Changes in the color dialog are now immediately reflected in whatever is in context. (As opposed to having to always hit "apply")
+2004-01-16 (darco) : Sketch tool is now persistant. Still needs some work--as it stands, you can't undo or turn off the sketch without closing the file and opening it up again.
+2004-01-15 (darco) : Added preliminary version of the sketch tool. This version doesn't suport colors, or persist across different tools yet. This support is on the way.
+2004-01-15 (darco) : Renamed tools
+2004-01-14 (darco) : Updates for supporting new BLines
+2004-01-14 (darco) : Import tool now respects the width and height of a bitmap when placing it
+2004-01-13 (darco) : Added support for multiple-line strings (for layers such as the Text layer)
+2004-01-13 (darco) : Added low-resolution mode to work area to speed up render times. You can toggle it on and off via the View->ToggleLow-Res menu item. (Low-res mode is ON by default)
+2004-01-09 (darco) : drawing onto the start or end of an existing BLine will now extend it rather than creating a new BLine
+2004-01-09 (darco) : You can now delete canvases from the canvas browser.
+2004-01-07 (adruab) : Pen sample grouping, gets rid of small errors in line, but also tends to cause breaking to occur at lower curvatures than it should
+2004-01-06 (darco) : Preliminary support for creating regions now implemented. It is EXTREMELY buggy, but it gives you an idea of what you can do with it.
+2004-01-06 (darco) : I fixed an error that is probably the source for many of the random crashes that seem to occur.
+2004-01-05 (darco) : Individual input devices (mouse, wacom tablet, etc) will now remember their associated tool, color, and BLine width. These settings are not yet saved on program exit--this will be implemented in the future.
+2004-01-05 (darco) : You can now adjust the default BLine size by directly clicking up the upper or lower part of the BLine size indicator.
+2004-01-05 (darco) : You can now draw looped blines in the sketch tool.
+2004-01-02 (adruab) : Fixed weird reversing tangents bug
+2004-01-01 (adruab) : Added tangent breaking to the curve input tool (first post of 2004 :P)
+2003-12-28 (adruab) : Fixed the dumb adaptive tesselator, and put pressure sensitivity back in
+2003-12-28 (adruab) : Finished the "dumb" adaptive curve tesselator (-bugs)
+2003-12-28 (darco) : Added physical dimensions to properties and render dialogs
+2003-12-24 (darco) : The clicking-too-fast bug should be fixed
+2003-12-24 (darco) : Added Fill Tool
+2003-12-23 (darco) : Preliminary support for automatic vertex connection when scribbiling in the new rotoscope tool
+2003-12-19 (darco) : Fix for last vertex width being wrong when drawing
+2003-12-18 (darco) : The zero-tangent bug with the new rotoscope should also be fixed
+2003-12-18 (darco) : Tangent handles are now turned off when rotoscoping
+2003-12-18 (darco) : Improved pressure sensitivity.
+2003-12-18 (darco) : Pressure sensitivity... :)
+2003-12-18 (darco) : Preliminary tablet support now implemented
+2003-12-17 (darco) : A handful of under-the-hood tweaks that should make using the program a tad more friendly.
+2003-12-17 (darco) : Improvements to the new rotoscope
+2003-12-17 (darco) : Creating a new layer will now insert it at the depth of the currently selected layer
+2003-12-03 (darco) : The place-holder for the new rotoscope now creates blines
+2003-12-03 (darco) : Fixed minor bug with disconnecting value nodes
+2003-12-02 (darco) : Improved about dialog graphic
+2003-12-02 (darco) : When you open a really big canvas, it is now auto-zoomed out to fit the window.
+2003-12-01 (darco) : Tool buttons can now show you which tool is currently active.
+2003-11-29 (darco) : Changed default aspect ratio of new composition from 4:3 to 16:9
+2003-11-29 (darco) : Changed default resolution of new composition from 75dpi to 72dpi
+2003-11-29 (darco) : Added locks&links to properties dialog.
+2003-11-29 (darco) : Converted resolution in Properties from Dots-per-meter to Dots-per-inch
+2003-11-29 (darco) : Added stub for new rotoscope tool. It doesn't do much at the moment other than let you temporarily draw over the window.
+2003-11-25 (darco) : Removed the useless red-blue selection
+2003-11-18 (darco) : Fixed weird crash-bug when importing compositions
+2003-11-13 (darco) : Fixed bug where encapsulating might re-order the layers
+2003-11-12 (darco) : Opening a new large composition will no longer result in un-weildly large canvas windows.
+2003-11-12 (darco) : Improved all of the CVS command.
+2003-11-12 (darco) : "CVS Add" will no longer ask you for a log entry. You enter the log entry when you "commit"
+2003-11-12 (darco) : Using "saveas" will now append ".sif" to the filename if you didn't specify an extension.
+2003-11-10 (darco) : The default value increment/decrement for the Waypoint Dialog has been changed from 1.0(which is fairly useless) to 0.1. (This is mostly for the TCB controls)
+2003-11-10 (darco) : Ducks now (for the most part) are always accurate with respect to what they are visually representing. They are now context-sensitive. :)
+2003-11-06 (darco) : You can now import other SINFG compositions in the exact same way you would import any other image.
+2003-11-06 (darco) : Added "remove" to waypoint right-click menu.
+2003-11-05 (darco) : Fixed a refresh bug with the time window and the children tab
+2003-11-05 (darco) : Added the ability to duplicate waypoints
+2003-10-31 (darco) : Grid snap now works again
+2003-10-31 (darco) : Added "Jump" column to keyframe tab
+2003-10-31 (darco) : MUCH IMPROVED support for selecting and moving multiple ducks
+2003-10-30 (darco) : Preliminary support for selecting and moving multiple ducks
+2003-10-28 (darco) : Fixed CVS-MODIFIED bug due to daylight-saving time
+2003-10-22 (darco) : Added some CVS features (Although their usefulness is limited in windows)
+2003-10-22 (darco) : Fixed some weirdness with undo/redo/refresh
+2003-10-21 (darco) : Fixed some rotoscope weirdness
+2003-10-21 (darco) : Minor improvement for confusing behavior of progress bar when rendering
+2003-10-21 (darco) : A dialog box will now pop up whenever it is unable to open a composition
+2003-10-21 (darco) : Added placeholders for icons
+2003-10-21 (darco) : Fixed most (all?) of the crazy Gtk/Glib errors.
+2003-10-19 (darco) : Fixed a bug where the "Use Current Frame" option in the Render Dialog was not being checked properly (meaning you couldn't render animatons)
+2003-10-15 (darco) : Added eyedrop tool icon
+2003-10-15 (darco) : Improved scrolling of work area
+2003-10-15 (darco) : Added Eyedrop tool
+2003-10-11 (darco) : Changed default undo/redo behavior to NOT clear the "redo" stack when a new action is performed. (the previous action was to clear the redo stack)
+2003-10-11 (darco) : Fixed some weirdness with the children tab
+2003-10-11 (darco) : Several speed improvements for the tables. This will greatly speed up loading files, editing values, and adjustments to keyframes.
+2003-10-10 (darco) : The "Zoom to 100%" feature can now be accessed by pressing the "`" key. (This is the that has the "~" on it)
+2003-10-10 (darco) : The "Zoom to 100%" feature will not "toggle", meaning that if you are alreay at a "100%" zoom level, then it will return to the previous zoom amount.
+2003-10-08 (darco) : Fixed first/last point on looped bline not being splitable from the work area duck.
+2003-10-07 (darco) : Fixed weird idle->rendering->idle->rendering switching bug
+2003-10-07 (darco) : Added blend_method option to layer tab
+2003-10-07 (darco) : Added amount slider to Layer tab
+2003-10-07 (darco) : Layers are now categorized
+2003-10-06 (darco) : Added red-blue gamma adjustment to setup dialog
+2003-10-06 (darco) : Implemented Image Import Tool. (CTRL-I)
+2003-10-06 (darco) : The Ducks in the Work Area are now more percisely placed. (Especially obvious for radiuses)
+2003-10-06 (darco) : Implemented adjustable default BLine width. To adjust it, use the scroll wheel on your mouse.
+2003-10-06 (darco) : Fixed bug where changing parameters may not always refresh the work area. (AGAIN)
+2003-10-06 (darco) : Fixed dragging-layer-into-inline-canvas crash bug.
+2003-10-06 (darco) : Removed activepoint-specific actions for non-animated canvases
+2003-10-04 (darco) : Fixed bug where when dragging a layer below it ends up being one off.
+2003-10-04 (darco) : Added button to toolbox for quickly displaying the color dialog
+2003-10-04 (darco) : Fixed some minor consistancy issues regarding the layer tab. (ie: disconnections not being visible...)
+2003-10-04 (darco) : You can now sort the ValueNodes in the Children tab
+2003-10-04 (darco) : Fixed bug where changing parameters may not always refresh the work area.
+2003-10-04 (darco) : Hopefuly fixed "dissapearing new layer menu" bug
+2003-10-03 (darco) : Preliminary support for editing layer descriptions
+2003-09-30 (darco) : Changing a canvas parameter now no longer requires you to click elsewhere before it takes effect.
+2003-09-30 (darco) : Changing an Enum parameter now no longer requires you to click elsewhere before it takes effect.
+2003-09-30 (darco) : The Keyframe tab and the TimeTrack columns are now hidden when the canvas's start and end times are equal (ie: if it isn't animated)
+2003-09-30 (darco) : Added hotkey for toggling grid snap -- CONTROL-L
+2003-09-30 (darco) : Added hotkey for toggling the grid -- CONTROL-G
+2003-09-30 (darco) : Right clicking on the default colors (in the toolbox) will swap the FG and BG colors.
+2003-09-30 (darco) : Right clicking on the default gradient (in the toolbox) will revert it back to being the FG->BG gradient.
+2003-09-30 (darco) : Added several keyboard accelerators. F8="Properties Dialog", F9="Render", F12="Options"
+2003-09-30 (darco) : Added "SaveAs..." to CanvasView "File" menu.
+2003-09-30 (darco) : The "Escape" key is now bound to the stop button.
+2003-09-30 (darco) : Added red-border visual queue for when we are in animate mode.
+2003-09-30 (darco) : You can now right click on layers inside of the work area and raise/lower them
+2003-09-30 (darco) : Added the ability to change the render quality of the work area. (View->PreviewQuality)
+2003-09-30 (darco) : You can now loop/unloop BLines and DynamicLists by right clicking on them.
+2003-09-30 (darco) : You can now halt rendering by pressing the stop button
+2003-09-30 (darco) : Improved BLine editing via BLine Rotoscope tool. You now insert points by right clicking on the curve rather than the vertex.
+2003-09-29 (darco) : Improved layer Drag-N-Drop
+2003-09-25 (darco) : Layers can now be rearanged via Drag-N-Drop
+2003-09-25 (darco) : The BLine Rotoscope tool now automaticly uses more reasonable tangents
+2003-09-24 (darco) : You can now select layers from the work area that are inside inline canvases by just clicking on them.
+2003-09-24 (darco) : Selecting a layer from the work area will now cause the layer tab to scroll to make that layer visible.
+2003-09-24 (darco) : Improved in-line canvas editing (now it doesn't collapse ever time you make a change)
+2003-09-24 (darco) : Fixed the bug where the canvas wouldn't refresh if values were edited too quickly
+2003-09-24 (darco) : Added some icons to dynamicly generated menus
+2003-09-24 (darco) : Added jump-to-(next/prev)-keyframe feature (Press '[' and ']')
+2003-09-24 (darco) : Added time-zoom feature (Hold down shift and press '-' and '=')
+2003-09-24 (darco) : Fixed lagging duck bug
+2003-09-23 (darco) : Color editor will now intelegently clamp values if necessary
+2003-09-23 (darco) : Added "selected color" box to color editing dialog
+2003-09-23 (darco) : Implemented keyboard accelerators for zoom. (GIMP style -- '-' for zoom out and '=' for zoom in)
+2003-09-23 (darco) : Implemented keyboard accelerators for Duck Hiding. (press ALT-1...6)
+2003-09-23 (darco) : Angles can now be visually edited
+2003-09-23 (darco) : Added "Split Tangents" action for BLinePoints
+2003-09-23 (darco) : Added "Merge Tangents" action for BLinePoints
+2003-09-23 (darco) : Added visual BLine width adjustment
+2003-09-23 (darco) : Added smart dynamic list item remove and smart dynamic list item insert (works for BLines, too)
+2003-09-22 (darco) : Implemented Duck Masking (see menu View->DuckMask from canvasview menu)
+2003-09-22 (darco) : Implemented key accelerators in CanvasView... (eg: Ctrl-Z=Undo, Ctrl-S=Save, etc)
+2003-09-22 (darco) : Added "Keyframe Lock" button
+2003-09-17 (darco) : Added "Duplicate Keyframe" feature
+2003-09-17 (darco) : Added "Remove Keyframe" feature
+2003-09-17 (darco) : Finished SINFGApp re-write.
+2003-09-05 (darco) : Added default foreground/background colors, as well as a default gradient.
+2003-09-03 (darco) : Version Increment
+2003-09-01 (darco) : If a given layer has a color parameter, then you can now edit the color of a layer by just selecting the layer and adjusting it's color in the color dialog. You can also adjust the color of all selected layers in this way.
+2003-08-31 (darco) : Added color-selection dialog, improving the ease and intuitiveness of color selection.
+2003-08-18 (darco) : Preliminary support for dynamic point removal.
+2003-08-18 (darco) : Improved support for adding points dynamicly. 
+2003-08-14 (darco) : Preliminary support for animating the addition and removal of points
+2003-08-12 (darco) : You can now right click on segments! To add a point ot a bline, right click on the segment where you want to add the point, and then select "add point".
+2003-08-12 (darco) : You can now click on a layer in the work area and it will be selected. (Not yet supported for all layers)
+2003-08-12 (darco) : Gradient editor now works. Right click on the gradient in the editor to display a menu for adding and removing CPoints.
+2003-08-11 (darco) : You can now see ducks appear as you select children. This greatly improves the ability to edit and work with complex images.
+2003-08-06 (darco) : The canvas browser is now hidden by default. When you first load a canvas, it will pop up automaticlly.
+2003-08-06 (darco) : Added blacklevel test pattern to the gamma tab of the setup dialog. As with the other patterns, try to make the middle of the square match the outside of the square. The goal is to have the highest blacklevel setting where the blacklevel pattern looks solid black.
+2003-08-06 (darco) : I am currently working on adding support for the color gradient editor. It isn't done yet, but if you double click on a gradient, you can bring up what will be the gradient editor.
+2003-08-06 (darco) : Added "Visually Linear Color Selection" checkbox to the setup. This adjusts all color values that you see so that they are more linear in scale. The default is ON.
+2003-08-05 (darco) : The "insert point" option in the rotoscope (bline) is being implemented. It currently only works for adding points to the start of the BLine.
+2003-08-05 (darco) : The "delete point" option in the rotoscope (bline) now works. (Although, it seems to crash when you try to delete the most recent point. Investigating...)
+2003-08-04 (darco) : The setup dialog now saves your changes to disk immediately. This makes is so that if the program crashes, then we don't loose our recently-updated changes
+2003-08-04 (darco) : The setup dialog is now broken down into tabs.
+2003-08-04 (darco) : Improved the speed of the gamma adjustments in the setup dialog.
+2003-08-01 (darco) : Changes made to the setup dialog are now saved to disk, and will be automaticly reloaded upon restarting the program.
+2003-08-01 (darco) : Setup dialog is now implemented, with visual gamma adjustments and the ability to choose the type of timestamp you want
+2003-07-28 (darco) : Added gradients as viewable parameters. (the gradient editor isn't ready yet though)
+2003-07-23 (darco) : Added buttons to the toolbar for poly and bline rotoscope
+2003-07-21 (darco) : Faster window scrolling, and better tiling
+2003-07-15 (darco) : For canvas parameters, you can now select canvases that are outside of the current canvas, even in other files
+2003-07-14 (darco) : TCB controls now implemented
+2003-05-22 (darco) : The time code in the canvas view work area will turn turn "red" if you are on a keyframe
+2003-05-22 (darco) : Activepoint keyframe stuff was more broken than I realized, but it should work now..
+2003-05-22 (darco) : Activepoints can now be viewed in the track view. You can select them, but not much else. Red lines are "off" and green lines are "on"
+2003-05-19 (darco) : Fixed a crashing bug that would sneak up while animating stuff.
+2003-05-19 (darco) : Improved keyframe editing even more.
+2003-05-08 (darco) : Improved keyframe editing. One step closer to "just working". *sigh* Ahh... Automagick...
+2003-05-08 (darco) : Many, Many under the hood updates and cleanups
+2003-04-27 (darco) : Adding a new layer now inserts it at the selected depth in the stack
+2003-04-27 (darco) : Duplicating a layer now puts the clone layer next to the original layer
+2003-04-24 (darco) : Preliminary support for keyframes/dope-sheet has now been implemented!
+2003-04-23 (darco) : Fixed bug where new canvases would have weird time
+2003-04-23 (darco) : You can now import image files into a canvas by dragging them onto the canvas window
+2003-04-22 (darco) : Raising and lowering layers is now faster
+2003-04-22 (darco) : Added some convenience buttons for raising and lowering the layers
+2003-04-19 (darco) : Added timecode readout on keyframe view. (still rather non-functional)
+2003-04-17 (darco) : PasteCanvas layers will now display the name of the canvas it is pasting instead of just "PasteCanvas"
+2003-04-17 (darco) : You can now view and edit the contents of an inline canvas
+2003-04-13 (darco) : Fixed crash bug when pressing render button on render dialog with empty filename
+2003-04-13 (darco) : The render dialog now has a default file name.
+2003-04-13 (darco) : On the Canvas Browser -- renamed "Undo/Redo" tab to "History"
+2003-04-13 (darco) : The layer and children tables now do a better job of keeping in sync with the scene -- meaning that you don't have to hit "refresh" as often.
+2003-04-13 (darco) : Fixed the bug where you could not see the polygon as you were rotoscoping it.
+2003-04-11 (darco) : Fixed a bug in the time widget which would crash the program if you pressed "enter" and the de-focused it.
+2003-04-11 (darco) : Start of significant under-the-hood updates
+2003-04-11 (darco) : "Time Bar" now only appears when start time and end time are not equal.
+2003-04-11 (darco) : Implemented the "move to top" and "move to bottom"
+2003-04-07 (darco) : Changes to properties window of canvas is now undoable
+2003-04-07 (darco) : Creation of Canvases is now undoable
+2003-04-04 (darco) : Improved path rotoscope
+2003-04-03 (darco) : Added "encapsulate" option to layer menu
+2003-04-03 (darco) : All references to time now use the time code format. 
+2003-04-02 (darco) : Using the rotoscope tool to create a path is now WYSIWYG (Instead of just showing lines, you now see the curve and the control points)
+2003-04-01 (darco) : Set the default frame-rate for new compositions to 30.
+2003-03-31 (darco) : Tons of under-the-hood changes. 
+2003-03-31 (darco) : Added the ability to delete, raise, and lower items on a dynamic list
+2003-03-31 (darco) : Added dialog box to path rotoscope
+2003-03-26 (darco) : Removed the "ID" entrybox from the Canvas Properties when the canvas is root.
+2003-03-26 (darco) : Set the default end-time for new compositions to ZERO.
+2003-03-26 (darco) : Set the default frame-rate for new compositions to 15.
+2003-03-22 (darco) : Added canvas options dialog
+2003-03-22 (darco) : Added ability to adjust grid size
+
+2003-03-21 (darco) : Added "Delete" button to waypoint dialog
+
+2003-03-20 (darco) : Version Increment (0.60.03)
+2003-03-20 (darco) : Added Waypoint dialog for editing waypoints
+
+2003-03-20 (darco) : Version Increment (0.60.02)
+2003-03-20 (darco) : Names of DataNode parameters are now more readable
+2003-03-20 (darco) : Removed "Rotoscope", added "Rotoscope Path" and "Rotoscope Poly"
+
+2003-03-19 (darco) : Added "Find" button to parameters that represent filenames
+
+2003-03-17 (darco) : Fixed a bug where the "Open Recent" list is reversed when restarting the program
+2003-03-17 (darco) : Added an "Open Recent" option to the file menu on the toolbox. It remembers the last 10 files opened or saved.
+2003-03-17 (darco) : Added target selection box to render dialog.
+2003-03-17 (darco) : Added "Use current frame" checkbox to render dialog.
+
+2003-03-04 (darco) : Implemented Render Functionality.
+2003-03-04 (darco) : Added support for "angle" type.
+2003-03-04 (darco) : Deselecting a parameter-edit popup will now make it dissapear immediately, rather than after the refresh.
+
+2003-03-01 (darco) : The root canvas on a new composition is now clean, instead of having a mandelbrot set.
+
+2003-02-26 (darco) : Changed the file dialogs to use the native Win32 file open/save dialogs when built for Win32 rather than the nasty looking Gtk+ file dialogs.
+2003-02-26 (darco) : Fixed Bug 0000007 (http://dev.sinfg.com/mantis/view_bug_page.php?f_id=0000007)
diff --git a/synfig-studio/trunk/README b/synfig-studio/trunk/README
new file mode 100644 (file)
index 0000000..2e9dd47
--- /dev/null
@@ -0,0 +1,4 @@
+$Id: README,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+Just a placeholder for now.
+
+
diff --git a/synfig-studio/trunk/alphalicense.txt b/synfig-studio/trunk/alphalicense.txt
new file mode 100644 (file)
index 0000000..2419786
--- /dev/null
@@ -0,0 +1,17 @@
+Alpha Test License Agreement - Synfig Core and Synfig Studio
+Last Changed: 1-14-2004
+
+* By continuing to install this software, you agree to be bound by the terms of this agreement. READ IT CAREFULLY.
+
+* This software is owned by Voria Software, hereafter known as "the Company"
+
+* This software is a part of a closed alpha test, and is licensed for use only to those who are participating in the alpha test (Hereafter referred to as "testers"). Use of this software by anyone who is not a tester is strictly prohibited.
+
+* At the end of the alpha test, testers must cease the use and discard of all copies of this software and associated materials (ie: software documentation)
+
+* The tester maintains full ownership of any still images and/or animations that has been created by the tester with this software.
+
+* Copies of the software, screenshots of the software, and all documentation associated with this software and this alpha test should be considered confidential. Do not distribute any of these materials to anyone not participating in this alpha test without written authorization.
+
+* DISCLAIMER: THIS SOFTWARE COMES WITH NO WARRANTY OF ANY KIND. THE TESTER AGREES THAT THE COMPANY WILL NOT BE HELD LIABLE FOR ANY DAMAGES, DIRECT OR INDIRECT, RESULTING FROM THE USE, MISUSE, OR MALFUNCTION OF THIS SOFTWARE.
+
diff --git a/synfig-studio/trunk/bootstrap b/synfig-studio/trunk/bootstrap
new file mode 100755 (executable)
index 0000000..fe60751
--- /dev/null
@@ -0,0 +1,240 @@
+#! /bin/sh
+#
+# Sinfg Studio Bootstrap Script
+# $Id: bootstrap,v 1.2 2005/01/10 08:13:44 darco Exp $
+# 
+# This script creates the configure script and Makefile.in files,
+# and also fixes a few things in both to ensure a smooth build
+# on all compilers and platforms.
+#
+
+# Grab the current directory and move to our own
+CURR_DIR=$(pwd)
+cd $(dirname $0)
+
+# Environment Variables
+BOOTSTRAP_NAME=$(basename $0)
+CONFIG_DIR=$(pwd)/config
+
+. $CONFIG_DIR/build.cfg
+
+SED_SCRIPT="
+s/@PACKAGE@/$PACKAGE/g;
+s/@PACKAGE_NAME@/$PACKAGE_NAME/g;
+s/@PACKAGE_BUGREPORT@/$PACKAGE_BUGREPORT/g;
+s/@PACKAGE_TARNAME@/$PACKAGE_TARNAME/g;
+s/@PACKAGE_VERSION@/$PACKAGE_VERSION/g;
+s/@VERSION@/$VERSION/g;
+s/@VERSION_MAJ@/$VERSION_MAJ/g;
+s/@VERSION_MIN@/$VERSION_MIN/g;
+s/@VERSION_REV@/$VERSION_REV/g;
+s/@VERSION_REL@/$VERSION_REL/g;
+s/@CFLAGS@//g;
+"
+
+# Required automake and autoconf versions
+#AUTOCONF_VERSION=2.5
+#AUTOMAKE_VERSION=1.6
+#LIBTOOL_VERSION=1.4
+export WANT_AUTOMAKE=1.8
+export WANT_AUTOCONF_2_5=1
+
+LIBTOOLIZE=libtoolize
+INTLTOOLIZE=intltoolize
+AUTOCONF=autoconf
+AUTOMAKE=automake
+ACLOCAL=aclocal
+AUTOHEADER=autoheader
+
+# Define the output function
+output () {
+       echo $BOOTSTRAP_NAME: $*
+}
+
+# Define the cleanup function
+cleanup () {
+       output Cleaning up...
+       rm -fr config.cache autom4te*.cache configure.in $TEMPFILE
+}
+
+output Prepairing build environment for $PACKAGE-$VERSION...
+
+# Look for the CVS directory. If we don't find it, we need to
+# ask the user if they know what they are doing.
+test -d CVS ||
+{
+       echo "
+$BOOTSTRAP_NAME: warning: This shell script is intended for those
+$BOOTSTRAP_NAME: warning: who either know what they are doing or
+$BOOTSTRAP_NAME: warning: or downloaded this program from the CVS
+$BOOTSTRAP_NAME: warning: repository. See README for more details.
+$BOOTSTRAP_NAME: warning: To avoid seeing this message in the future,
+$BOOTSTRAP_NAME: warning: create an empty directory called 'CVS'."
+       echo Waiting for 15 seconds...
+       sleep 15
+}
+
+# Create the temporary file
+output Creating temporary file...
+TEMPFILE=`mktemp /tmp/$BOOTSTRAP_NAME.XXXXXX` ||
+{
+       output ERROR: Unable to create temporary file!
+       exit 1
+}
+
+# Check for autoconf
+(which autoconf > /dev/null 2>&1 ) ||
+{
+       output error: 'Could not find GNU autoconf!'
+       output You need to download and install GNU autoconf v2.52 or higher.
+       output '<ftp://ftp.gnu.org/gnu/autoconf>'
+       cleanup;
+       exit 1
+}
+
+# Check autoconf version
+output Using $(autoconf --version | grep utoconf)
+autoconf --version | grep -q "$AUTOCONF_VERSION" || echo \
+"$BOOTSTRAP_NAME: warning: Unexpected version of GNU Autoconf (expected $AUTOCONF_VERSION)
+$BOOTSTRAP_NAME: warning: *** Bootstrap process may fail!"
+
+# Check for automake
+(which automake > /dev/null 2>&1 ) ||
+{
+       output error: 'Could not find GNU automake!'
+       output You need to download and install GNU automake v1.5 or higher.
+       output '<ftp://ftp.gnu.org/gnu/automake>'
+       cleanup;
+       exit 1
+}
+
+# Check automake version
+output Using $(automake --version | grep utomake)
+automake --version | grep -q "$AUTOMAKE_VERSION" || echo \
+"$BOOTSTRAP_NAME: warning: Unexpected version of GNU Automake (expected $AUTOMAKE_VERSION)
+$BOOTSTRAP_NAME: warning: *** Bootstrap process may fail!"
+
+# Check for libtool
+(which libtool > /dev/null 2>&1 ) ||
+{
+       output error: 'Could not find GNU libtool!'
+       output You need to download and install GNU libtool v1.4 or higher.
+       output '<ftp://ftp.gnu.org/gnu/libtool>'
+       exit 1
+}
+
+# Check libtool version
+output Using $(libtoolize --version | grep ibtool)
+libtoolize --version | grep -q "$LIBTOOL_VERSION" || echo \
+"$BOOTSTRAP_NAME: warning: Unexpected version of GNU Libtool (expected $LIBTOOL_VERSION)
+$BOOTSTRAP_NAME: warning: *** Bootstrap process may fail!"
+
+
+aclocalfix () {
+sed '
+s:${srcdir}/intltool:${ac_aux_dir}/intltool:g;
+s.printf ("\\t%s @ %ld ;\\n", erva+name_rva, 1+ i);.printf ("\\t\\"%s\\" @ %ld ;\\n", erva+name_rva, 1+ i);.;
+' < aclocal.m4 > $TEMPFILE &&
+rm aclocal.m4 &&
+mv $TEMPFILE aclocal.m4
+}
+
+for FILENAME in project.spec ; do {
+output Creating $FILENAME...
+sed "$SED_SCRIPT" < $CONFIG_DIR/$FILENAME.in > $FILENAME;
+} ; done
+
+output Renaming project.spec to $PACKAGE-$VERSION.spec...
+mv project.spec "$PACKAGE-$VERSION.spec"
+
+output Finishing up $PACKAGE-$VERSION.spec...
+echo %changelog >> "$PACKAGE-$VERSION.spec"
+cat ChangeLog >> "$PACKAGE-$VERSION.spec"
+
+output Creating configure.in from configure.ac...
+sed "$SED_SCRIPT" < $CONFIG_DIR/configure.ac > configure.in;
+
+output Setting up build environment...
+
+# Set the shell to output what we are doing
+set -x
+
+# Create all of the build environment files
+(
+#      $INTLTOOLIZE -c &&
+       $LIBTOOLIZE -c -f &&
+       $ACLOCAL -I $CONFIG_DIR $ACLOCAL_FLAGS &&
+       aclocalfix &&
+       $AUTOHEADER &&
+       $AUTOMAKE --foreign --add-missing --copy --include-deps &&
+       $AUTOCONF -o configure &&
+       true
+) ||
+{
+       # Something went wrong...
+       set +x
+       output Failure.
+       cleanup;
+       exit 1
+}
+
+# Turn off echoing of commands
+set +x
+
+#output Patching configure script to look for gcc3...
+#sed "
+#s/g++ c++/g++3 g++ c++/;
+#s/gcc cc/gcc3 gcc cc/;
+#s:"'${prefix}/include'":"'${prefix}/include/sinfg'":;
+#s:PREFIX/include:PREFIX/include/ETL:;
+#" < configure > $TEMPFILE
+#cp $TEMPFILE configure
+
+# Patch the Makefile.in files
+for filename in $(find Makefile.in src -name Makefile.in) ; do {
+       echo $BOOTSTRAP_NAME: Patching $filename
+       (
+               cp $filename $TEMPFILE &&
+               sed "
+                       s;-I. ;;
+                       s;-I"'$(srcdir)'" ;-I"'$(top_srcdir)'" ;
+                       s;configure.in;config/configure.ac;
+               " < $TEMPFILE > $filename
+       ) ||
+       {
+               # Patch failure
+               output Failure. Unable to patch $filename.
+               cleanup;
+               exit 1
+       }
+}; done
+
+output Creating Makefile...
+( echo "
+all:
+       ./configure --enable-maintainer-mode
+       make all
+       
+install:
+       ./configure --enable-maintainer-mode
+       make install
+       
+check:
+       ./configure --enable-maintainer-mode
+       make check
+
+distcheck:
+       ./configure --enable-maintainer-mode
+       make check
+       
+dist:
+       ./configure --enable-maintainer-mode
+       make dist
+" ) > Makefile
+
+echo $BOOTSTRAP_NAME: Complete.
+
+cleanup;
+
+# Move back to the current directory
+cd $CURR_DIR
diff --git a/synfig-studio/trunk/config/ETL.m4 b/synfig-studio/trunk/config/ETL.m4
new file mode 100755 (executable)
index 0000000..f614a5b
--- /dev/null
@@ -0,0 +1,75 @@
+# ETL M4 Macro
+# For GNU Autotools
+# $Id: ETL.m4,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+#
+# By Robert B. Quattlebaum Jr. <darco@users.sf.net>
+#
+
+AC_DEFUN([ETL_DEPS],
+[
+       AC_C_BIGENDIAN
+       
+       AC_CHECK_LIB(user32, main)
+       AC_CHECK_LIB(kernel32, main)
+       AC_CHECK_LIB(pthread, main)
+               
+       AC_HEADER_STDC
+       
+       AC_CHECK_HEADERS(pthread.h)
+       AC_CHECK_HEADERS(sched.h)
+       AC_CHECK_HEADERS(sys/times.h)
+       AC_CHECK_HEADERS(sys/time.h)
+       AC_CHECK_HEADERS(unistd.h)
+       AC_CHECK_HEADERS(windows.h)
+       AC_CHECK_FUNCS([pthread_create])
+       AC_CHECK_FUNCS([pthread_rwlock_init])
+       AC_CHECK_FUNCS([pthread_yield])
+       AC_CHECK_FUNCS([sched_yield])
+       AC_CHECK_FUNCS([CreateThread])
+       AC_CHECK_FUNCS([__clone])
+       AC_CHECK_FUNCS([QueryPerformanceCounter])
+       
+       AC_CHECK_FUNCS([gettimeofday])
+       AC_CHECK_FUNCS([vsscanf])
+       AC_CHECK_FUNCS([vsprintf])
+       AC_CHECK_FUNCS([vasprintf])
+       AC_CHECK_FUNCS([vsnprintf],[],[
+               AC_CHECK_FUNC([_vsnprintf],[
+                       AC_DEFINE(vsnprintf,_vsnprintf,[define if the vsnprintf function is mangled])
+                       AC_DEFINE(HAVE_VSNPRINTF,1)
+               ])
+       ])
+       
+       $1
+])
+
+AC_DEFUN([USING_ETL],
+[
+       AC_ARG_WITH(ETL-includes,
+       [  --with-ETL-includes    Specify location of ETL headers],[
+       CXXFLAGS="$CXXFLAGS -I$withval"
+       ])
+
+       AC_PATH_PROG(ETL_CONFIG,ETL-config,no)
+
+       if test "$ETL_CONFIG" = "no"; then
+               no_ETL_config="yes"
+               $2
+       else
+               AC_MSG_CHECKING([if $ETL_CONFIG works])
+               if $ETL_CONFIG --libs >/dev/null 2>&1; then
+                       ETL_VERSION="`$ETL_CONFIG --version`"
+                       AC_MSG_RESULT([yes, $ETL_VERSION])
+                       CXXFLAGS="$CXXFLAGS `$ETL_CONFIG --cxxflags`"
+                       $1
+               else
+                       AC_MSG_RESULT(no)
+                       no_ETL_config="yes"
+                       $2
+               fi
+       fi
+
+       ETL_DEPS($1,$2)
+])
+
+
diff --git a/synfig-studio/trunk/config/build.cfg b/synfig-studio/trunk/config/build.cfg
new file mode 100644 (file)
index 0000000..f9ce723
--- /dev/null
@@ -0,0 +1,13 @@
+
+PACKAGE_NAME="Synfg Studio"
+PACKAGE_BUGREPORT="darco@voria.com"
+PACKAGE_TARNAME=synfigstudio
+VERSION_MAJ="0"
+VERSION_MIN="61"
+VERSION_REV="00"
+VERSION_REL="1"
+
+VERSION=$VERSION_MAJ.$VERSION_MIN.$VERSION_REV
+
+PACKAGE_VERSION=$VERSION
+PACKAGE=$PACKAGE_TARNAME
diff --git a/synfig-studio/trunk/config/configure.ac b/synfig-studio/trunk/config/configure.ac
new file mode 100755 (executable)
index 0000000..5281339
--- /dev/null
@@ -0,0 +1,186 @@
+# $Header: /opt/voria/cvs/studio/config/configure.ac,v 1.3 2005/01/17 05:20:08 darco Exp $
+
+# -- I N I T --------------------------------------------------
+
+. $srcdir/config/build.cfg 
+
+AC_INIT(@PACKAGE_NAME@,@PACKAGE_VERSION@,@PACKAGE_BUGREPORT@,@PACKAGE_TARNAME@)
+AC_REVISION
+
+AC_CONFIG_AUX_DIR(config)
+AM_CONFIG_HEADER(config.h)
+AC_CANONICAL_HOST
+dnl AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
+
+# -- V A R I A B L E S ----------------------------------------
+
+# -- P R O G R A M S ------------------------------------------
+
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CPP
+AC_PROG_CXXCPP
+AC_PROG_INSTALL
+
+AC_LANG_CPLUSPLUS
+
+
+AC_ARG_DEBUG
+AC_ARG_OPTIMIZATION
+AC_ARG_WARNINGS
+AC_ARG_PROFILE_ARCS
+AC_ARG_BRANCH_PROBABILITIES
+AC_ARG_PROFILING
+AC_ARG_LICENSE_KEY
+
+AC_ARG_ENABLE(g5opt,[
+  --enable-g5opt           enable optimizations specific to G5 proc],[
+    G5OPTFLAGS="-mpowerpc-gpopt -mno-multiple -mno-update -mcpu=970  -mtune=970 -falign-loops=16 -falign-functions=16"
+],
+[
+    G5OPTFLAGS=
+])
+
+AC_WIN32_QUIRKS
+
+AC_LIBTOOL_WIN32_DLL
+AC_LIBTOOL_DLOPEN
+AC_DISABLE_STATIC
+AC_ENABLE_SHARED
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+AC_LIBTOOL_PATCH
+
+
+
+
+
+dnl AC_PROG_INTLTOOL(0.11)
+
+# -- L I B R A R I E S ----------------------------------------
+
+PKG_CHECK_MODULES(GTKMM, gtkmm-2.4 gthread-2.0,[],[
+       AC_MSG_ERROR([ ** Gtkmm-2.4 Is a required library, aborting.])
+])
+AC_SUBST(GTKMM_CFLAGS)
+AC_SUBST(GTKMM_LIBS)
+
+PKG_CHECK_MODULES(SINFG, synfig ETL sigc++-2.0,,[
+       AC_MSG_ERROR([ ** Unable to set up dependent libraries])
+])
+AC_SUBST(SINFG_CFLAGS)
+AC_SUBST(SINFG_LIBS)
+
+windowsys="gtkmm"
+AC_DEFINE(STUDIO_WINSYS_H,"gtkmm/winsys.h",[blah])
+AM_CONDITIONAL(WINDOWSYS_GTKMM,true)
+
+
+# --- FMOD CHECK -------------
+AC_ARG_WITH(libfmod,[
+  --with-libfmod         Enable support for FMOD],[
+],[
+       AC_CHECK_LIB(fmod, FSOUND_Init,[
+               with_libfmod="yes"
+       ],[
+               with_libfmod="no"
+       ])
+])
+if test $with_libfmod = "yes" ; then {
+       AM_CONDITIONAL(WITH_FMOD,true)
+       FMOD_LIBS="/usr/lib/libfmod.so"
+       AC_DEFINE(WITH_FMOD,"I'm here damnit",[blah])
+} else {
+       AM_CONDITIONAL(WITH_FMOD,false)
+       FMOD_LIBS=
+} ; fi
+
+# -- H E A D E R S --------------------------------------------
+
+AC_CHECK_HEADERS([unistd.h signal.h fcntl.h])
+AC_CHECK_HEADERS([sys/types.h sys/wait.h sys/stat.h sys/time.h sys/resource.h])
+
+# -- T Y P E S & S T R U C T S --------------------------------
+
+# -- F U N C T I O N S ----------------------------------------
+
+AC_CHECK_FUNCS([fork])
+AC_CHECK_FUNCS([kill])
+AC_CHECK_FUNCS([pipe])
+AC_CHECK_FUNCS([setpriority mkfifo stat]) 
+
+# -- A R G U M E N T S ----------------------------------------
+
+# -- O U T P U T ----------------------------------------------
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CPPFLAGS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(LDFLAGS)
+
+VERSION_MAJ=@VERSION_MAJ@
+VERSION_MIN=@VERSION_MIN@
+VERSION_REV=@VERSION_REV@
+AC_SUBST(VERSION_MAJ)
+AC_SUBST(VERSION_MIN)
+AC_SUBST(VERSION_REV)
+
+# fmod stuff...
+AC_SUBST(FMOD_LIBS)
+
+imagedir=$datadir/pixmaps
+
+imageext=png
+
+AC_SUBST(imageext)
+AC_SUBST(imagedir)
+
+
+
+AC_DEFINE_UNQUOTED(IMAGE_EXT,"$imageext", [ Describes the file extension for images ] )
+
+[[ $prefix = NONE ]] && prefix=$ac_default_prefix
+export prefix
+AC_DEFINE_UNQUOTED(IMAGE_DIR,"`echo echo $imagedir | sh`", [ Describes where the icons and stuff will be ] )
+
+AC_OUTPUT(
+Makefile
+sinfgstudio.desktop
+sinfgstudio.mime
+sinfgstudio.keys
+src/Makefile
+src/gtkmm/Makefile
+src/sinfgapp/Makefile
+images/Makefile
+win32inst.nsi
+)
+
+# -- S U M M A R Y --------------------------------------------
+
+echo "
+$PACKAGE_NAME v.$VERSION
+Configuration Summary
+- - - - - -
+
+Install Prefix -------------------> $prefix
+Data Prefix ----------------------> $datadir
+Host Platform --------------------> $host
+Icon Format ----------------------> $imageext
+Debug Mode -----------------------> $debug
+Profiling Mode -------------------> $profiling
+Optimizations --------------------> $optimization
+Window System --------------------> $windowsys
+FMOD Enabled ---------------------> $with_libfmod
+
+"'$'"CXX ------------------------------> '$CXX'
+"'$'"CXXFLAGS -------------------------> '$CXXFLAGS'
+"'$'"LDFLAGS --------------------------> '$LDFLAGS'
+"'$'"SINFG_CFLAGS ---------------------> '$SINFG_CFLAGS'
+"'$'"SINFG_LIBS -----------------------> '$SINFG_LIBS'
+"'$'"GTKMM_CFLAGS ---------------------> '$GTKMM_CFLAGS'
+"'$'"GTKMM_LIBS -----------------------> '$GTKMM_LIBS'
+"
diff --git a/synfig-studio/trunk/config/cxx_macros.m4 b/synfig-studio/trunk/config/cxx_macros.m4
new file mode 100755 (executable)
index 0000000..8fc247a
--- /dev/null
@@ -0,0 +1,88 @@
+AC_DEFUN([AC_CXX_FUNCTION_NONTYPE_PARAMETERS],
+[AC_CACHE_CHECK(whether the compiler supports function templates with non-type parameters,
+ac_cv_cxx_function_nontype_parameters,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+template<class T, int N> class A {};
+template<class T, int N> int f(const A<T,N>& x) { return 0; }
+],[A<double, 17> z; return f(z);],
+ ac_cv_cxx_function_nontype_parameters=yes, ac_cv_cxx_function_nontype_parameters=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_function_nontype_parameters" = yes; then
+  AC_DEFINE(HAVE_FUNCTION_NONTYPE_PARAMETERS,,
+            [define if the compiler supports function templates with non-type parameters])
+fi
+])
+
+AC_DEFUN([AC_CXX_NAMESPACES],
+[AC_CACHE_CHECK(whether the compiler implements namespaces,
+ac_cv_cxx_namespaces,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
+                [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_namespaces" = yes; then
+  AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
+fi
+])
+
+AC_DEFUN([AC_CXX_HAVE_COMPLEX],
+[AC_CACHE_CHECK(whether the compiler has complex<T>,
+ac_cv_cxx_have_complex,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <complex>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[complex<float> a; complex<double> b; return 0;],
+ ac_cv_cxx_have_complex=yes, ac_cv_cxx_have_complex=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_complex" = yes; then
+  AC_DEFINE(HAVE_COMPLEX,,[define if the compiler has complex<T>])
+fi
+])
+
+AC_DEFUN([AC_CXX_HAVE_SSTREAM],
+[AC_CACHE_CHECK(whether the compiler has stringstream,
+ac_cv_cxx_have_sstream,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <sstream>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[stringstream message; message << "Hello"; return 0;],
+ ac_cv_cxx_have_sstream=yes, ac_cv_cxx_have_sstream=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_sstream" = yes; then
+  AC_DEFINE(HAVE_SSTREAM,,[define if the compiler has stringstream])
+fi
+])
+
+AC_DEFUN([AC_CXX_MUTABLE],
+[AC_CACHE_CHECK(whether the compiler supports the mutable keyword,
+ac_cv_cxx_mutable,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([
+class A { mutable int i;
+          public:
+          int f (int n) const { i = n; return i; }
+        };
+],[A a; return a.f (1);],
+ ac_cv_cxx_mutable=yes, ac_cv_cxx_mutable=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_mutable" = yes; then
+  AC_DEFINE(HAVE_MUTABLE,,[define if the compiler supports the mutable keyword])
+fi
+])
+
diff --git a/synfig-studio/trunk/config/gnome.m4 b/synfig-studio/trunk/config/gnome.m4
new file mode 100755 (executable)
index 0000000..a496df6
--- /dev/null
@@ -0,0 +1,407 @@
+# gnome-common.m4
+# 
+
+dnl GNOME_COMMON_INIT
+
+AC_DEFUN([GNOME_COMMON_INIT],
+[
+       AC_CACHE_VAL(ac_cv_gnome_aclocal_dir,
+       [ac_cv_gnome_aclocal_dir="$GNOME_COMMON_MACROS_DIR"])
+       AC_CACHE_VAL(ac_cv_gnome_aclocal_flags,
+       [ac_cv_gnome_aclocal_flags="$ACLOCAL_FLAGS"])
+       GNOME_ACLOCAL_DIR="$ac_cv_gnome_aclocal_dir"
+       GNOME_ACLOCAL_FLAGS="$ac_cv_gnome_aclocal_flags"
+       AC_SUBST(GNOME_ACLOCAL_DIR)
+       AC_SUBST(GNOME_ACLOCAL_FLAGS)
+
+       ACLOCAL="$ACLOCAL $GNOME_ACLOCAL_FLAGS"
+
+       AM_CONDITIONAL(INSIDE_GNOME_DOCU, false)
+])
+
+AC_DEFUN([GNOME_GTKDOC_CHECK],
+[
+       AC_CHECK_PROG(GTKDOC, gtkdoc-mkdb, true, false)
+       AM_CONDITIONAL(HAVE_GTK_DOC, $GTKDOC)
+       AC_SUBST(HAVE_GTK_DOC)
+
+       dnl Let people disable the gtk-doc stuff.
+       AC_ARG_ENABLE(gtk-doc, [  --enable-gtk-doc  Use gtk-doc to build documentation [default=auto]], enable_gtk_doc="$enableval", enable_gtk_doc=auto)
+
+       if test x$enable_gtk_doc = xauto ; then
+         if test x$GTKDOC = xtrue ; then
+           enable_gtk_doc=yes
+         else
+           enable_gtk_doc=no
+         fi
+       fi
+
+       dnl NOTE: We need to use a separate automake conditional for this
+       dnl       to make this work with the tarballs.
+       AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes)
+])
+
+AC_DEFUN([GNOME_DEBUG_CHECK],
+[
+       AC_ARG_ENABLE(debug, [  --enable-debug turn on debugging [default=no]], enable_debug="$enableval", enable_debug=no)
+
+       if test x$enable_debug = xyes ; then
+         AC_DEFINE(GNOME_ENABLE_DEBUG)
+       fi
+])
+
+# Define a conditional.
+
+AC_DEFUN([AM_CONDITIONAL],
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
+
+dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
+dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
+dnl also defines GSTUFF_PKG_ERRORS on error
+AC_DEFUN(PKG_CHECK_MODULES, [
+  succeeded=no
+
+  if test -z "$PKG_CONFIG"; then
+    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+  fi
+
+  if test "$PKG_CONFIG" = "no" ; then
+     echo "*** The pkg-config script could not be found. Make sure it is"
+     echo "*** in your path, or set the PKG_CONFIG environment variable"
+     echo "*** to the full path to pkg-config."
+     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
+  else
+     PKG_CONFIG_MIN_VERSION=0.9.0
+     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
+        AC_MSG_CHECKING(for $2)
+
+        if $PKG_CONFIG --exists "$2" ; then
+            AC_MSG_RESULT(yes)
+            succeeded=yes
+
+            AC_MSG_CHECKING($1_CFLAGS)
+            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
+            AC_MSG_RESULT($$1_CFLAGS)
+
+            AC_MSG_CHECKING($1_LIBS)
+            $1_LIBS=`$PKG_CONFIG --libs "$2"`
+            AC_MSG_RESULT($$1_LIBS)
+        else
+            $1_CFLAGS=""
+            $1_LIBS=""
+            ## If we have a custom action on failure, don't print errors, but 
+            ## do set a variable so people can do so.
+            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+            ifelse([$4], ,echo $$1_PKG_ERRORS,)
+        fi
+
+        AC_SUBST($1_CFLAGS)
+        AC_SUBST($1_LIBS)
+     else
+        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
+        echo "*** See http://www.freedesktop.org/software/pkgconfig"
+     fi
+  fi
+
+  if test $succeeded = yes; then
+     ifelse([$3], , :, [$3])
+  else
+     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
+  fi
+])
+
+
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995, 1996
+#
+# Modified to never use included libintl. 
+# Owen Taylor <otaylor@redhat.com>, 12/15/1998
+#
+#
+# This file can be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+#
+#
+# If you make changes to this file, you MUST update the copy in
+# acinclude.m4. [ aclocal dies on duplicate macros, so if
+# we run 'aclocal -I macros/' then we'll run into problems
+# once we've installed glib-gettext.m4 :-( ]
+#
+
+AC_DEFUN([AM_GLIB_LC_MESSAGES],
+  [if test $ac_cv_header_locale_h = yes; then
+    AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+      [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+    if test $am_cv_val_LC_MESSAGES = yes; then
+      AC_DEFINE(HAVE_LC_MESSAGES, 1,
+        [Define if your <locale.h> file defines LC_MESSAGES.])
+    fi
+  fi])
+
+dnl AM_GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_GLIB_PATH_PROG_WITH_TEST],
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+  /*)
+  ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in ifelse([$5], , $PATH, [$5]); do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if [$3]; then
+       ac_cv_path_$1="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+  ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+  AC_MSG_RESULT([$]$1)
+else
+  AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# serial 5
+
+AC_DEFUN(AM_GLIB_WITH_NLS,
+  dnl NLS is obligatory
+  [USE_NLS=yes
+    AC_SUBST(USE_NLS)
+
+    dnl Figure out what method
+    nls_cv_force_use_gnu_gettext="no"
+
+    nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+    if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+      dnl User does not insist on using GNU NLS library.  Figure out what
+      dnl to use.  If gettext or catgets are available (in this order) we
+      dnl use this.  Else we have to fall back to GNU NLS library.
+      dnl catgets is only used if permitted by option --with-catgets.
+      nls_cv_header_intl=
+      nls_cv_header_libgt=
+      CATOBJEXT=NONE
+      XGETTEXT=:
+
+      AC_CHECK_HEADER(libintl.h,
+        [AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc,
+         [AC_TRY_LINK([#include <libintl.h>], [return (int) dgettext ("","")],
+           gt_cv_func_dgettext_libc=yes, gt_cv_func_dgettext_libc=no)])
+
+          gt_cv_func_dgettext_libintl="no"
+          libintl_extra_libs=""
+
+         if test "$gt_cv_func_dgettext_libc" != "yes" ; then
+           AC_CHECK_LIB(intl, bindtextdomain,
+              [AC_CHECK_LIB(intl, dgettext,
+                            gt_cv_func_dgettext_libintl=yes)])
+
+           if test "$gt_cv_func_dgettext_libc" != "yes" ; then
+              AC_MSG_CHECKING([if -liconv is needed to use gettext])
+              AC_MSG_RESULT([])
+              AC_CHECK_LIB(intl, dcgettext,
+                           [gt_cv_func_dgettext_libintl=yes
+                            libintl_extra_libs=-liconv],
+                           :,-liconv)
+            fi
+          fi
+
+          if test "$gt_cv_func_dgettext_libintl" = "yes"; then
+           LIBS="$LIBS -lintl $libintl_extra_libs";
+          fi
+
+         if test "$gt_cv_func_dgettext_libc" = "yes" \
+           || test "$gt_cv_func_dgettext_libintl" = "yes"; then
+           AC_DEFINE(HAVE_GETTEXT,1,
+              [Define if the GNU gettext() function is already present or preinstalled.])
+           AM_GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+             [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+           if test "$MSGFMT" != "no"; then
+             AC_CHECK_FUNCS(dcgettext)
+             AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+             AM_GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+               [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+             AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+                            return _nl_msg_cat_cntr],
+               [CATOBJEXT=.gmo
+                DATADIRNAME=share],
+               [CATOBJEXT=.mo
+                DATADIRNAME=lib])
+             INSTOBJEXT=.mo
+           fi
+         fi
+
+         # Added by Martin Baulig 12/15/98 for libc5 systems
+         if test "$gt_cv_func_dgettext_libc" != "yes" \
+           && test "$gt_cv_func_dgettext_libintl" = "yes"; then
+           INTLLIBS="-lintl $libintl_extra_libs"
+           LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+         fi
+      ])
+
+      if test "$CATOBJEXT" = "NONE"; then
+        dnl Neither gettext nor catgets in included in the C library.
+        dnl Fall back on GNU gettext library.
+        nls_cv_use_gnu_gettext=yes
+      fi
+    fi
+
+    if test "$nls_cv_use_gnu_gettext" != "yes"; then
+      AC_DEFINE(ENABLE_NLS, 1,
+        [always defined to indicate that i18n is enabled])
+    else
+      dnl Unset this variable since we use the non-zero value as a flag.
+      CATOBJEXT=
+    fi
+
+    dnl Test whether we really found GNU xgettext.
+    if test "$XGETTEXT" != ":"; then
+      dnl If it is no GNU xgettext we define it as : so that the
+      dnl Makefiles still can work.
+      if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+        : ;
+      else
+        AC_MSG_RESULT(
+         [found xgettext program is not GNU xgettext; ignore it])
+        XGETTEXT=":"
+      fi
+    fi
+
+    # We need to process the po/ directory.
+    POSUB=po
+
+    AC_OUTPUT_COMMANDS(
+      [case "$CONFIG_FILES" in *po/Makefile.in*)
+        sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+      esac])
+
+    dnl These rules are solely for the distribution goal.  While doing this
+    dnl we only have to keep exactly one list of the available catalogs
+    dnl in configure.in.
+    for lang in $ALL_LINGUAS; do
+      GMOFILES="$GMOFILES $lang.gmo"
+      POFILES="$POFILES $lang.po"
+    done
+
+    dnl Make all variables we use known to autoconf.
+    AC_SUBST(CATALOGS)
+    AC_SUBST(CATOBJEXT)
+    AC_SUBST(DATADIRNAME)
+    AC_SUBST(GMOFILES)
+    AC_SUBST(INSTOBJEXT)
+    AC_SUBST(INTLDEPS)
+    AC_SUBST(INTLLIBS)
+    AC_SUBST(INTLOBJS)
+    AC_SUBST(POFILES)
+    AC_SUBST(POSUB)
+  ])
+
+AC_DEFUN(AM_GLIB_GNU_GETTEXT,
+  [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+   AC_REQUIRE([AC_PROG_CC])dnl
+   AC_REQUIRE([AC_PROG_RANLIB])dnl
+   AC_REQUIRE([AC_HEADER_STDC])dnl
+   AC_REQUIRE([AC_C_CONST])dnl
+   AC_REQUIRE([AC_C_INLINE])dnl
+   AC_REQUIRE([AC_TYPE_OFF_T])dnl
+   AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+   AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+   AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+   AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+   AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+   AM_GLIB_LC_MESSAGES
+   AM_GLIB_WITH_NLS
+
+   if test "x$CATOBJEXT" != "x"; then
+     if test "x$ALL_LINGUAS" = "x"; then
+       LINGUAS=
+     else
+       AC_MSG_CHECKING(for catalogs to be installed)
+       NEW_LINGUAS=
+       for lang in ${LINGUAS=$ALL_LINGUAS}; do
+         case "$ALL_LINGUAS" in
+          *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+         esac
+       done
+       LINGUAS=$NEW_LINGUAS
+       AC_MSG_RESULT($LINGUAS)
+     fi
+
+     dnl Construct list of names of catalog files to be constructed.
+     if test -n "$LINGUAS"; then
+       for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+     fi
+   fi
+
+   dnl Determine which catalog format we have (if any is needed)
+   dnl For now we know about two different formats:
+   dnl   Linux libc-5 and the normal X/Open format
+   test -d po || mkdir po
+   if test "$CATOBJEXT" = ".cat"; then
+     AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+     dnl Transform the SED scripts while copying because some dumb SEDs
+     dnl cannot handle comments.
+     sed -e '/^#/d' $srcdir/po/$msgformat-msg.sed > po/po2msg.sed
+   fi
+
+   dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+   dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+   dnl Try to locate is.
+   MKINSTALLDIRS=
+   if test -n "$ac_aux_dir"; then
+     MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+   fi
+   if test -z "$MKINSTALLDIRS"; then
+     MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+   fi
+   AC_SUBST(MKINSTALLDIRS)
+
+   dnl Generate list of files to be processed by xgettext which will
+   dnl be included in po/Makefile.
+   test -d po || mkdir po
+   if test "x$srcdir" != "x."; then
+     if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+       posrcprefix="$srcdir/"
+     else
+       posrcprefix="../$srcdir/"
+     fi
+   else
+     posrcprefix="../"
+   fi
+   rm -f po/POTFILES
+   sed -e "/^#/d" -e "/^\$/d" -e "s,.*,        $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+       < $srcdir/po/POTFILES.in > po/POTFILES
+  ])
+
diff --git a/synfig-studio/trunk/config/libxml.m4 b/synfig-studio/trunk/config/libxml.m4
new file mode 100755 (executable)
index 0000000..f6bd51f
--- /dev/null
@@ -0,0 +1,389 @@
+# Configure paths for LIBXML2
+# Toshio Kuratomi 2001-04-21
+# Adapted from:
+# Configure paths for GLIB
+# Owen Taylor     97-11-3
+
+dnl AM_PATH_XML([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for XML, and define XML_CFLAGS and XML_LIBS
+dnl
+AC_DEFUN(AM_PATH_XML,[ 
+AC_ARG_WITH(xml-prefix,
+            [  --with-xml-prefix=PFX   Prefix where libxml is installed (optional)],
+            xml_config_prefix="$withval", xml_config_prefix="")
+AC_ARG_WITH(xml-exec-prefix,
+            [  --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
+            xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
+AC_ARG_ENABLE(xmltest,
+              [  --disable-xmltest       Do not try to compile and run a test LIBXML program],,
+              enable_xmltest=yes)
+
+  if test x$xml_config_exec_prefix != x ; then
+     xml_config_args="$xml_config_args --exec-prefix=$xml_config_exec_prefix"
+     if test x${XML_CONFIG+set} != xset ; then
+        XML_CONFIG=$xml_config_exec_prefix/bin/xml-config
+     fi
+  fi
+  if test x$xml_config_prefix != x ; then
+     xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
+     if test x${XML_CONFIG+set} != xset ; then
+        XML_CONFIG=$xml_config_prefix/bin/xml-config
+     fi
+  fi
+
+  AC_PATH_PROG(XML_CONFIG, xml-config, no)
+  min_xml_version=ifelse([$1], ,1.0.0,[$1])
+  AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
+  no_xml=""
+  if test "$XML_CONFIG" = "no" ; then
+    no_xml=yes
+  else
+    XML_CFLAGS=`$XML_CONFIG $xml_config_args --cflags`
+    XML_LIBS=`$XML_CONFIG $xml_config_args --libs`
+    xml_config_major_version=`$XML_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    xml_config_minor_version=`$XML_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    xml_config_micro_version=`$XML_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_xmltest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $XML_CFLAGS"
+      LIBS="$XML_LIBS $LIBS"
+dnl
+dnl Now check if the installed libxml is sufficiently new.
+dnl (Also sanity checks the results of xml-config to some extent)
+dnl
+      rm -f conf.xmltest
+      AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libxml/tree.h>
+
+int 
+main()
+{
+  int xml_major_version, xml_minor_version, xml_micro_version;
+  int major, minor, micro;
+  char *tmp_version;
+  int tmp_int_version;
+
+  system("touch conf.xmltest");
+
+  /* Capture xml-config output via autoconf/configure variables */
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = (char *)strdup("$min_xml_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string from xml-config\n", "$min_xml_version");
+     exit(1);
+   }
+   free(tmp_version);
+
+   /* Capture the version information from the header files */
+   tmp_int_version = LIBXML_VERSION;
+   xml_major_version=tmp_int_version / 10000;
+   xml_minor_version=(tmp_int_version - xml_major_version * 10000) / 100;
+   xml_micro_version=(tmp_int_version - xml_minor_version * 100 - xml_major_version * 10000);
+
+ /* Compare xml-config output to the libxml headers */
+  if ((xml_major_version != $xml_config_major_version) ||
+      (xml_minor_version != $xml_config_minor_version)
+#if 0
+      ||
+/* The last released version of libxml-1.x has an incorrect micro version in
+ * the header file so neither the includes nor the library will match the
+ * micro_version to the output of xml-config
+ */
+      (xml_micro_version != $xml_config_micro_version)
+#endif 
+         )
+         
+    {
+      printf("*** libxml header files (version %d.%d.%d) do not match\n",
+         xml_major_version, xml_minor_version, xml_micro_version);
+      printf("*** xml-config (version %d.%d.%d)\n",
+         $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
+      return 1;
+    } 
+/* Compare the headers to the library to make sure we match */
+  /* Less than ideal -- doesn't provide us with return value feedback, 
+   * only exits if there's a serious mismatch between header and library.
+   */
+    LIBXML_TEST_VERSION;
+
+    /* Test that the library is greater than our minimum version */
+    if (($xml_config_major_version > major) ||
+        (($xml_config_major_version == major) && ($xml_config_minor_version > minor)) ||
+        (($xml_config_major_version == major) && ($xml_config_minor_version == minor) &&
+        ($xml_config_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
+               xml_major_version, xml_minor_version, xml_micro_version);
+        printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
+           major, minor, micro);
+        printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the xml-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of LIBXML, but you can also set the XML_CONFIG environment to point to the\n");
+        printf("*** correct copy of xml-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+    }
+  return 1;
+}
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+
+  if test "x$no_xml" = x ; then
+     AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$XML_CONFIG" = "no" ; then
+       echo "*** The xml-config script installed by LIBXML could not be found"
+       echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the XML_CONFIG environment variable to the"
+       echo "*** full path to xml-config."
+     else
+       if test -f conf.xmltest ; then
+        :
+       else
+          echo "*** Could not run libxml test program, checking why..."
+          CFLAGS="$CFLAGS $XML_CFLAGS"
+          LIBS="$LIBS $XML_LIBS"
+          AC_TRY_LINK([
+#include <libxml/tree.h>
+#include <stdio.h>
+],      [ LIBXML_TEST_VERSION; return 0;],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
+          echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+          echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
+          echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
+          echo "*** may want to edit the xml-config script: $XML_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+
+     XML_CFLAGS=""
+     XML_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(XML_CFLAGS)
+  AC_SUBST(XML_LIBS)
+  rm -f conf.xmltest
+])
+
+# Configure paths for LIBXML2
+# Toshio Kuratomi 2001-04-21
+# Adapted from:
+# Configure paths for GLIB
+# Owen Taylor     97-11-3
+
+dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for XML, and define XML_CFLAGS and XML_LIBS
+dnl
+AC_DEFUN(AM_PATH_XML2,[ 
+AC_ARG_WITH(xml-prefix,
+            [  --with-xml-prefix=PFX   Prefix where libxml is installed (optional)],
+            xml_config_prefix="$withval", xml_config_prefix="")
+AC_ARG_WITH(xml-exec-prefix,
+            [  --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
+            xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
+AC_ARG_ENABLE(xmltest,
+              [  --disable-xmltest       Do not try to compile and run a test LIBXML program],,
+              enable_xmltest=yes)
+
+  if test x$xml_config_exec_prefix != x ; then
+     xml_config_args="$xml_config_args --exec-prefix=$xml_config_exec_prefix"
+     if test x${XML2_CONFIG+set} != xset ; then
+        XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
+     fi
+  fi
+  if test x$xml_config_prefix != x ; then
+     xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
+     if test x${XML2_CONFIG+set} != xset ; then
+        XML2_CONFIG=$xml_config_prefix/bin/xml2-config
+     fi
+  fi
+
+  AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
+  min_xml_version=ifelse([$1], ,2.0.0,[$1])
+  AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
+  no_xml=""
+  if test "$XML2_CONFIG" = "no" ; then
+    no_xml=yes
+  else
+    XML_CFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
+    XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
+    xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_xmltest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_CXXFLAGS="$CXXFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $XML_CFLAGS"
+      CXXFLAGS="$CXXFLAGS $XML_CFLAGS"
+      LIBS="$XML_LIBS $LIBS"
+dnl
+dnl Now check if the installed libxml is sufficiently new.
+dnl (Also sanity checks the results of xml2-config to some extent)
+dnl
+      rm -f conf.xmltest
+      AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libxml/xmlversion.h>
+
+int 
+main()
+{
+  int xml_major_version, xml_minor_version, xml_micro_version;
+  int major, minor, micro;
+  char *tmp_version;
+
+  system("touch conf.xmltest");
+
+  /* Capture xml2-config output via autoconf/configure variables */
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = (char *)strdup("$min_xml_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string from xml2-config\n", "$min_xml_version");
+     exit(1);
+   }
+   free(tmp_version);
+
+   /* Capture the version information from the header files */
+   tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
+   if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
+     printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
+     exit(1);
+   }
+   free(tmp_version);
+
+ /* Compare xml2-config output to the libxml headers */
+  if ((xml_major_version != $xml_config_major_version) ||
+      (xml_minor_version != $xml_config_minor_version) ||
+      (xml_micro_version != $xml_config_micro_version))
+    {
+      printf("*** libxml header files (version %d.%d.%d) do not match\n",
+         xml_major_version, xml_minor_version, xml_micro_version);
+      printf("*** xml2-config (version %d.%d.%d)\n",
+         $xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
+      return 1;
+    } 
+/* Compare the headers to the library to make sure we match */
+  /* Less than ideal -- doesn't provide us with return value feedback, 
+   * only exits if there's a serious mismatch between header and library.
+   */
+    LIBXML_TEST_VERSION;
+
+    /* Test that the library is greater than our minimum version */
+    if ((xml_major_version > major) ||
+        ((xml_major_version == major) && (xml_minor_version > minor)) ||
+        ((xml_major_version == major) && (xml_minor_version == minor) &&
+        (xml_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
+               xml_major_version, xml_minor_version, xml_micro_version);
+        printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
+           major, minor, micro);
+        printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
+        printf("*** correct copy of xml2-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+    }
+  return 1;
+}
+],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       CXXFLAGS="$ac_save_CXXFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+
+  if test "x$no_xml" = x ; then
+     AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$XML2_CONFIG" = "no" ; then
+       echo "*** The xml2-config script installed by LIBXML could not be found"
+       echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the XML2_CONFIG environment variable to the"
+       echo "*** full path to xml2-config."
+     else
+       if test -f conf.xmltest ; then
+        :
+       else
+          echo "*** Could not run libxml test program, checking why..."
+          CFLAGS="$CFLAGS $XML_CFLAGS"
+          CXXFLAGS="$CXXFLAGS $XML_CFLAGS"
+          LIBS="$LIBS $XML_LIBS"
+          AC_TRY_LINK([
+#include <libxml/xmlversion.h>
+#include <stdio.h>
+],      [ LIBXML_TEST_VERSION; return 0;],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
+          echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+          echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
+          echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
+          echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          CXXFLAGS="$ac_save_CXXFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+
+     XML_CFLAGS=""
+     XML_LIBS=""
+     $3
+
+
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(XML_CFLAGS)
+  AC_SUBST(XML_LIBS)
+  rm -f conf.xmltest
+])
diff --git a/synfig-studio/trunk/config/project.spec.in b/synfig-studio/trunk/config/project.spec.in
new file mode 100755 (executable)
index 0000000..2826101
--- /dev/null
@@ -0,0 +1,47 @@
+
+Summary: Voria Extented Template Library
+Name: @PACKAGE_TARNAME@-devel
+Version: @VERSION_MAJ@.@VERSION_MIN@.@VERSION_REV@
+Release: @VERSION_REL@
+Copyright: free (see license), see /usr/share/doc/%{name}-%{version}/license.html
+URL: http://www.voria.com/
+Packager: Robert B. Quattlebaum Jr. <darco@bigfoot.com>
+Group: Development/Languages
+Icon: config/logo.gif
+#Source0: http://www.stlport.org/archive/%{name}-%{version}.tar.gz
+#Patch0: STLport-rename.patch
+#Patch1: STLport-rules.patch
+#Patch2: STLport-install-dir.patch
+Buildroot: %{_tmppath}/%{name}-%{version}-%(id -u -n)
+
+%description
+VoriaETL is a multiplatform class and template library 
+designed to complement and supplement the C++ STL.
+
+%prep
+%setup
+#%patch0 -p1
+#%patch1 -p1
+#%patch2 -p1
+
+%build
+./configure --prefix=$RPM_BUILD_ROOT
+make
+
+%install
+make install
+
+%clean
+make clean
+
+%post -n @PACKAGE@-devel
+/sbin/ldconfig
+
+%postun -n @PACKAGE@-devel
+/sbin/ldconfig
+
+%files
+%defattr(-,root,root)
+%doc INSTALL README doc test
+/usr/include/*
+
diff --git a/synfig-studio/trunk/config/sinfg.m4 b/synfig-studio/trunk/config/sinfg.m4
new file mode 100755 (executable)
index 0000000..b4df86f
--- /dev/null
@@ -0,0 +1,51 @@
+# SINFG M4 Macro
+# For GNU Autotools
+# $Id: sinfg.m4,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+#
+# By Robert B. Quattlebaum Jr. <darco@users.sf.net>
+#
+
+AC_DEFUN([SINFG_DEPS],
+[
+       USING_ETL(,$2)
+       AM_PATH_XML2(,,$2)
+       AC_CHECK_FUNCS([floor pow sqrt],,$2)
+       $1
+])
+
+AC_DEFUN([USING_SINFG],
+[
+       AC_ARG_WITH(sinfg-includes,
+       [  --with-sinfg-includes    Specify location of sinfg headers],[
+       CXXFLAGS="$CXXFLAGS -I$withval"
+       ])
+
+       AC_PATH_PROG(SINFG_CONFIG,sinfg-config,no)
+
+       if test "$SINFG_CONFIG" = "no"; then
+               no_SINFG_config="yes"
+               $2
+       else
+               AC_MSG_CHECKING([if $SINFG_CONFIG works])
+               if $SINFG_CONFIG --libs >/dev/null 2>&1; then
+                       SINFG_VERSION="`$SINFG_CONFIG --version`"
+                       AC_MSG_RESULT([yes, $SINFG_VERSION])
+                       SINFG_CXXFLAGS="`$SINFG_CONFIG --cxxflags`"
+                       SINFG_CFLAGS="`$SINFG_CONFIG --cflags`"
+                       SINFG_LIBS="`$SINFG_CONFIG --libs`"
+                       CXXFLAGS="$CXXFLAGS $SINFG_CXXFLAGS"
+                       AC_SUBST(SINFG_CXXFLAGS)
+                       AC_SUBST(SINFG_LIBS)
+                       AC_SUBST(SINFG_CFLAGS)
+                       $1
+               else
+                       AC_MSG_RESULT(no)
+                       no_SINFG_config="yes"
+                       $2
+               fi
+       fi
+
+       SINFG_DEPS($1,$2)
+])
+
+
diff --git a/synfig-studio/trunk/config/subs.m4 b/synfig-studio/trunk/config/subs.m4
new file mode 100755 (executable)
index 0000000..e7bab1c
--- /dev/null
@@ -0,0 +1,276 @@
+
+## AC_ARG_WARNINGS()
+##
+## Provide the --enable-warnings configure argument, set to 'minimum'
+## by default.
+##
+AC_DEFUN([AC_ARG_WARNINGS],
+[
+  AC_ARG_ENABLE([warnings],
+      [  --enable-warnings=[[none|minimum|maximum|hardcore]]
+                          Control compiler pickyness.  [[default=maximum]]],
+      [gtkmm_enable_warnings="$enableval"],
+      gtkmm_enable_warnings="maximum")
+
+  AC_MSG_CHECKING([for compiler warning flags to use])
+
+  gtkmm_warning_flags=''
+
+  case "$gtkmm_enable_warnings" in
+    none|no)     gtkmm_warning_flags='';;
+    minimum|yes) gtkmm_warning_flags='-Wall -Wno-unused-parameter';;
+    maximum)     gtkmm_warning_flags='-W -Wall -Wno-unused-parameter';;
+    hardcore)    gtkmm_warning_flags='-W -Wall -Werror -Wno-unused-parameter';;
+  esac
+
+  gtkmm_use_flags=''
+
+  if test "x$gtkmm_warning_flags" != "x"
+  then
+    echo 'int foo() { return 0; }' > conftest.cc
+
+    for flag in $gtkmm_warning_flags
+    do
+      # Test whether the compiler accepts the flag.  GCC doesn't bail
+      # out when given an unsupported flag but prints a warning, so
+      # check the compiler output instead.
+      gtkmm_cxx_out="`$CXX $flag -c conftest.cc 2>&1`"
+      rm -f conftest.$OBJEXT
+      test "x${gtkmm_cxx_out}" = "x" && \
+        gtkmm_use_flags="${gtkmm_use_flags:+$gtkmm_use_flags }$flag"
+    done
+
+    rm -f conftest.cc
+    gtkmm_cxx_out=''
+  fi
+
+  if test "x$gtkmm_use_flags" != "x"
+  then
+    for flag in $gtkmm_use_flags
+    do
+      case " $CXXFLAGS " in
+        *" $flag "*) ;; # don't add flags twice
+        *)           CXXFLAGS="${CXXFLAGS:+$CXXFLAGS }$flag";;
+      esac
+    done
+  else
+    gtkmm_use_flags='none'
+  fi
+
+  AC_MSG_RESULT([$gtkmm_use_flags])
+])
+
+
+
+
+AC_DEFUN([AC_ARG_DEBUG],
+[
+       AC_MSG_CHECKING([for debug flags])
+
+       AC_ARG_ENABLE(debug,[  --enable-debug           Build in debugging mode],[
+               debug=$enableval
+       ],[
+               debug="no"
+       ])
+       debug_flags=''
+
+       case "$debug" in
+               yes)
+                       debug_flags="-D_DEBUG -g"
+               ;;
+               half)
+                       debug_flags="-DNDEBUG -g"
+               ;;
+               no|*)
+                       debug_flags="-DNDEBUG -Wno-deprecated"
+               ;;
+       esac
+
+
+       CXXFLAGS="`echo $CXXFLAGS | sed s:-g::` $debug_flags"
+       CFLAGS="`echo $CFLAGS | sed s:-g::` $debug_flags"
+
+       AC_MSG_RESULT([$debug_flags])
+])
+
+
+
+
+AC_DEFUN([AC_ARG_OPTIMIZATION],
+[
+       AC_MSG_CHECKING([for optimization flags])
+
+       AC_ARG_ENABLE(optimization,[  --enable-optimization=[[0,1,2,3,4]] Select optimization level (default=2)],[
+               optimization=$enableval
+       ],[
+               optimization="2"
+       ])
+       optimization_flags=''
+       case "$optimization" in
+               0|no)   optimization_flags="-O0";;
+               1)              optimization_flags="-O1 -ffast-math";;
+               2|yes)  optimization_flags="-O2 -ffast-math";;
+               pass1)  optimization_flags="-O2 -ffast-math -fprofile-arcs";;
+               pass2)  optimization_flags="-O2 -ffast-math -fbranch-probabilities";;
+               3)              optimization_flags="-O3 -ffast-math";;
+               *)              optimization_flags="-O4 -ffast-math";;
+       esac
+       CXXFLAGS="`echo $CXXFLAGS | sed 's:-O.::g'` $optimization_flags"
+       CFLAGS="`echo $CFLAGS | sed 's:-O.::g'` $optimization_flags"
+       AC_MSG_RESULT([$optimization_flags])    
+])
+
+AC_DEFUN([AC_ARG_PROFILE_ARCS],
+[
+       AC_MSG_CHECKING([for arc profiling])
+
+       AC_ARG_ENABLE(profile-arcs,[  --enable-profile-arcs      Enable arc profiling],[
+               profile_arcs=$enableval
+       ],[
+               profile_arcs=no
+       ])
+       
+       if test $profile_arcs = "yes" ; then {
+               CXXFLAGS="$CXXFLAGS -fprofile-arcs";
+               CFLAGS="$CFLAGS -fprofile-arcs";
+       } ; fi
+               
+       AC_MSG_RESULT([$profile_arcs])  
+])
+
+AC_DEFUN([AC_ARG_BRANCH_PROBABILITIES],
+[
+       AC_MSG_CHECKING([for branch-probabilities])
+
+       AC_ARG_ENABLE(branch-probabilities,[  --enable-branch-probabilities      Enable branch-probabilities],[
+               branch_probabilities=$enableval
+       ],[
+               branch_probabilities=no
+       ])
+       
+       if test $branch_probabilities = "yes" ; then {
+               CXXFLAGS="$CXXFLAGS -fbranch-probabilities";
+               CFLAGS="$CFLAGS -fbranch-probabilities";
+       } ; fi
+               
+       AC_MSG_RESULT([$branch_probabilities])  
+])
+
+AC_DEFUN([AC_ARG_PROFILING],
+[
+       AC_MSG_CHECKING([for profiling])
+
+       AC_ARG_ENABLE(profiling,[  --enable-profiling      Enable profiling using gprof],[
+               profiling=$enableval
+       ],[
+               profiling=no
+       ])
+       
+       if test $profiling = "yes" ; then {
+               CFLAGS="$CFLAGS -pg";
+               CXXFLAGS="$CXXFLAGS -pg";
+               LDFLAGS="$LDFLAGS -pg";
+               LIBS="$LIBS";
+       } ; fi
+               
+       AC_MSG_RESULT([$profiling])     
+])
+
+AC_DEFUN([AC_ARG_TIMELIMIT],
+[
+       AC_ARG_ENABLE(timelimit,[  --enable-timelimit=[[days]] Set number of usable days(default=forever)],[
+               death_time=$((`date +%s`+$enableval*60*60*24))
+               AC_DEFINE_UNQUOTED(DEATH_TIME,$death_time, [ Describes the time at which the library will stop working ] )
+       ],
+       [
+               death_time="no"
+       ])
+])
+
+AC_DEFUN([AC_ARG_LICENSE_KEY],
+[
+       AC_ARG_ENABLE(license_key,[  --enable-license-key    Turn on license key requirement],[
+               AC_DEFINE(LICENSE_KEY_REQUIRED,, [ Enables license key checks ] )
+       ],
+       [
+               license_key="no"
+       ])
+])
+
+AC_DEFUN([AC_ARG_TIMELIMIT],
+[
+       AC_ARG_ENABLE(timelimit,[  --enable-timelimit=[[days]] Set number of usable days(default=forever)],[
+               death_time=$((`date +%s`+$enableval*60*60*24))
+               AC_DEFINE_UNQUOTED(DEATH_TIME,$death_time, [ Describes the time at which the library will stop working ] )
+       ],
+       [
+               death_time="no"
+       ])
+])
+
+MINGW_FLAGS="-mno-cygwin"
+
+
+AC_DEFUN([AC_WIN32_QUIRKS],
+[
+
+case "$host" in
+  *mingw*)
+    AC_MSG_CHECKING([the flavor of the compiler])
+    if ( $CC --version | grep -q mingw ) ; then {
+        AC_MSG_RESULT([compiler is mingw special])
+        LIBTOOL_PATCH_SED="
+            s/dir=\"\$absdir\"/dir=\`cygpath -d -m \"\$absdir\"\`/;
+            s/absdir=\`cd \"\$dir\" && pwd\`/absdir=\`cygpath -d -m \"\$dir\"\`/;
+            s/# We need an absolute path/dir=\`cygpath -d -m \"\$dir\"\` # We need an absolute path/;
+            s- /usr/lib- C:/mingw/lib-g;
+            s-\"/lib -\"C:/mingw/lib -g;
+            s- /lib/ - -g;
+        ";
+        sys_lib_dlsearch_path_spec="C:/mingw/lib"
+        ac_default_prefix=`cygpath -d -m "$ac_default_prefix"`;
+    } else {
+    AC_MSG_RESULT([compiler is cygwin stock, adding -mno-cygwin])
+    CPP="$CPP $MINGW_FLAGS"
+    CC="$CC $MINGW_FLAGS"
+    CXX="$CXX $MINGW_FLAGS -L/usr/$host/lib -I/usr/include/c++/3.3.3/$host"
+    CXXCPP="$CXXCPP $MINGW_FLAGS"
+
+
+} ; fi
+
+    LTCC="gcc"
+    CXXFLAGS="$CXXFLAGS -LC:/GTK/lib"
+    CFLAGS="$CFLAGS -LC:/GTK/lib"
+    LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--subsystem=console -Wl,--enable-runtime-pseudo-reloc" 
+dnl    LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--subsystem=console -Wl,--enable-runtime-pseudo-reloc"
+    ;;
+  *cygwin*)
+    LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols"
+dnl    LDFLAGS="$LDFLAGS -lole32 -no-undefined -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--subsystem=console"
+    CXXFLAGS="$CXXFLAGS -I/target/include"
+    CFLAGS="$CFLAGS -I/target/include"
+    ;;
+  powerpc-apple*)
+    echo Adding mac-specific optimization flags. . .
+    CXXFLAGS="$CXXFLAGS $G5OPTFLAGS"
+    ;;
+esac
+
+
+])
+
+AC_DEFUN([AC_LIBTOOL_PATCH],
+[
+
+if [[ "$LIBTOOL_PATCH_SED""x" != "x" ]] ; then {
+    printf "Patching libtool... "
+    cat libtool | sed "$LIBTOOL_PATCH_SED" > libtool2
+    rm libtool
+    mv libtool2 libtool
+    chmod +x libtool
+    AC_MSG_RESULT([patched])
+} fi ;
+
+
+])
diff --git a/synfig-studio/trunk/debugcrash b/synfig-studio/trunk/debugcrash
new file mode 100755 (executable)
index 0000000..b305d37
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+gdb -nw --core=~/core src/gtkmm/.libs/lt-sinfgstudio
diff --git a/synfig-studio/trunk/fixer b/synfig-studio/trunk/fixer
new file mode 100755 (executable)
index 0000000..4bb7098
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+TEMPFILENAME=~/deleteme.tmp
+
+for filename in `find . -name '*.[ch]*'` ; do {
+       sed '
+s/SigC::Signal./sigc::signal/g;
+
+' < $filename > $TEMPFILENAME && ( diff -q $TEMPFILENAME $filename || cp $TEMPFILENAME $filename )
+} ; done
diff --git a/synfig-studio/trunk/images/Makefile.am b/synfig-studio/trunk/images/Makefile.am
new file mode 100644 (file)
index 0000000..523a6e4
--- /dev/null
@@ -0,0 +1,75 @@
+
+SINFG=sinfg
+EXT=@imageext@
+
+EXTRA_DIST=studio_about.sif
+IMAGES=mirror_icon.$(EXT) time_track_icon.$(EXT) pastecanvas_icon.$(EXT) group_icon.$(EXT) clear_redo_icon.$(EXT) clear_undo_icon.$(EXT) navigator_icon.$(EXT) info_icon.$(EXT) zoom_icon.$(EXT) meta_data_icon.$(EXT) children_icon.$(EXT) keyframe_icon.$(EXT) swap_colors_icon.$(EXT) rotate_icon.$(EXT) scale_icon.$(EXT) smooth_move_icon.$(EXT) width_icon.$(EXT) rectangle_icon.$(EXT) circle_icon.$(EXT) draw_icon.$(EXT) sketch_icon.$(EXT) fill_icon.$(EXT) normal_icon.$(EXT) sif_icon.$(EXT) sinfg_icon.$(EXT) saveall_icon.$(EXT) bool_icon.$(EXT) integer_icon.$(EXT) angle_icon.$(EXT) segment_icon.$(EXT) blinepoint_icon.$(EXT) list_icon.$(EXT) canvas_pointer_icon.$(EXT) string_icon.$(EXT) eyedrop_icon.$(EXT) about_icon.$(EXT) about_dialog.$(EXT) canvas_icon.$(EXT) vector_icon.$(EXT) real_icon.$(EXT) color_icon.$(EXT) valuenode_icon.$(EXT) polygon_icon.$(EXT) bline_icon.$(EXT) layer_icon.$(EXT) duplicate_icon.$(EXT) gradient_icon.$(EXT) keyframe_lock_all.$(EXT) keyframe_lock_past.$(EXT) keyframe_lock_future.$(EXT) keyframe_lock_none.$(EXT)
+
+CLEANFILES=$(IMAGES)
+
+imagedir=@imagedir@
+
+image_DATA=$(IMAGES)
+
+
+all: $(IMAGES)
+
+SUFFIXES=.sif .tif .png
+
+#.SUFFIXES: $(SUFFIXES)
+
+PNGTOICO=pngtoico
+CONVERT=convert
+
+sif_icon.ico:
+       $(SINFG) sif_icon.sif -w 16 -h 16 -o sif_icon_16.gif sif_icon.sif -w 32 -h 32 -o sif_icon_32.gif sif_icon.sif -w 64 -h 64 -o sif_icon_64.gif
+       $(CONVERT) sif_icon_16.gif sif_icon_16.png
+       $(CONVERT) sif_icon_32.gif sif_icon_32.png
+       $(CONVERT) sif_icon_64.gif sif_icon_64.png
+       $(PNGTOICO) sif_icon_64.png > sif_icon.ico
+#      $(PNGTOICO) sif_icon_16.png sif_icon_32.png sif_icon_64.png > sif_icon.ico
+
+clean:
+       $(RM) $(CLEANFILES)
+
+.sif.bmp:
+       $(SINFG) -q $< -o $@ --time 0
+
+.sif.$(EXT):
+       $(SINFG) -q $< -o $@ --time 0
+
+keyframe_lock_all.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0
+
+keyframe_lock_past.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c PastOnly
+
+keyframe_lock_future.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c FutureOnly
+
+keyframe_lock_none.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c Disabled
+
+#.sif.png:
+#      $(SINFG) -q $< -o $@ --time 0
+       
+#datanode_icon.$(EXT): datanode_icon.sif
+#      $(SINFG) -q datanode_icon.sif -o datanode_icon.$(EXT) -w 128 -h 128 --time 0
+
+#color_icon.$(EXT): color_icon.sif
+#      $(SINFG) -q color_icon.sif -o color_icon.$(EXT) -w 128 -h 128 --time 0
+
+#real_icon.$(EXT): real_icon.sif
+#      $(SINFG) -q real_icon.sif -o real_icon.$(EXT) -w 128 -h 128 --time 0
+
+#vector_icon.$(EXT): vector_icon.sif
+#      $(SINFG) -q vector_icon.sif -o vector_icon.$(EXT) -w 128 -h 128 --time 0
+
+#about_dialog.$(EXT): about_dialog.sif
+#      $(SINFG) -q about_dialog.sif -o about_dialog.$(EXT) --time 0
+
+#about_icon.$(EXT): about_icon.sif
+#      $(SINFG) -q about_icon.sif -o about_icon.$(EXT) -w 128 -h 128 --time 0
+
+#canvas_icon.$(EXT): canvas_icon.sif
+#      $(SINFG) -q canvas_icon.sif -o canvas_icon.$(EXT) -w 128 -h 128 --time 0
diff --git a/synfig-studio/trunk/images/Makefile.inc b/synfig-studio/trunk/images/Makefile.inc
new file mode 100644 (file)
index 0000000..7bea629
--- /dev/null
@@ -0,0 +1,35 @@
+
+EXT=png
+SINFG=sinfg
+
+EXTRA_DIST=studio_about.sif
+IMAGES=fill_icon.$(EXT) normal_icon.$(EXT) sif_icon.$(EXT) sinfg_icon.$(EXT) saveall_icon.$(EXT) bool_icon.$(EXT) integer_icon.$(EXT) angle_icon.$(EXT) segment_icon.$(EXT) blinepoint_icon.$(EXT) list_icon.$(EXT) canvas_pointer_icon.$(EXT) string_icon.$(EXT) eyedrop_icon.$(EXT) about_icon.$(EXT) about_dialog.$(EXT) canvas_icon.$(EXT) vector_icon.$(EXT) real_icon.$(EXT) color_icon.$(EXT) valuenode_icon.$(EXT) polygon_icon.$(EXT) bline_icon.$(EXT) layer_icon.$(EXT) duplicate_icon.$(EXT) gradient_icon.$(EXT) keyframe_lock_all.$(EXT) keyframe_lock_past.$(EXT) keyframe_lock_future.$(EXT) keyframe_lock_none.$(EXT)
+
+CLEANFILES=$(IMAGES)
+
+
+all: $(IMAGES)
+
+.SUFFIXES:.sif .tif .png
+
+clean:
+       $(RM) $(CLEANFILES)
+
+.sif.tif:
+       $(SINFG) -q $< -o $@ --time 0
+
+.sif.png:
+       $(SINFG) -q $< -o $@ --time 0
+
+keyframe_lock_all.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0
+
+keyframe_lock_past.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c PastOnly
+
+keyframe_lock_future.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c FutureOnly
+
+keyframe_lock_none.$(EXT): keyframe_lock_icon.sif
+       $(SINFG) -q $< -o $@ --time 0 -c Disabled
+
diff --git a/synfig-studio/trunk/images/about_dialog.sif b/synfig-studio/trunk/images/about_dialog.sif
new file mode 100644 (file)
index 0000000..b6add27
--- /dev/null
@@ -0,0 +1,1704 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="300" height="350" xres="2952.755900" yres="2952.755900" view-box="-1.500000 2.500000 1.500000 -1.000000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>About Dialog Graphic</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_show" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <meta name="onion_skin" content="0"/>
+  <defs>
+    <canvas id="Sphere" height="300" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>Aqua Sphere</name>
+      <desc>This aqua-colored sphere reminds me of something from MacOS X.</desc>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.744518</g>
+            <b>0.825040</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.7500000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.587045</r>
+            <g>0.941024</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.5000000007"/>
+        </param>
+        <param name="feather">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.9999999985"/>
+        </param>
+        <param name="feather">
+          <real value="0.8000000030"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.2999999993"/>
+        </param>
+        <param name="feather">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.1500000060</x>
+            <y>-0.3499999940</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="blur" active="false" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="9"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.762890</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+    <canvas id="ShadowTitle" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="text" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="text">
+          <string guid="842559A41D447D775379B936F4A2CDC2">SINFG Studio</string>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="family">
+          <string>luxisr</string>
+        </param>
+        <param name="style">
+          <integer value="0"/>
+        </param>
+        <param name="weight">
+          <integer value="400"/>
+        </param>
+        <param name="compress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="vcompress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1899999976</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="orient">
+          <vector>
+            <x>1.0000000000</x>
+            <y>1.0000000000</y>
+          </vector>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="use_kerning">
+          <bool value="true"/>
+        </param>
+        <param name="grid_fit">
+          <bool value="false"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.0500000007</x>
+            <y>0.0500000007</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="text" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="text">
+          <string guid="842559A41D447D775379B936F4A2CDC2">SINFG Studio</string>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="family">
+          <string>luxisr</string>
+        </param>
+        <param name="style">
+          <integer value="0"/>
+        </param>
+        <param name="weight">
+          <integer value="400"/>
+        </param>
+        <param name="compress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="vcompress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1899999976</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="orient">
+          <vector>
+            <x>1.0000000000</x>
+            <y>1.0000000000</y>
+          </vector>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="use_kerning">
+          <bool value="true"/>
+        </param>
+        <param name="grid_fit">
+          <bool value="false"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="SolidColor" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="linear_gradient" active="true" version="0.0" desc="Rising Darkness">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="p1">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.2500000000</y>
+      </vector>
+    </param>
+    <param name="p2">
+      <vector>
+        <x>0.0000000000</x>
+        <y>2.7500000000</y>
+      </vector>
+    </param>
+    <param name="gradient">
+      <gradient>
+        <color pos="0.000000">
+          <r>0.000000</r>
+          <g>0.000000</g>
+          <b>0.000000</b>
+          <a>0.000000</a>
+        </color>
+        <color pos="1.000000">
+          <r>0.000000</r>
+          <g>0.000000</g>
+          <b>0.000000</b>
+          <a>1.000000</a>
+        </color>
+      </gradient>
+    </param>
+    <param name="loop">
+      <bool value="false"/>
+    </param>
+    <param name="zigzag">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Alpha Test">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="rectangle" active="true" version="0.2" desc="Rectangle003">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="point1">
+            <vector>
+              <x>-1.7500000000</x>
+              <y>2.5000000000</y>
+            </vector>
+          </param>
+          <param name="point2">
+            <vector>
+              <x>1.7500000000</x>
+              <y>2.2500703335</y>
+            </vector>
+          </param>
+          <param name="expand">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Gradient005">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-1.5000000000</x>
+              <y>2.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-1.2500000000</x>
+              <y>2.2500000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient_rotate type="gradient">
+              <gradient>
+                <gradient>
+                  <color pos="0.250000">
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>0.000000</a>
+                  </color>
+                  <color pos="0.250000">
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                  <color pos="0.750000">
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                  <color pos="0.750000">
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>0.000000</a>
+                  </color>
+                </gradient>
+              </gradient>
+              <offset>
+                <real value="-0.2500000000"/>
+              </offset>
+            </gradient_rotate>
+          </param>
+          <param name="loop">
+            <bool value="true"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>A       L       P       H       A</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Arial Black</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="400"/>
+          </param>
+          <param name="compress">
+            <real value="0.9750000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0937500000</x>
+              <y>0.0773138478</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>2.3665711880</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="spherize" active="true" version="0.2">
+          <param name="center">
+            <vector>
+              <x>-1.5000000000</x>
+              <y>2.3711292744</y>
+            </vector>
+          </param>
+          <param name="radius">
+            <real value="0.1211293260"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="clip">
+            <bool value="false"/>
+          </param>
+          <param name="type">
+            <integer value="2"/>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Gradient006">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="17"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>1.5000000000</x>
+              <y>2.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>1.5000000000</x>
+              <y>2.2500000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.194737">
+                <r>0.483334</r>
+                <g>0.483334</g>
+                <b>0.483334</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.278947">
+                <r>0.801383</r>
+                <g>0.801383</g>
+                <b>0.801384</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.378947">
+                <r>0.546153</r>
+                <g>0.546153</g>
+                <b>0.546153</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0416666679</x>
+              <y>-0.0416666679</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0416666679</x>
+              <y>0.0416666679</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0s"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Bright Light">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="4"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>1.2500000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="conical_gradient" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.038596">
+                <r>0.920368</r>
+                <g>0.920368</g>
+                <b>0.920368</b>
+                <a>0.000000</a>
+              </color>
+              <color pos="0.052632">
+                <r>0.934270</r>
+                <g>0.934270</g>
+                <b>0.934270</b>
+                <a>0.820503</a>
+              </color>
+              <color pos="0.094737">
+                <r>0.929226</r>
+                <g>0.929226</g>
+                <b>0.929226</b>
+                <a>0.404875</a>
+              </color>
+              <color pos="0.136842">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.425000</a>
+              </color>
+              <color pos="0.164912">
+                <r>0.876978</r>
+                <g>0.876978</g>
+                <b>0.876978</b>
+                <a>0.064816</a>
+              </color>
+              <color pos="0.231579">
+                <r>0.940432</r>
+                <g>0.940432</g>
+                <b>0.940432</b>
+                <a>0.353949</a>
+              </color>
+              <color pos="0.301754">
+                <r>0.976427</r>
+                <g>0.976427</g>
+                <b>0.976427</b>
+                <a>0.252097</a>
+              </color>
+              <color pos="0.364912">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.800000</a>
+              </color>
+              <color pos="0.389474">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+              <color pos="0.466667">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.655000</a>
+              </color>
+              <color pos="0.484211">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+              <color pos="0.526316">
+                <r>0.997147</r>
+                <g>0.997147</g>
+                <b>0.997147</b>
+                <a>0.752147</a>
+              </color>
+              <color pos="0.564912">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+              <color pos="0.645614">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.697727</a>
+              </color>
+              <color pos="0.719298">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.733333">
+                <r>0.958579</r>
+                <g>0.958579</g>
+                <b>0.958579</b>
+                <a>0.150345</a>
+              </color>
+              <color pos="0.817544">
+                <r>0.930914</r>
+                <g>0.930914</g>
+                <b>0.930914</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.852632">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+              <color pos="0.880702">
+                <r>0.992545</r>
+                <g>0.992545</g>
+                <b>0.992545</b>
+                <a>0.537339</a>
+              </color>
+              <color pos="0.915789">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+              <color pos="0.933333">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.964912">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.000000</a>
+              </color>
+              <color pos="0.978947">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.525000</a>
+              </color>
+              <color pos="1.000000">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>0.008584</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="center">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="angle">
+            <angle value="90.000000"/>
+          </param>
+          <param name="symmetric">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1" desc="Sunlight Hue">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="6"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.493478</r>
+              <g>1.439264</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+        </layer>
+        <layer type="blur" active="false" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0374999978</x>
+              <y>0.0374999978</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="0"/>
+          </param>
+        </layer>
+        <layer type="circle" active="true" version="0.1" desc="Attenuation">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="feather">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+          <param name="falloff">
+            <integer value="2"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0s"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Voria Logo w/ Shade">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Voria Logo">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>1.2500000000</y>
+            </vector>
+          </param>
+          <param name="canvas" use="../images/logo.sif#"/>
+          <param name="zoom">
+            <real value="-0.2999999925"/>
+          </param>
+          <param name="time_offset">
+            <time value="0s"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.013829</r>
+              <g>0.013829</g>
+              <b>0.013829</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.1041666642</x>
+              <y>0.1041666642</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0s"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="clamp" active="true" version="0.2" desc="Super-Saturation Clamp">
+    <param name="invert_negative">
+      <bool value="false"/>
+    </param>
+    <param name="clamp_ceiling">
+      <bool value="true"/>
+    </param>
+    <param name="ceiling">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="floor">
+      <real value="0.0000000000"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Software Title">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0099999998</x>
+        <y>0.1424999982</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Gradient058">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.6999999881"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-0.0990606323</x>
+              <y>0.4690153301</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-0.0990606323</x>
+              <y>-0.0307283755</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>0.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="text">
+            <string guid="5FDE2E2EC5F2E563F9AD4CCF6DFC9074">S T U D I O</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>0.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>times</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="400"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>1.0000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="warp" active="true" version="0.1">
+          <param name="src_tl">
+            <vector>
+              <x>-2.0734415054</x>
+              <y>0.6111532450</y>
+            </vector>
+          </param>
+          <param name="src_br">
+            <vector>
+              <x>2.1833333969</x>
+              <y>-0.0333333351</y>
+            </vector>
+          </param>
+          <param name="dest_tl">
+            <vector>
+              <x>-2.5265016556</x>
+              <y>-0.3445624709</y>
+            </vector>
+          </param>
+          <param name="dest_tr">
+            <vector>
+              <x>2.6473100185</x>
+              <y>-0.3445624709</y>
+            </vector>
+          </param>
+          <param name="dest_br">
+            <vector>
+              <x>2.1666667461</x>
+              <y>0.0170713197</y>
+            </vector>
+          </param>
+          <param name="dest_bl">
+            <vector>
+              <x>-2.0499999523</x>
+              <y>0.0170713197</y>
+            </vector>
+          </param>
+          <param name="clip">
+            <bool value="true"/>
+          </param>
+          <param name="horizon">
+            <real value="4.0000000000"/>
+          </param>
+        </layer>
+        <layer type="super_sample" active="true" version="0.1">
+          <param name="width">
+            <integer value="2"/>
+          </param>
+          <param name="height">
+            <integer value="2"/>
+          </param>
+          <param name="scanline">
+            <bool value="false"/>
+          </param>
+          <param name="alpha_aware">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="blur" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.1000000015</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+        </layer>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="text">
+            <string guid="5FDE2E2EC5F2E563F9AD4CCF6DFC9074">S T U D I O</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>times</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="400"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.4500000179</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>1.0000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rectangle" active="true" version="0.2" desc="Rectangle009">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>0.000000</a>
+            </color>
+          </param>
+          <param name="point1">
+            <vector>
+              <x>-2.5000000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </param>
+          <param name="point2">
+            <vector>
+              <x>2.5000000000</x>
+              <y>-0.5000000000</y>
+            </vector>
+          </param>
+          <param name="expand">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="text">
+            <string>S   Y   N   F   I   G</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>arialbd</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.3000000119</x>
+              <y>0.2166666687</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>1.0000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.5666666627</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.1000000015</x>
+              <y>0.1000000015</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="-0.6500000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0s"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Frame">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Gradient060">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>0.0000000000</x>
+              <y>-0.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>0.0000000000</x>
+              <y>2.5000000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>0.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rectangle" active="true" version="0.2" desc="Rectangle010">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>0.000000</a>
+            </color>
+          </param>
+          <param name="point1">
+            <vector>
+              <x>-1.5000000000</x>
+              <y>2.5000000000</y>
+            </vector>
+          </param>
+          <param name="point2">
+            <vector>
+              <x>1.5000000000</x>
+              <y>-1.0000000000</y>
+            </vector>
+          </param>
+          <param name="expand">
+            <real value="-0.0312499999"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0s"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/about_icon.sif b/synfig-studio/trunk/images/about_icon.sif
new file mode 100644 (file)
index 0000000..aff3ee3
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0500000007</y>
+      </vector>
+    </param>
+    <param name="canvas" use="./././logo.sif#"/>
+    <param name="zoom">
+      <real value="0.2750000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.2000000030</x>
+        <y>0.2000000030</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/angle_icon.sif b/synfig-studio/trunk/images/angle_icon.sif
new file mode 100644 (file)
index 0000000..d53afe1
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>DEG</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Arial</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>1.0000000000</x>
+        <y>1.2031250000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/bline_icon.sif b/synfig-studio/trunk/images/bline_icon.sif
new file mode 100644 (file)
index 0000000..824157f
--- /dev/null
@@ -0,0 +1,540 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled2</name>
+  <layer type="region" active="false" version="0.1" desc="Shadow">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6499999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.1000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="C74885137555A7A4ADC6C0AF52B8104D">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.9769230485</x>
+                <y>1.8730769157</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-2.2346153259</x>
+                <y>-0.9346153736</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.6000000238</x>
+                <y>-0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-1.3999999762</x>
+                <y>-3.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>4.0615386963</x>
+                <y>-0.0384615399</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="region" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.500000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="C74885137555A7A4ADC6C0AF52B8104D">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.9769230485</x>
+                <y>1.8730769157</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-2.2346153259</x>
+                <y>-0.9346153736</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.6000000238</x>
+                <y>-0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-1.3999999762</x>
+                <y>-3.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>4.0615386963</x>
+                <y>-0.0384615399</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Spotlight">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.5000000000"/>
+    </param>
+    <param name="feather">
+      <real value="1.5000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.6999999881</x>
+        <y>0.8000000119</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="outline" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="C74885137555A7A4ADC6C0AF52B8104D">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.9769230485</x>
+                <y>1.8730769157</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-2.2346153259</x>
+                <y>-0.9346153736</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-0.8999999762</x>
+                <y>-0.8999999762</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.6000000238</x>
+                <y>-0.8000000119</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-1.3999999762</x>
+                <y>-3.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>4.0615386963</x>
+                <y>-0.0384615399</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="10.3000000000"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="false"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="false"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/blinepoint_icon.sif b/synfig-studio/trunk/images/blinepoint_icon.sif
new file mode 100644 (file)
index 0000000..badbf3a
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>BLINE
+POINT</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Arial</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.6250000000</x>
+        <y>1.2500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/bool_icon.sif b/synfig-studio/trunk/images/bool_icon.sif
new file mode 100644 (file)
index 0000000..2f1a95e
--- /dev/null
@@ -0,0 +1,266 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>ON
+OFF</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.531049</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.6250000000</x>
+        <y>0.7500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rectangle" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="9"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>0.217638</g>
+        <b>-0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector>
+        <x>-1.2500000000</x>
+        <y>0.1250000000</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector>
+        <x>1.3750000000</x>
+        <y>1.3750000000</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="90.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.0500000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.0500000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rectangle" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>-0.000000</g>
+        <b>-0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector>
+        <x>-1.5000000000</x>
+        <y>-0.1250000000</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector>
+        <x>1.5000000000</x>
+        <y>0.1250000000</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rotate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="amount">
+      <angle value="45.000000"/>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="0.2400000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="translate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.1250000000</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="super_sample" active="false" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/canvas_icon.sif b/synfig-studio/trunk/images/canvas_icon.sif
new file mode 100644 (file)
index 0000000..34dcbfa
--- /dev/null
@@ -0,0 +1,332 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.200000 -1.200000 1.200000 1.200000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Sinfg Studio Canvas Icon</name>
+  <defs>
+    <canvas id="Sphere" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>Sphere</name>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.744518</g>
+            <b>0.825040</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.7500000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.587045</r>
+            <g>0.941024</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.5000000007"/>
+        </param>
+        <param name="feather">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.7500000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.1000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.6000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.2999999993"/>
+        </param>
+        <param name="feather">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.1500000060</x>
+            <y>-0.3499999940</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="blur" active="false" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="9"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.762890</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="SolidColor" active="false" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6499999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.9700000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.1750000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Sphere"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/canvas_pointer_icon.sif b/synfig-studio/trunk/images/canvas_pointer_icon.sif
new file mode 100644 (file)
index 0000000..99a4c06
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 -2.000000 2.000000 2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.985195</r>
+        <g>0.174900</g>
+        <b>-0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.6000000238</x>
+            <y>0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>-0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.6000000238</x>
+            <y>0.6000000238</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>1.3999999762</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>1.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.6000000238</x>
+            <y>1.0000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="-135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.1000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="2.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-0.0000000000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.3499999940</x>
+        <y>0.3499999940</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="canvas_icon.sif#"/>
+    <param name="zoom">
+      <real value="0.3000000045"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/children_icon.sif b/synfig-studio/trunk/images/children_icon.sif
new file mode 100644 (file)
index 0000000..c3bb476
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="0"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>CHILD</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.189396</g>
+        <b>0.155043</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Arial Black</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="400"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.7919595838</x>
+        <y>0.7919595838</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rotate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="amount">
+      <angle value="45.000000"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/circle_icon.sif b/synfig-studio/trunk/images/circle_icon.sif
new file mode 100644 (file)
index 0000000..61026d6
--- /dev/null
@@ -0,0 +1,445 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="false" version="0.1" desc="Circle014">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7900000215"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000042</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Circle013">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>-0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.7996272426"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="0"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Circle014">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.6493710692"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="0"/>
+    </param>
+  </layer>
+  <layer type="outline" active="true" version="0.2" desc="NewBLine003 Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="false">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.0000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.0000100000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>0.0000100000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector guid="74EA9676E36A79C9185E298C32101C7D">
+                <x>0.7500000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.0000100000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>0.0000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.1500000000"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="false"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="false"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Circle011">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.4230769277</x>
+        <y>0.4487179518</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.214520</r>
+        <g>0.214520</g>
+        <b>0.214520</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector" guid="3C063B97C9CE427155357B5FFAA3569B">
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.214520</r>
+        <g>0.214520</g>
+        <b>0.214520</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector guid="74EA9676E36A79C9185E298C32101C7D">
+        <x>0.7500000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector" guid="3C063B97C9CE427155357B5FFAA3569B">
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="translate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>-0.1093750000</x>
+        <y>0.0312500000</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/clear_redo_icon.sif b/synfig-studio/trunk/images/clear_redo_icon.sif
new file mode 100644 (file)
index 0000000..9f89262
--- /dev/null
@@ -0,0 +1,1834 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="1"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="region" active="true" version="0.1" desc="Arrow Region">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.213899</r>
+        <g>0.706536</g>
+        <b>0.150728</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="C9164709873BD5CB51D49173D73A74A7">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000656"/>
+                </c0>
+                <c1>
+                  <angle value="-179.999985"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-1.0000001192</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5129950643"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.3717083073"/>
+                </c0>
+                <c1>
+                  <angle value="-18.434948"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.1213203745"/>
+                </c0>
+                <c1>
+                  <angle value="135.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000298</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.4181875288"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.3923076923"/>
+                </c0>
+                <c1>
+                  <angle value="89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000437"/>
+                </c0>
+                <c1>
+                  <angle value="0.000005"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="outline" active="true" version="0.2" desc="Arrow Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="C9164709873BD5CB51D49173D73A74A7">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000656"/>
+                </c0>
+                <c1>
+                  <angle value="-179.999985"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-1.0000001192</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5129950643"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.3717083073"/>
+                </c0>
+                <c1>
+                  <angle value="-18.434948"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.1213203745"/>
+                </c0>
+                <c1>
+                  <angle value="135.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000298</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.4181875288"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.3923076923"/>
+                </c0>
+                <c1>
+                  <angle value="89.999992"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000437"/>
+                </c0>
+                <c1>
+                  <angle value="0.000005"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-89.999992"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2499999702</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.1562500012"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="true"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.3499999940"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Cross Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="9067578A5DE578DD1711891EB7D0C04E">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="bevel" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="135.000000"/>
+          </param>
+          <param name="depth">
+            <real value="0.2000000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.1000000000"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Cross Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="9067578A5DE578DD1711891EB7D0C04E">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0625000005"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/clear_undo_icon.sif b/synfig-studio/trunk/images/clear_undo_icon.sif
new file mode 100644 (file)
index 0000000..f5eaa34
--- /dev/null
@@ -0,0 +1,1834 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="region" active="true" version="0.1" desc="Arrow Region">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>0.250000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="D07021C1072962EE219CCB0F36311C9F">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-1.2500000000</x>
+                <y>0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5129950643"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.3717082451"/>
+                </c0>
+                <c1>
+                  <angle value="-161.565048"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.1213203436"/>
+                </c0>
+                <c1>
+                  <angle value="45.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.4181875288"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.3923076923"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="outline" active="true" version="0.2" desc="Arrow Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true" guid="D07021C1072962EE219CCB0F36311C9F">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-1.2500000000</x>
+                <y>0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5129950643"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.3717082451"/>
+                </c0>
+                <c1>
+                  <angle value="-161.565048"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.1213203436"/>
+                </c0>
+                <c1>
+                  <angle value="45.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.4181875288"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.3923076923"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.1562500012"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="true"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.3499999940"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Cross Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="D940CE40C974AFFE78BE2EB67735B2FA">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="bevel" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="135.000000"/>
+          </param>
+          <param name="depth">
+            <real value="0.2000000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.1000000000"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Cross Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="D940CE40C974AFFE78BE2EB67735B2FA">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="-135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.7500000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="90.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="45.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="1.0606601718"/>
+                      </c0>
+                      <c1>
+                        <angle value="135.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0625000005"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/color_icon.sif b/synfig-studio/trunk/images/color_icon.sif
new file mode 100644 (file)
index 0000000..d2093e4
--- /dev/null
@@ -0,0 +1,391 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755928" yres="2952.755928" view-box="-1.200000 1.200000 1.200000 -1.200000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Sinfg Studio Color Icon</name>
+  <defs>
+    <canvas id="ColorDisc" xres="2952.755900" yres="2952.755900" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>ColorDisc</name>
+      <defs>
+        <gradient id="Colors">
+          <color pos="0.000000">
+            <r>1.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="0.166667">
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="0.333333">
+            <r>0.000000</r>
+            <g>1.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="0.500000">
+            <r>0.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="0.666667">
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="0.833333">
+            <r>1.000000</r>
+            <g>0.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+          <color pos="1.000000">
+            <r>1.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </gradient>
+      </defs>
+      <layer type="conical_gradient" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="gradient" use="Colors"/>
+        <param name="center">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="angle">
+          <angle value="0.000000"/>
+        </param>
+        <param name="symmetric">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="0"/>
+        </param>
+      </layer>
+      <layer type="circle" active="false" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0625000000</x>
+            <y>0.1093750000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="3"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="false" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.333252</r>
+            <g>0.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="false" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000015"/>
+        </param>
+        <param name="feather">
+          <real value="0.3500000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.1093750000</x>
+            <y>-0.1406250000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="3"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="SolidColor" active="false" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="circle" active="false" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6999999881"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.9499999992"/>
+    </param>
+    <param name="feather">
+      <real value="0.1750000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.1151999980</x>
+        <y>0.1151999980</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="ColorDisc"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.3000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8000000119"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/draw_icon.sif b/synfig-studio/trunk/images/draw_icon.sif
new file mode 100644 (file)
index 0000000..4fe8054
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.630956</r>
+        <g>0.260201</g>
+        <b>0.059618</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8999999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>DRAW</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Sans Serif</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.7954951525</x>
+              <y>0.7954950929</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="45.000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="true" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/duplicate_icon.sif b/synfig-studio/trunk/images/duplicate_icon.sif
new file mode 100644 (file)
index 0000000..06507b5
--- /dev/null
@@ -0,0 +1,366 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled1</name>
+  <defs>
+    <canvas id="Item" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.1000000015</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.4000000060</x>
+                <y>0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.4000000060</x>
+                <y>-0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.4000000060</x>
+                <y>-0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.4000000060</x>
+                <y>0.4000000060</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1000000015</x>
+            <y>0.1000000015</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.4000000060</x>
+                <y>0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.4000000060</x>
+                <y>-0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.4000000060</x>
+                <y>-0.4000000060</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.4000000060</x>
+                <y>0.4000000060</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.900000</g>
+            <b>0.600000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.3000000119</x>
+                <y>0.3000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.3000000119</x>
+                <y>-0.3000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.3000000119</x>
+                <y>-0.3000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.3000000119</x>
+                <y>0.3000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.4000000060</x>
+        <y>-0.4000000060</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Item"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>-0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Item"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.8000000119</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.6000000238</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.6000000238</x>
+            <y>-0.4000000060</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.4000000060</x>
+            <y>-0.4000000060</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.4000000060</x>
+            <y>-0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.1000000015</x>
+            <y>-0.5000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.4000000060</x>
+            <y>-0.8000000119</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.4000000060</x>
+            <y>-0.6000000238</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.8000000119</x>
+            <y>-0.6000000238</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/eyedrop_icon.sif b/synfig-studio/trunk/images/eyedrop_icon.sif
new file mode 100644 (file)
index 0000000..d0fff4c
--- /dev/null
@@ -0,0 +1,1386 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled1</name>
+  <layer type="rectangle" active="false" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>0.152747</g>
+        <b>0.941503</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector>
+        <x>-1.6000000238</x>
+        <y>-1.6000000238</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector>
+        <x>1.6000000238</x>
+        <y>1.6000000238</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Colorful Eyedrop">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>-0.1000000015</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.241820</r>
+              <g>0.376990</g>
+              <b>0.966331</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="558EC4172AAD982234345DD6759F67C1">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.2500000000</x>
+                      <y>-0.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.5000000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.2500000000</x>
+                      <y>-0.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Colors">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-1.5000000000</x>
+              <y>-1.5000000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>1.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.147368">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>-0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.326316">
+                <r>-0.000000</r>
+                <g>1.000000</g>
+                <b>-0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.484211">
+                <r>-0.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.652632">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.814035">
+                <r>1.000000</r>
+                <g>-0.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>1.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Shadows">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="6"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-0.8615384698</x>
+              <y>0.1025641039</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-0.1128205135</x>
+              <y>-0.6666666865</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>-0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.203509">
+                <r>0.117420</r>
+                <g>0.117420</g>
+                <b>0.117420</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.392982">
+                <r>0.252708</r>
+                <g>0.252708</g>
+                <b>0.252708</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.600000">
+                <r>0.433233</r>
+                <g>0.433233</g>
+                <b>0.433233</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.771930">
+                <r>0.628843</r>
+                <g>0.628843</g>
+                <b>0.628843</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.971930">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Highlights">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.5799999833"/>
+          </param>
+          <param name="blend_method">
+            <integer value="4"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-0.8615384698</x>
+              <y>0.1025641039</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-0.1128205135</x>
+              <y>-0.6666666865</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.656140">
+                <r>-0.000000</r>
+                <g>-0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.894737">
+                <r>0.388889</r>
+                <g>0.388889</g>
+                <b>0.388889</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.971930">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Eyedropper Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>-0.000000</r>
+              <g>-0.000000</g>
+              <b>-0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="558EC4172AAD982234345DD6759F67C1">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.7500000000</x>
+                      <y>-1.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.2500000000</x>
+                      <y>-0.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.5000000000</x>
+                      <y>-1.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.2500000000</x>
+                      <y>-0.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.0000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0500000000" guid="45E003D5BD28330B94A4594A552239D4"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="false"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Rubber">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.015396</r>
+                    <g>0.015396</g>
+                    <b>0.015396</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="CE9E71F1AB906B7BF10900AA247E5A6D">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.7500000000</x>
+                            <y>1.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.5000000000</x>
+                            <y>-1.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>1.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>1.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="bevel" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="type">
+                  <integer value="1"/>
+                </param>
+                <param name="color1">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>0.622449</a>
+                  </color>
+                </param>
+                <param name="color2">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="angle">
+                  <angle value="135.000000"/>
+                </param>
+                <param name="depth">
+                  <real value="0.2000000000"/>
+                </param>
+                <param name="softness">
+                  <real value="0.4000000000"/>
+                </param>
+                <param name="use_luma">
+                  <bool value="false"/>
+                </param>
+                <param name="solid">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="CE9E71F1AB906B7BF10900AA247E5A6D">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.7500000000</x>
+                            <y>1.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.5000000000</x>
+                            <y>-1.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>1.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>1.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="0.1000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="false" version="0.1">
+    <param name="width">
+      <integer value="3"/>
+    </param>
+    <param name="height">
+      <integer value="3"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1500000060</x>
+        <y>0.1500000060</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/fill_icon.sif b/synfig-studio/trunk/images/fill_icon.sif
new file mode 100644 (file)
index 0000000..fe415c3
--- /dev/null
@@ -0,0 +1,3130 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="region" active="true" version="0.1" desc="Shadow Region">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.4600000083"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="true">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.7500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.7500000000</x>
+                <y>-0.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>0.7538461685</x>
+                <y>1.1230769157</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.7384615541</x>
+                <y>1.1230769157</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>0.7500000000</x>
+                <y>0.7500000000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.7500000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-0.7384615541</x>
+                <y>-1.1230769157</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0099999998"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="true"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>-0.7538461685</x>
+                <y>-1.1076923609</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>-0.7500000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="blur" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1500000060</x>
+        <y>0.1500000060</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Inner Bucket Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.4939709008</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Inner Bucket Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>0.7500000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient guid="8E526C5A6EBFA624A3553497AFBB1996">
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.621053">
+                <r>0.921951</r>
+                <g>0.921951</g>
+                <b>0.921951</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.719298">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.782456">
+                <r>0.864472</r>
+                <g>0.864472</g>
+                <b>0.864472</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.165981</r>
+                <g>0.165981</g>
+                <b>0.165981</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Inner Bucket Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.4939709008</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Bucket Contents">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0442307703</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Paint in Bucket">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>-0.000000</r>
+              <g>0.295220</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>-0.1250000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.4939709008</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Paint Colors">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.6399999857"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="spiral_gradient" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>1.000000</r>
+                      <g>-0.000000</g>
+                      <b>-0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="0.157895">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>-0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="0.333333">
+                      <r>-0.000000</r>
+                      <g>1.000000</g>
+                      <b>-0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="0.491228">
+                      <r>-0.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="0.666700">
+                      <r>-0.000000</r>
+                      <g>-0.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="0.842105">
+                      <r>1.000000</r>
+                      <g>-0.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>-0.000000</g>
+                      <b>-0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="center">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.3750000000</y>
+                  </vector>
+                </param>
+                <param name="radius">
+                  <real value="1.1250000000"/>
+                </param>
+                <param name="angle">
+                  <angle value="0.000000"/>
+                </param>
+                <param name="clockwise">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="stretch" active="true" version="0.1">
+                <param name="amount">
+                  <vector>
+                    <x>1.0000000000</x>
+                    <y>0.4499999881</y>
+                  </vector>
+                </param>
+                <param name="center">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.3750000000</y>
+                  </vector>
+                </param>
+              </layer>
+              <layer type="blur" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="size">
+                  <vector>
+                    <x>0.1000000015</x>
+                    <y>0.1000000015</y>
+                  </vector>
+                </param>
+                <param name="type">
+                  <integer value="1"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Paint Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.8199999928"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="outline" active="true" version="0.2" desc="Light Shading">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>-0.0000000000</x>
+                    <y>-0.1442307681</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.4939709008</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7680873275</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7680873275</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>-0.7488565445</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>-0.7488565445</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>0.7511434555</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>0.7511434555</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="Dark shading">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0320512839</x>
+                    <y>-0.1955128163</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.4939709008</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7680873275</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7680873275</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>-0.7488565445</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>-0.7488565445</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>0.7511434555</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0192307699</x>
+                            <y>0.7511434555</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="blur" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="size">
+                  <vector>
+                    <x>0.0399999991</x>
+                    <y>0.0399999991</y>
+                  </vector>
+                </param>
+                <param name="type">
+                  <integer value="1"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Paint Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>-0.1250000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="C5E57087E098684198F698E4C3314E28">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.4939709008</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7680873275</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>-0.7488565445</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.5000000000</x>
+                      <y>-0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.0192307699</x>
+                      <y>0.7511434555</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Outer Bucket">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Outer Bucket Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="6B9D4638C3D948BC14C9D9904A4A1BBA">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>0.7500000000</x>
+              <y>-0.2500000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>-0.2500000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient guid="8E526C5A6EBFA624A3553497AFBB1996">
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.621053">
+                <r>0.921951</r>
+                <g>0.921951</g>
+                <b>0.921951</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.719298">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.782456">
+                <r>0.864472</r>
+                <g>0.864472</g>
+                <b>0.864472</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.165981</r>
+                <g>0.165981</g>
+                <b>0.165981</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="linear_gradient" active="true" version="0.0">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="0.3499999940"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="p1">
+                  <vector>
+                    <x>1.0000000000</x>
+                    <y>1.0000000000</y>
+                  </vector>
+                </param>
+                <param name="p2">
+                  <vector>
+                    <x>-1.0000000000</x>
+                    <y>-1.0000000000</y>
+                  </vector>
+                </param>
+                <param name="gradient">
+                  <stripes type="gradient">
+                    <color1>
+                      <color>
+                        <r>0.000000</r>
+                        <g>0.000000</g>
+                        <b>0.000000</b>
+                        <a>0.000000</a>
+                      </color>
+                    </color1>
+                    <color2>
+                      <color>
+                        <r>0.000000</r>
+                        <g>0.000000</g>
+                        <b>0.000000</b>
+                        <a>1.000000</a>
+                      </color>
+                    </color2>
+                    <stripes>
+                      <integer value="10"/>
+                    </stripes>
+                  </stripes>
+                </param>
+                <param name="loop">
+                  <bool value="false"/>
+                </param>
+                <param name="zigzag">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="spherize" active="true" version="0.1">
+                <param name="center">
+                  <vector>
+                    <x>-0.0019615984</x>
+                    <y>-0.4694150686</y>
+                  </vector>
+                </param>
+                <param name="radius">
+                  <real value="0.7467968221"/>
+                </param>
+                <param name="percent">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="type">
+                  <integer value="2"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Outer Bucket Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="6B9D4638C3D948BC14C9D9904A4A1BBA">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.7500000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Collar">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="Bucket Collar Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="3767DAB229C8C6CE046DF18D9373F8A9">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1F6CA929AE42D6CB2C8B947B9DD93F14">
+                      <x>-0.8000000119</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.1000000015</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                      <link>
+                        <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                          <x>0.0000000000</x>
+                          <y>0.9499999881</y>
+                        </vector>
+                      </link>
+                      <scalar>
+                        <real value="-1.0000000000"/>
+                      </scalar>
+                    </scale>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="3D7525E1394A0BF5B19036F269C51779">
+                      <x>0.8000000119</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                      <x>0.0000000000</x>
+                      <y>0.9499999881</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.1000000015</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.8000000119</x>
+                      <y>0.3750000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.1000000015</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                      <link>
+                        <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                          <x>0.0000000000</x>
+                          <y>0.9499999881</y>
+                        </vector>
+                      </link>
+                      <scalar>
+                        <real value="-1.0000000000"/>
+                      </scalar>
+                    </scale>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.8000000119</x>
+                      <y>0.3750000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                      <x>0.0000000000</x>
+                      <y>0.9499999881</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.1000000015</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector guid="3D7525E1394A0BF5B19036F269C51779">
+              <x>0.8000000119</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector guid="1F6CA929AE42D6CB2C8B947B9DD93F14">
+              <x>-0.8000000119</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient guid="8E526C5A6EBFA624A3553497AFBB1996">
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.621053">
+                <r>0.921951</r>
+                <g>0.921951</g>
+                <b>0.921951</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.719298">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.782456">
+                <r>0.864472</r>
+                <g>0.864472</g>
+                <b>0.864472</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.165981</r>
+                <g>0.165981</g>
+                <b>0.165981</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Bucket Collar Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="3767DAB229C8C6CE046DF18D9373F8A9">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1F6CA929AE42D6CB2C8B947B9DD93F14">
+                      <x>-0.8000000119</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.1000000015</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                      <link>
+                        <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                          <x>0.0000000000</x>
+                          <y>0.9499999881</y>
+                        </vector>
+                      </link>
+                      <scalar>
+                        <real value="-1.0000000000"/>
+                      </scalar>
+                    </scale>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="3D7525E1394A0BF5B19036F269C51779">
+                      <x>0.8000000119</x>
+                      <y>0.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                      <x>0.0000000000</x>
+                      <y>0.9499999881</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.1000000015</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.8000000119</x>
+                      <y>0.3750000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-0.1000000015</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                      <link>
+                        <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                          <x>0.0000000000</x>
+                          <y>0.9499999881</y>
+                        </vector>
+                      </link>
+                      <scalar>
+                        <real value="-1.0000000000"/>
+                      </scalar>
+                    </scale>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-0.8000000119</x>
+                      <y>0.3750000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0099999998"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                      <x>0.0000000000</x>
+                      <y>0.9499999881</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>0.1000000015</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Top">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1" desc="CollarTop Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="775E9F9CB5E5558FB34346B26A8DA8D6">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="1F6CA929AE42D6CB2C8B947B9DD93F14">
+                            <x>-0.8000000119</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                            <x>0.0000000000</x>
+                            <y>0.9499999881</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0615384616</x>
+                            <y>0.9076923132</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="3D7525E1394A0BF5B19036F269C51779">
+                            <x>0.8000000119</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                            <link>
+                              <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                                <x>0.0000000000</x>
+                                <y>0.9499999881</y>
+                              </vector>
+                            </link>
+                            <scalar>
+                              <real value="-1.0000000000"/>
+                            </scalar>
+                          </scale>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0205128212</x>
+                            <y>-0.8717948794</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="circle" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="radius">
+                  <real value="0.7500000000"/>
+                </param>
+                <param name="feather">
+                  <real value="0.6000000000"/>
+                </param>
+                <param name="pos">
+                  <vector>
+                    <x>-0.5000000000</x>
+                    <y>0.7500000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="true"/>
+                </param>
+                <param name="falloff">
+                  <integer value="1"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="CollarTop Outline">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="775E9F9CB5E5558FB34346B26A8DA8D6">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="1F6CA929AE42D6CB2C8B947B9DD93F14">
+                            <x>-0.8000000119</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                            <x>0.0000000000</x>
+                            <y>0.9499999881</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0615384616</x>
+                            <y>0.9076923132</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="3D7525E1394A0BF5B19036F269C51779">
+                            <x>0.8000000119</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <scale type="vector" guid="FA952C378995370A1966ECABF5971D47">
+                            <link>
+                              <vector guid="6A84A58F2F3C0C1E4DCE80A8013066DB">
+                                <x>0.0000000000</x>
+                                <y>0.9499999881</y>
+                              </vector>
+                            </link>
+                            <scalar>
+                              <real value="-1.0000000000"/>
+                            </scalar>
+                          </scale>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0205128212</x>
+                            <y>-0.8717948794</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="region" active="true" version="0.1" desc="CollarHole Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>0.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="28FCF4AC129BB1943F1E1536880A375D">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="CollarHole Outline">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="28FCF4AC129BB1943F1E1536880A375D">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0099999998"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>FILL</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.3546048403</x>
+        <y>0.3546048403</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-0.2500000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="translate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>-0.2412532866</x>
+        <y>0.2151449770</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="-0.0750000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/gradient_icon.sif b/synfig-studio/trunk/images/gradient_icon.sif
new file mode 100644 (file)
index 0000000..165409c
--- /dev/null
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.6999999881</x>
+            <y>0.6999999881</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.6999999881</x>
+            <y>-0.6999999881</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.6999999881</x>
+            <y>-0.6999999881</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.6999999881</x>
+            <y>0.6999999881</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="linear_gradient" active="true" version="0.0">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="p1">
+      <vector>
+        <x>0.6999999881</x>
+        <y>0.6999999881</y>
+      </vector>
+    </param>
+    <param name="p2">
+      <vector>
+        <x>-0.6999999881</x>
+        <y>-0.6999999881</y>
+      </vector>
+    </param>
+    <param name="gradient">
+      <gradient>
+        <color pos="0.000000">
+          <r>1.000000</r>
+          <g>-0.000000</g>
+          <b>-0.000000</b>
+          <a>1.000000</a>
+        </color>
+        <color pos="1.000000">
+          <r>-0.000000</r>
+          <g>-0.000000</g>
+          <b>1.000000</b>
+          <a>1.000000</a>
+        </color>
+      </gradient>
+    </param>
+    <param name="loop">
+      <bool value="false"/>
+    </param>
+    <param name="zigzag">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <list>
+        <vector>
+          <x>-0.8000000119</x>
+          <y>0.8000000119</y>
+        </vector>
+        <vector>
+          <x>-0.8000000119</x>
+          <y>-0.8000000119</y>
+        </vector>
+        <vector>
+          <x>0.8000000119</x>
+          <y>-0.8000000119</y>
+        </vector>
+        <vector>
+          <x>0.8000000119</x>
+          <y>0.8000000119</y>
+        </vector>
+      </list>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="0.1400000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/group_icon.sif b/synfig-studio/trunk/images/group_icon.sif
new file mode 100644 (file)
index 0000000..f84e075
--- /dev/null
@@ -0,0 +1,2065 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="1"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="0"/>
+  <meta name="guide_snap" content="0"/>
+  <meta name="onion_skin" content="0"/>
+  <defs>
+    <canvas id="Layer" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.1000000015</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.900000</g>
+            <b>0.600000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Back">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide01 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>1.000000</g>
+              <b>0.250000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="A562AB022428E182DE31F5816326C95D">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="FCF91E0786FF918D46630AF312DE635E">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="055CDEAE3EA375AAD84E3B6391E1BBFE">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="B7FDF7C39B98384E9B169D23C42AB57D">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DEBD8B41481A0903EBACB592B94E5D9A">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide01 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="A562AB022428E182DE31F5816326C95D">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="FCF91E0786FF918D46630AF312DE635E">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="055CDEAE3EA375AAD84E3B6391E1BBFE">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="B7FDF7C39B98384E9B169D23C42AB57D">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DEBD8B41481A0903EBACB592B94E5D9A">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Left">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide04 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>1.000000</g>
+              <b>0.250000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="021D9E8AB6EED15123AC58C3DA723836">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="FCF91E0786FF918D46630AF312DE635E">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="8E2C2204BA6BAAE9795B2E2CF879BD88">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1EED98B8E4D2B881132D3FFE1A5B7690">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DEBD8B41481A0903EBACB592B94E5D9A">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide04 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="021D9E8AB6EED15123AC58C3DA723836">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="FCF91E0786FF918D46630AF312DE635E">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="8E2C2204BA6BAAE9795B2E2CF879BD88">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1EED98B8E4D2B881132D3FFE1A5B7690">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DEBD8B41481A0903EBACB592B94E5D9A">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Shading" group="Shading">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8000000119"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.5000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.4882812491"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.3589743674</x>
+        <y>-0.1217948720</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Right">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide03 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>1.000000</g>
+              <b>0.250000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="268982196DB71162D54030DD1F8267FF">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="055CDEAE3EA375AAD84E3B6391E1BBFE">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="68C2FB859380EF7AA1E2FAAE0B60BF41">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DF9B0060A7C9F6A06A2B00B0A943DBCD">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="B7FDF7C39B98384E9B169D23C42AB57D">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide03 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="268982196DB71162D54030DD1F8267FF">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="055CDEAE3EA375AAD84E3B6391E1BBFE">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="68C2FB859380EF7AA1E2FAAE0B60BF41">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DF9B0060A7C9F6A06A2B00B0A943DBCD">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="B7FDF7C39B98384E9B169D23C42AB57D">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1" group="Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Front">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide02 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>1.000000</g>
+              <b>0.250000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="49B953A1D5262D3CBF3A681E5CD36787">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="8E2C2204BA6BAAE9795B2E2CF879BD88">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="68C2FB859380EF7AA1E2FAAE0B60BF41">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DF9B0060A7C9F6A06A2B00B0A943DBCD">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1EED98B8E4D2B881132D3FFE1A5B7690">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide02 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="49B953A1D5262D3CBF3A681E5CD36787">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="8E2C2204BA6BAAE9795B2E2CF879BD88">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="68C2FB859380EF7AA1E2FAAE0B60BF41">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="DF9B0060A7C9F6A06A2B00B0A943DBCD">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1EED98B8E4D2B881132D3FFE1A5B7690">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="circle" active="true" version="0.1" desc="Shading" group="Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.5500000119"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="feather">
+            <real value="0.4882812491"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.2500000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+          <param name="falloff">
+            <integer value="2"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/info_icon.sif b/synfig-studio/trunk/images/info_icon.sif
new file mode 100644 (file)
index 0000000..c736939
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="circle" active="true" version="0.1" desc="Circle067">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.265778</g>
+        <b>0.265778</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>i</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Times</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="400"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>2.2500000000</x>
+        <y>2.2500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/integer_icon.sif b/synfig-studio/trunk/images/integer_icon.sif
new file mode 100644 (file)
index 0000000..48fe158
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>123
+456</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="0.7000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>1.2656250000</x>
+        <y>1.2968750000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/keyframe_icon.sif b/synfig-studio/trunk/images/keyframe_icon.sif
new file mode 100644 (file)
index 0000000..5d657ca
--- /dev/null
@@ -0,0 +1,331 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon005">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-1.0000000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.7500000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.7500000000</x>
+            <y>-0.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.5000000000</x>
+            <y>-0.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.5000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.2500000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.0000000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.7500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.7500000000</x>
+            <y>-0.5000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.5000000000</x>
+            <y>-0.5000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.5000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>-0.5000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-1.0000000000</x>
+            <y>-0.5000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Circle060">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-1.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Circle061">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>0.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.5018364633"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-1.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="SolidColor" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.377273</r>
+        <g>0.210909</g>
+        <b>0.054545</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.0937500000"/>
+    </param>
+    <param name="softness">
+      <real value="0.0937500000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0937500000</x>
+        <y>-0.0937500000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1250000000</x>
+        <y>0.1250000000</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rotate" active="false" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="amount">
+      <angle value="45.000000"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/keyframe_lock_icon.sif b/synfig-studio/trunk/images/keyframe_lock_icon.sif
new file mode 100644 (file)
index 0000000..bd8f202
--- /dev/null
@@ -0,0 +1,2407 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Keyframe Lock Button</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <defs>
+    <canvas id="Disabled" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="PasteCanvas" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="canvas" use=":"/>
+        <param name="zoom">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="time_offset">
+          <time value="0f"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="8"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="false" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="13"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+    </canvas>
+    <canvas id="FutureOnly" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <meta name="grid_show" content="0"/>
+      <meta name="grid_size" content="0.250000 0.250000"/>
+      <meta name="grid_snap" content="0"/>
+      <meta name="guide_snap" content="0"/>
+      <defs>
+        <dynamic_list type="vector" id="FutureMask">
+          <entry>
+            <vector>
+              <x>0.7500000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>0.7500000000</x>
+              <y>-1.5000000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>2.0000000000</x>
+              <y>-1.5000000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>2.0000000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </entry>
+        </dynamic_list>
+      </defs>
+      <layer type="PasteCanvas" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="canvas" use=":"/>
+        <param name="zoom">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="time_offset">
+          <time value="0f"/>
+        </param>
+      </layer>
+      <layer type="rectangle" active="true" version="0.2" desc="Rectangle002">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="10"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="point1">
+          <vector>
+            <x>-2.0000000000</x>
+            <y>2.0000000000</y>
+          </vector>
+        </param>
+        <param name="point2">
+          <vector>
+            <x>0.0000000000</x>
+            <y>-2.0000000000</y>
+          </vector>
+        </param>
+        <param name="expand">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+    </canvas>
+    <canvas id="PastOnly" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <meta name="grid_show" content="1"/>
+      <meta name="grid_size" content="0.250000 0.250000"/>
+      <meta name="grid_snap" content="0"/>
+      <meta name="guide_snap" content="0"/>
+      <defs>
+        <dynamic_list type="vector" id="PastMask">
+          <entry>
+            <vector>
+              <x>-2.0000000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>-2.0000000000</x>
+              <y>-1.2500000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>-0.7500000000</x>
+              <y>-1.2500000000</y>
+            </vector>
+          </entry>
+          <entry>
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </entry>
+        </dynamic_list>
+      </defs>
+      <layer type="PasteCanvas" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="canvas" use=":"/>
+        <param name="zoom">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="time_offset">
+          <time value="0f"/>
+        </param>
+      </layer>
+      <layer type="rectangle" active="true" version="0.2" desc="Rectangle004">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="10"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="point1">
+          <vector>
+            <x>0.0000000000</x>
+            <y>2.0000000000</y>
+          </vector>
+        </param>
+        <param name="point2">
+          <vector>
+            <x>2.0000000000</x>
+            <y>-2.0000000000</y>
+          </vector>
+        </param>
+        <param name="expand">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Lock">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-0.5000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="rectangle" active="true" version="0.2" desc="LockBody">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.493452</r>
+              <g>0.491552</g>
+              <b>0.491552</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="point1">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </param>
+          <param name="point2">
+            <vector>
+              <x>0.7500000000</x>
+              <y>-0.7500000000</y>
+            </vector>
+          </param>
+          <param name="expand">
+            <real value="-0.0500000000"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="linear_gradient" active="true" version="0.0" desc="Gradient005">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="p1">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="p2">
+            <vector>
+              <x>0.7500000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.150000">
+                <r>0.505263</r>
+                <g>0.505263</g>
+                <b>0.505263</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="0.850000">
+                <r>0.485435</r>
+                <g>0.484084</g>
+                <b>0.485435</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="loop">
+            <bool value="false"/>
+          </param>
+          <param name="zigzag">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rectangle" active="true" version="0.2" desc="LockOutline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="point1">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </param>
+          <param name="point2">
+            <vector>
+              <x>0.7500000000</x>
+              <y>-0.7500000000</y>
+            </vector>
+          </param>
+          <param name="expand">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Keyhole">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0900000036</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="polygon" active="true" version="0.1" desc="Polygon">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="vector_list">
+                  <dynamic_list type="vector">
+                    <entry>
+                      <vector>
+                        <x>0.0000000000</x>
+                        <y>0.2500000000</y>
+                      </vector>
+                    </entry>
+                    <entry>
+                      <vector>
+                        <x>-0.2151769996</x>
+                        <y>-0.6455309987</y>
+                      </vector>
+                    </entry>
+                    <entry>
+                      <vector>
+                        <x>0.2151769996</x>
+                        <y>-0.6455309987</y>
+                      </vector>
+                    </entry>
+                  </dynamic_list>
+                </param>
+              </layer>
+              <layer type="circle" active="true" version="0.1" desc="Circle007">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="radius">
+                  <real value="0.2500000000"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="pos">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.2500000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="falloff">
+                  <integer value="2"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Bar">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1" desc="Region007 Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.280608</r>
+                    <g>0.280608</g>
+                    <b>0.280608</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="44AB3CC637BD7F0193CD0216DB2967FC">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.6250000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6250000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.3750000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.3750000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.1250000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="179.999985"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="180.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.3750000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.6250000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="bevel" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="type">
+                  <integer value="1"/>
+                </param>
+                <param name="color1">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="color2">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="angle">
+                  <angle value="135.000000"/>
+                </param>
+                <param name="depth">
+                  <real value="0.2000000000"/>
+                </param>
+                <param name="softness">
+                  <real value="0.1000000000"/>
+                </param>
+                <param name="use_luma">
+                  <bool value="false"/>
+                </param>
+                <param name="solid">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="Region007 Outline">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="44AB3CC637BD7F0193CD0216DB2967FC">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.6250000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6250000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.3750000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.3750000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.1250000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="179.999985"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="180.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.3750000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.6250000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="1.5000000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="0.0500000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.3500000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.2000000030</x>
+        <y>0.2000000030</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Arrows">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-0.5000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Past">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.2500000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="08CC95D6F9E6A0AC85DCD9C7AF2A5769">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0192307699</x>
+                            <y>-0.6346153617</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.352394</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="08CC95D6F9E6A0AC85DCD9C7AF2A5769">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0192307699</x>
+                            <y>-0.6346153617</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-1.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="1.3000000000" guid="655D2EFC28BD075FC89EB6466DA205B0"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.1500000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Future">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>-0.2500000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="E54AFF06AA4F157AF843B023E88FA27F">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.352394</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="E54AFF06AA4F157AF843B023E88FA27F">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0500000000" guid="B881CFF98EEADEDEED58D9264C5A72FF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.7500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>-0.7500000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="1.3000000000" guid="655D2EFC28BD075FC89EB6466DA205B0"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.1500000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="shade" active="false" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.1000000015</x>
+              <y>-0.1000000015</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.2000000030</x>
+              <y>0.2000000030</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="translate" active="false" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-0.2500000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/layer_icon.sif b/synfig-studio/trunk/images/layer_icon.sif
new file mode 100644 (file)
index 0000000..395e88c
--- /dev/null
@@ -0,0 +1,332 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <defs>
+    <canvas id="Layer" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.1000000015</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.900000</g>
+            <b>0.600000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.5000000000</x>
+        <y>-0.5000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Layer"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.2000000030</x>
+        <y>-0.2000000030</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Layer"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>-0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Layer"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.5000000000"/>
+    </param>
+    <param name="feather">
+      <real value="1.5000000075"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.6999999881</x>
+        <y>0.6999999881</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/list_icon.sif b/synfig-studio/trunk/images/list_icon.sif
new file mode 100644 (file)
index 0000000..07c99dc
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>LIST</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.9375000000</x>
+        <y>1.0781250000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/logo.sif b/synfig-studio/trunk/images/logo.sif
new file mode 100644 (file)
index 0000000..a83e78b
--- /dev/null
@@ -0,0 +1,3062 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="512" height="512" xres="5905.511856" yres="5905.511856" view-box="-1.499986 1.499986 1.499986 -1.499986" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Voria Logo</name>
+  <defs>
+    <canvas id="WhiteBG" width="644" height="644" xres="5750.000000" yres="5750.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>WhiteBG</name>
+      <layer type="PasteCanvas" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0273553673</y>
+          </vector>
+        </param>
+        <param name="canvas" use=":"/>
+        <param name="zoom">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="time_offset">
+          <time value="0f"/>
+        </param>
+        <param name="children_lock">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="shade" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.8999999762"/>
+        </param>
+        <param name="blend_method">
+          <integer value="12"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0495141000</x>
+            <y>-0.0378637239</y>
+          </vector>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1417397559</x>
+            <y>0.1417397559</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="12"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+    </canvas>
+    <canvas id="TextLogo" width="764" height="1208" xres="11811.023712" yres="11811.023712" view-box="-1.200000 1.500000 1.200000 -2.300000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <defs>
+        <real value="0.5850000000" id="Crutch"/>
+      </defs>
+      <layer type="text" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="text">
+          <string>STUDIOS</string>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="family">
+          <string>SFAutomaton</string>
+        </param>
+        <param name="style">
+          <integer value="0"/>
+        </param>
+        <param name="weight">
+          <integer value="400"/>
+        </param>
+        <param name="compress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="vcompress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="size">
+          <scale type="vector" scalar="Crutch">
+            <link>
+              <vector>
+                <x>0.5153846145</x>
+                <y>0.3852432668</y>
+              </vector>
+            </link>
+          </scale>
+        </param>
+        <param name="orient">
+          <vector>
+            <x>0.5000000000</x>
+            <y>0.5000000000</y>
+          </vector>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.0149999997</x>
+            <y>-2.0204918385</y>
+          </vector>
+        </param>
+        <param name="use_kerning">
+          <bool value="true"/>
+        </param>
+        <param name="grid_fit">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="text" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="text">
+          <string>VORIA</string>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="family">
+          <string>SFAutomaton</string>
+        </param>
+        <param name="style">
+          <integer value="0"/>
+        </param>
+        <param name="weight">
+          <integer value="400"/>
+        </param>
+        <param name="compress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="vcompress">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="size">
+          <scale type="vector" scalar="Crutch">
+            <link>
+              <vector>
+                <x>0.7500000000</x>
+                <y>0.6250000000</y>
+              </vector>
+            </link>
+          </scale>
+        </param>
+        <param name="orient">
+          <vector>
+            <x>0.5000000000</x>
+            <y>0.5000000000</y>
+          </vector>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>-1.6250000000</y>
+          </vector>
+        </param>
+        <param name="use_kerning">
+          <bool value="true"/>
+        </param>
+        <param name="grid_fit">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="super_sample" active="true" version="0.1">
+        <param name="width">
+          <integer value="2"/>
+        </param>
+        <param name="height">
+          <integer value="2"/>
+        </param>
+        <param name="scanline">
+          <bool value="false"/>
+        </param>
+        <param name="alpha_aware">
+          <bool value="true"/>
+        </param>
+      </layer>
+      <layer type="translate" active="true" version="0.1">
+        <param name="origin">
+          <vector>
+            <x>0.0192000009</x>
+            <y>-0.0665485263</y>
+          </vector>
+        </param>
+      </layer>
+      <layer type="blur" active="false" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="12"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1000000015</x>
+            <y>0.1000000015</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="PasteCanvas" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="canvas" use=":"/>
+        <param name="zoom">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="time_offset">
+          <time value="0f"/>
+        </param>
+        <param name="children_lock">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="shade" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.7500000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="12"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.1000000015</x>
+            <y>0.1000000015</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="12"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Voria Logo">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas width="644" height="644">
+        <layer type="region" active="true" version="0.1" desc="Colored Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.333333</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="3F2AB3B642879FB63687A7132E7461D4">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-1.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="region" active="false" version="0.1" desc="White Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="3F2AB3B642879FB63687A7132E7461D4">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-1.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.3000000119"/>
+          </param>
+          <param name="blend_method">
+            <integer value="4"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>-1.3750000000</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.7500000000</x>
+              <y>0.7500000000</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.2500001192"/>
+          </param>
+          <param name="blend_method">
+            <integer value="6"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>1.3999999762</x>
+              <y>1.3999999762</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Sun Texture">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.2000000030"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas width="332" height="447" xres="4000.000000" yres="4000.000000" view-box="-1.300000 1.500000 1.300000 -2.000000">
+              <layer type="circle" active="false" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="radius">
+                  <real value="0.2500000000"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="pos">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>-0.5000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="falloff">
+                  <integer value="1"/>
+                </param>
+              </layer>
+              <layer type="conical_gradient" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="gradient">
+                  <stripes type="gradient">
+                    <color1>
+                      <color>
+                        <r>-0.000000</r>
+                        <g>-0.000000</g>
+                        <b>-0.000000</b>
+                        <a>-0.000000</a>
+                      </color>
+                    </color1>
+                    <color2>
+                      <color>
+                        <r>-0.000000</r>
+                        <g>-0.000000</g>
+                        <b>-0.000000</b>
+                        <a>1.000000</a>
+                      </color>
+                    </color2>
+                    <stripes>
+                      <integer value="10"/>
+                    </stripes>
+                  </stripes>
+                </param>
+                <param name="center">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>-0.5000000000</y>
+                  </vector>
+                </param>
+                <param name="angle">
+                  <angle value="90.000000"/>
+                </param>
+                <param name="symmetric">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="star" active="false" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>-0.5000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="radius1">
+                  <real value="0.2500000000"/>
+                </param>
+                <param name="radius2">
+                  <real value="0.3750000000"/>
+                </param>
+                <param name="angle">
+                  <angle value="90.000000"/>
+                </param>
+                <param name="points">
+                  <integer value="10"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="Logo Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="3F2AB3B642879FB63687A7132E7461D4">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>1.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-2.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>-1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>-2.2500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>0.0000000000</x>
+                      <y>-1.5000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>0.7500000000</x>
+                      <y>0.7500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector>
+                      <x>1.0000000000</x>
+                      <y>-1.0000000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="0.0250000000" guid="EE9B2DD8126DAA97A74FE6119420FA5D"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="true"/>
+                  </c4>
+                  <c5>
+                    <vector>
+                      <x>1.5000000000</x>
+                      <y>0.0000000000</y>
+                    </vector>
+                  </c5>
+                  <c6>
+                    <vector>
+                      <x>-0.2500000000</x>
+                      <y>2.2500000000</y>
+                    </vector>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="2.0000000000"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Hatch Marks">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="B9CD34EC206EBDA66DC129C40AD08F88">
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0400000000" guid="AF726E5B1A4D1A835ABCD0C275542CAF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.7300000191</x>
+                            <y>-0.2599999905</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-1.1250000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.3750000000</x>
+                            <y>-0.6250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.4900000095</x>
+                            <y>-0.6999999881</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.7500000000</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.7500000000</x>
+                            <y>-0.2500000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="B9CD34EC206EBDA66DC129C40AD08F88">
+                            <x>0.0000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0400000000" guid="AF726E5B1A4D1A835ABCD0C275542CAF"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.8012820482</x>
+                            <y>-0.5311999917</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-1.1250000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.3750000000</x>
+                            <y>-0.6250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.5833333135</x>
+                            <y>-0.3968000114</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.8846153617</x>
+                            <y>-0.4679712355</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.3538461626</x>
+                            <y>-0.0614596680</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="FEFF5BFF0971328303A9B7191AF8F425">
+                            <x>-0.5615384579</x>
+                            <y>-0.5704039931</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>-0.1250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.2794871926</x>
+                            <y>-0.7752695680</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.2615384758</x>
+                            <y>-0.2612035871</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.3871794939</x>
+                            <y>-0.2170109153</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.1846153885</x>
+                            <y>-0.2612035871</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="FEFF5BFF0971328303A9B7191AF8F425">
+                            <x>-0.5615384579</x>
+                            <y>-0.5704039931</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.1538461596</x>
+                            <y>-0.3533930779</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.6999999881</x>
+                            <y>-0.9955000281</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0769230798</x>
+                            <y>-0.3687579930</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.8846153617</x>
+                            <y>-0.4679712355</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.3538461626</x>
+                            <y>-0.0614596680</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="E36878E9187702120AE96B15EFE7FD59">
+                            <x>0.5615384579</x>
+                            <y>-0.5704039931</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.1250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2794871926</x>
+                            <y>-0.7752695680</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.2615384758</x>
+                            <y>-0.2612035871</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.3871794939</x>
+                            <y>-0.2170109153</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.1846153885</x>
+                            <y>-0.2612035871</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="E36878E9187702120AE96B15EFE7FD59">
+                            <x>0.5615384579</x>
+                            <y>-0.5704039931</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.1538461596</x>
+                            <y>-0.3533930779</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6999999881</x>
+                            <y>-0.9955000281</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0769230798</x>
+                            <y>-0.3687579930</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.4713114798</x>
+                            <y>0.6239523292</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>-0.1875000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="DA616009EFE01AFC3459CD8311B8776B">
+                            <x>0.0000000000</x>
+                            <y>0.3125000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.3750000000</x>
+                            <y>-0.3750000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.3639999926</x>
+                            <y>-0.1780321598</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.1875000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.4713114798</x>
+                            <y>0.6239523292</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>-0.1875000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="DA616009EFE01AFC3459CD8311B8776B">
+                            <x>0.0000000000</x>
+                            <y>0.3125000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0200000000" guid="974EB21DF9CCD3DAD51541940E3405CA"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.3750000000</x>
+                            <y>-0.3750000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.3639999926</x>
+                            <y>-0.1780321598</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.1875000000</x>
+                            <y>-0.5000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.8125000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>-0.1250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="8F4E22A3E4E43F1F544255AA5C595BB0">
+                            <x>0.0000000000</x>
+                            <y>-1.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0150000000" guid="2EDA639401BE9445B258DFEFAB7DEB21"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.1875000000</x>
+                            <y>-0.1875000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2019230723</x>
+                            <y>-1.2694432735</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.1888111830</x>
+                            <y>-0.3540983498</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="false">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2500000000</x>
+                            <y>-0.8125000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.2500000000</x>
+                            <y>-0.1250000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.0000000000</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector guid="8F4E22A3E4E43F1F544255AA5C595BB0">
+                            <x>0.0000000000</x>
+                            <y>-1.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0150000000" guid="2EDA639401BE9445B258DFEFAB7DEB21"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.1875000000</x>
+                            <y>-0.1875000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.3076923192</x>
+                            <y>-0.1280000061</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.2045454532</x>
+                            <y>-1.2720662355</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.1730769277</x>
+                            <y>-0.3304918110</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.1923076957</x>
+                            <y>-0.1536000073</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Shine">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.8500000238"/>
+          </param>
+          <param name="blend_method">
+            <integer value="16"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="radial_gradient" active="true" version="0.1" desc="Radial Gradient">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>0.000000</r>
+                      <g>0.000000</g>
+                      <b>0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="center">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.3750000000</y>
+                  </vector>
+                </param>
+                <param name="radius">
+                  <real value="0.6250000000"/>
+                </param>
+                <param name="loop">
+                  <bool value="false"/>
+                </param>
+                <param name="zigzag">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="linear_gradient" active="true" version="0.0" desc="Linear Gradient">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="6"/>
+                </param>
+                <param name="p1">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.3750000000</y>
+                  </vector>
+                </param>
+                <param name="p2">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>1.0000000000</y>
+                  </vector>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>0.000000</r>
+                      <g>0.000000</g>
+                      <b>0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="loop">
+                  <bool value="false"/>
+                </param>
+                <param name="zigzag">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="region" active="true" version="0.1" desc="Shiny Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>0.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="true"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0097048784"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.0000000150</x>
+                            <y>1.0000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.3750000328"/>
+                            </c0>
+                            <c1>
+                              <angle value="179.999985"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="180.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.5000000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.8385255008"/>
+                            </c0>
+                            <c1>
+                              <angle value="-116.565048"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="-90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.2500000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.3750000328"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="0.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5000000000</x>
+                            <y>0.5000000000</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="1.0000000000"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.8385254934"/>
+                            </c0>
+                            <c1>
+                              <angle value="116.565048"/>
+                            </c1>
+                          </radial_composite>
+                        </c5>
+                        <c6>
+                          <radial_composite type="vector">
+                            <c0>
+                              <real value="0.7500000000"/>
+                            </c0>
+                            <c1>
+                              <angle value="90.000000"/>
+                            </c1>
+                          </radial_composite>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="colorcorrect" active="true" version="0.1">
+                <param name="hue_adjust">
+                  <angle value="0.000000"/>
+                </param>
+                <param name="brightness">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="contrast">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="exposure">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="gamma">
+                  <real value="0.4500000268"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="translate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.1250000000</y>
+            </vector>
+          </param>
+        </layer>
+        <layer type="shade" active="false" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.8000000119"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0500000007</x>
+              <y>-0.0500000007</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.1000000015</x>
+              <y>0.1000000015</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+    <param name="children_lock">
+      <bool value="true"/>
+    </param>
+  </layer>
+  <layer type="SolidColor" active="false" version="0.1" desc="White Background">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="SolidColor" active="false" version="0.1" desc="Desaturate">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="10"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/meta_data_icon.sif b/synfig-studio/trunk/images/meta_data_icon.sif
new file mode 100644 (file)
index 0000000..dc77e29
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="1"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="0"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>META</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Arial Black</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="400"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.7919595838</x>
+        <y>0.7919595838</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rotate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="amount">
+      <angle value="45.000000"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/mirror_icon.sif b/synfig-studio/trunk/images/mirror_icon.sif
new file mode 100644 (file)
index 0000000..66dc615
--- /dev/null
@@ -0,0 +1,202 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.156182</r>
+        <g>0.216089</g>
+        <b>0.621507</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>MIRROR</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Sans Serif</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.6536458135</x>
+              <y>0.7733984590</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="-45.000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="true" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/navigator_icon.sif b/synfig-studio/trunk/images/navigator_icon.sif
new file mode 100644 (file)
index 0000000..f09c758
--- /dev/null
@@ -0,0 +1,451 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="circle" active="true" version="0.1" desc="Circle070">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.411657</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.5000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="polygon" active="true" version="0.1" desc="Polygon006">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.068166</r>
+              <g>0.086724</g>
+              <b>0.444444</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>0.0000000000</x>
+                  <y>1.7500000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.5000000000</x>
+                  <y>1.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.5000000000</x>
+                  <y>1.0000000000</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="polygon" active="true" version="0.1" desc="Polygon007">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.068166</r>
+              <g>0.086724</g>
+              <b>0.444444</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>1.7500000000</x>
+                  <y>0.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>1.0000000000</x>
+                  <y>0.5000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>1.0000000000</x>
+                  <y>-0.5000000000</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="polygon" active="true" version="0.1" desc="Polygon008">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.068166</r>
+              <g>0.086724</g>
+              <b>0.444444</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>0.0000000000</x>
+                  <y>-1.7500000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.5000000000</x>
+                  <y>-1.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.5000000000</x>
+                  <y>-1.0000000000</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="polygon" active="true" version="0.1" desc="Polygon009">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.068166</r>
+              <g>0.086724</g>
+              <b>0.444444</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>-1.7500000000</x>
+                  <y>0.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-1.0000000000</x>
+                  <y>-0.5000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-1.0000000000</x>
+                  <y>0.5000000000</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="bevel" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="135.000000"/>
+          </param>
+          <param name="depth">
+            <real value="0.2000000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.1000000000"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>NAV</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.7500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1562500000</x>
+        <y>0.1562500000</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/normal_icon.sif b/synfig-studio/trunk/images/normal_icon.sif
new file mode 100644 (file)
index 0000000..8934fb8
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>0.147464</g>
+        <b>0.764577</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.8000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="polygon" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>4.594794</r>
+              <g>4.594794</g>
+              <b>4.594794</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.1005025133</x>
+              <y>-0.0201005023</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>0.4000000060</x>
+                  <y>0.4000000060</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.8000000119</x>
+                  <y>1.6000000238</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.8000000119</x>
+                  <y>-0.2000000030</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.4000000060</x>
+                  <y>0.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.4000000060</x>
+                  <y>-1.6000000238</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.8000000119</x>
+                  <y>-1.3999999762</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.0000000000</x>
+                  <y>0.2000000030</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="blur" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.2500000000</x>
+              <y>0.2500000000</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+        </layer>
+        <layer type="polygon" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.1005025133</x>
+              <y>-0.0201005023</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="vector_list">
+            <dynamic_list type="vector">
+              <entry>
+                <vector>
+                  <x>0.4000000060</x>
+                  <y>0.4000000060</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.8000000119</x>
+                  <y>1.6000000238</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.8000000119</x>
+                  <y>-0.2000000030</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.4000000060</x>
+                  <y>0.0000000000</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.4000000060</x>
+                  <y>-1.6000000238</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>0.8000000119</x>
+                  <y>-1.3999999762</y>
+                </vector>
+              </entry>
+              <entry>
+                <vector>
+                  <x>-0.0000000000</x>
+                  <y>0.2000000030</y>
+                </vector>
+              </entry>
+            </dynamic_list>
+          </param>
+        </layer>
+        <layer type="zoom" active="true" version="0.1">
+          <param name="amount">
+            <real value="-0.1000000000"/>
+          </param>
+          <param name="center">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/pastecanvas_icon.sif b/synfig-studio/trunk/images/pastecanvas_icon.sif
new file mode 100644 (file)
index 0000000..58e809e
--- /dev/null
@@ -0,0 +1,2065 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="1"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="0"/>
+  <meta name="guide_snap" content="0"/>
+  <meta name="onion_skin" content="0"/>
+  <defs>
+    <canvas id="Layer" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.1000000015</x>
+            <y>-0.1000000015</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.8000000119</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>-0.2000000030</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2000000030</x>
+                <y>0.8000000119</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.900000</g>
+            <b>0.600000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>-0.6999999881</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>-0.1000000015</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.1000000015</x>
+                <y>0.6999999881</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Back">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide01 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.850000</r>
+              <g>0.640000</g>
+              <b>0.200000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="340C3DFE8E5CE5C4F4C6D3219F894929">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="17D265B7DF46739C41864202D568868B">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="41E4113A73C0F43E25DD26EF0CF53856">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="A803805801DB415A58D0F8F64B345E7B">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="29F6269436134CCEDC7E2A5094367DD4">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide01 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="340C3DFE8E5CE5C4F4C6D3219F894929">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="17D265B7DF46739C41864202D568868B">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="41E4113A73C0F43E25DD26EF0CF53856">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="A803805801DB415A58D0F8F64B345E7B">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="29F6269436134CCEDC7E2A5094367DD4">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Left">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide04 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.850000</r>
+              <g>0.640000</g>
+              <b>0.200000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="7064D47FC92644033605EFABF2064E48">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="17D265B7DF46739C41864202D568868B">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="D05391769240C4C39F28F37120E9E790">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1DFD877E5605ED5EE4AD968106D16BD9">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="29F6269436134CCEDC7E2A5094367DD4">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide04 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="7064D47FC92644033605EFABF2064E48">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="17D265B7DF46739C41864202D568868B">
+                      <x>-0.2500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="D05391769240C4C39F28F37120E9E790">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1DFD877E5605ED5EE4AD968106D16BD9">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="29F6269436134CCEDC7E2A5094367DD4">
+                      <x>-0.2500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Shading" group="Shading">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8000000119"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.5000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.4882812491"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.3589743674</x>
+        <y>-0.1217948720</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Right">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide03 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.850000</r>
+              <g>0.640000</g>
+              <b>0.200000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="40DA79BE005460FEF4001B8F79B14CAF">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="41E4113A73C0F43E25DD26EF0CF53856">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="EEF03825B5905242002E934B6EDCE1DA">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="9EFC05B03DD5718969805BEF166864F6">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="A803805801DB415A58D0F8F64B345E7B">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide03 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="40DA79BE005460FEF4001B8F79B14CAF">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="41E4113A73C0F43E25DD26EF0CF53856">
+                      <x>0.7500000000</x>
+                      <y>0.6217948794</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="EEF03825B5905242002E934B6EDCE1DA">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="9EFC05B03DD5718969805BEF166864F6">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="A803805801DB415A58D0F8F64B345E7B">
+                      <x>0.7500000000</x>
+                      <y>-0.3782051206</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1" group="Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Front">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="region" active="true" version="0.1" desc="BoxSide02 Region">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.850000</r>
+              <g>0.640000</g>
+              <b>0.200000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="920D6528FB937E1E183356E9D7028A05">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="D05391769240C4C39F28F37120E9E790">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="EEF03825B5905242002E934B6EDCE1DA">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="9EFC05B03DD5718969805BEF166864F6">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1DFD877E5605ED5EE4AD968106D16BD9">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+        </layer>
+        <layer type="outline" active="true" version="0.2" desc="BoxSide02 Outline">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="antialias">
+            <bool value="true"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="blurtype">
+            <integer value="1"/>
+          </param>
+          <param name="bline">
+            <bline type="bline_point" loop="true" guid="920D6528FB937E1E183356E9D7028A05">
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="D05391769240C4C39F28F37120E9E790">
+                      <x>-0.7500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="EEF03825B5905242002E934B6EDCE1DA">
+                      <x>0.2500000000</x>
+                      <y>0.2500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="9EFC05B03DD5718969805BEF166864F6">
+                      <x>0.2500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="-180.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+              <entry>
+                <composite type="bline_point">
+                  <c1>
+                    <vector guid="1DFD877E5605ED5EE4AD968106D16BD9">
+                      <x>-0.7500000000</x>
+                      <y>-0.7500000000</y>
+                    </vector>
+                  </c1>
+                  <c2>
+                    <real value="1.0000000000"/>
+                  </c2>
+                  <c3>
+                    <real value="0.5000000000"/>
+                  </c3>
+                  <c4>
+                    <bool value="false"/>
+                  </c4>
+                  <c5>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c5>
+                  <c6>
+                    <radial_composite type="vector">
+                      <c0>
+                        <real value="0.0000000000"/>
+                      </c0>
+                      <c1>
+                        <angle value="0.000000"/>
+                      </c1>
+                    </radial_composite>
+                  </c6>
+                </composite>
+              </entry>
+            </bline>
+          </param>
+          <param name="width">
+            <real value="0.0651041665"/>
+          </param>
+          <param name="sharp_cusps">
+            <bool value="false"/>
+          </param>
+          <param name="round_tip[0]">
+            <bool value="true"/>
+          </param>
+          <param name="round_tip[1]">
+            <bool value="true"/>
+          </param>
+          <param name="loopyness">
+            <real value="1.0000000000"/>
+          </param>
+        </layer>
+        <layer type="circle" active="true" version="0.1" desc="Shading" group="Shading">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.5500000119"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="0.7500000000"/>
+          </param>
+          <param name="feather">
+            <real value="0.4882812491"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>-0.7500000000</x>
+              <y>0.2500000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+          <param name="falloff">
+            <integer value="2"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/polygon_icon.sif b/synfig-studio/trunk/images/polygon_icon.sif
new file mode 100644 (file)
index 0000000..2f6fa6b
--- /dev/null
@@ -0,0 +1,288 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled1</name>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.500000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.7232009768</x>
+            <y>0.1709987968</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.7232009768</x>
+            <y>-0.7174007297</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.6174007058</x>
+            <y>-0.7174007297</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.1883995235</x>
+            <y>-0.3000000119</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.6825993061</x>
+            <y>0.1941997558</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.6999999881</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.9499999881"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.1045361017"/>
+    </param>
+    <param name="feather">
+      <real value="1.1000000164"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.6000000238</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.8000000119</x>
+            <y>0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.8000000119</x>
+            <y>-0.8000000119</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>-0.8000000119</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.3000000119</x>
+            <y>-0.3000000119</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8000000119</x>
+            <y>0.2000000030</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.8000000119</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="0.1000000015"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.6000000238</x>
+        <y>-0.8999999762</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/real_icon.sif b/synfig-studio/trunk/images/real_icon.sif
new file mode 100644 (file)
index 0000000..2a8e77d
--- /dev/null
@@ -0,0 +1,281 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.400000 -1.400000 1.400000 1.400000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Sinfg Studio Canvas Icon</name>
+  <defs>
+    <canvas id="Sphere" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>Untitled</name>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.300000</g>
+            <b>0.100000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0500000022"/>
+        </param>
+        <param name="feather">
+          <real value="1.3500000015"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2187500000</x>
+            <y>-0.2812500000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2031250000</x>
+            <y>-0.2656250000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>0.4215</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.3281250000</x>
+        <y>0.3828125000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.2624999881</x>
+        <y>-0.8750000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>3.1415</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.4046874940</x>
+        <y>0.6234375238</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.1312499940</x>
+        <y>0.2843750119</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/rectangle_icon.sif b/synfig-studio/trunk/images/rectangle_icon.sif
new file mode 100644 (file)
index 0000000..f8f5076
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="rectangle" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.5500000119"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector guid="88605003D919D5F1406046A0216B2936">
+        <x>0.6250000000</x>
+        <y>-0.6250000000</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector guid="78E67B9CE6352411669D1A4EEEEA9620">
+        <x>-0.6250000000</x>
+        <y>0.6250000000</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="0.0500000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="blur" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.2000000030</x>
+        <y>0.2000000030</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="translate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>0.1250000000</x>
+        <y>-0.1250000000</y>
+      </vector>
+    </param>
+  </layer>
+  <layer type="rectangle" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector guid="88605003D919D5F1406046A0216B2936">
+        <x>0.6250000000</x>
+        <y>-0.6250000000</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector guid="78E67B9CE6352411669D1A4EEEEA9620">
+        <x>-0.6250000000</x>
+        <y>0.6250000000</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="0.0500000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="rectangle" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="point1">
+      <vector guid="88605003D919D5F1406046A0216B2936">
+        <x>0.6250000000</x>
+        <y>-0.6250000000</y>
+      </vector>
+    </param>
+    <param name="point2">
+      <vector guid="78E67B9CE6352411669D1A4EEEEA9620">
+        <x>-0.6250000000</x>
+        <y>0.6250000000</y>
+      </vector>
+    </param>
+    <param name="expand">
+      <real value="-0.0500000000"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="duck">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.217638</r>
+        <g>0.217638</g>
+        <b>0.217638</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector guid="78E67B9CE6352411669D1A4EEEEA9620">
+        <x>-0.6250000000</x>
+        <y>0.6250000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector" guid="4C2E02CFD8096C0EFAEEF17DB8EDC282">
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="duck">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.217638</r>
+        <g>0.217638</g>
+        <b>0.217638</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector guid="88605003D919D5F1406046A0216B2936">
+        <x>0.6250000000</x>
+        <y>-0.6250000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector" guid="4C2E02CFD8096C0EFAEEF17DB8EDC282">
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.0000000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.2500000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Spotlight">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.6250000000</x>
+        <y>0.6250000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/rotate_icon.sif b/synfig-studio/trunk/images/rotate_icon.sif
new file mode 100644 (file)
index 0000000..8947644
--- /dev/null
@@ -0,0 +1,398 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <defs>
+    <canvas id="Arrow" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <layer type="circle" active="true" version="0.1" desc="Circle017">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color guid="C77A1BE47ED0BCB6B9E67E24F7276AF8">
+            <r>1.000000</r>
+            <g>0.000000</g>
+            <b>0.103813</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.5000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="rectangle" active="true" version="0.2" desc="Rectangle009">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.060778</r>
+            <g>0.058655</g>
+            <b>0.058655</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="point1">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="point2">
+          <vector>
+            <x>1.0000000000</x>
+            <y>-1.0000000000</y>
+          </vector>
+        </param>
+        <param name="expand">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1" desc="Circle018">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.060778</r>
+            <g>0.058655</g>
+            <b>0.058655</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.2500000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="polygon" active="true" version="0.1" desc="ArrowHead">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="color">
+          <color guid="C77A1BE47ED0BCB6B9E67E24F7276AF8">
+            <r>1.000000</r>
+            <g>0.000000</g>
+            <b>0.103813</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="offset">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="antialias">
+          <bool value="true"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="blurtype">
+          <integer value="1"/>
+        </param>
+        <param name="vector_list">
+          <dynamic_list type="vector">
+            <entry>
+              <vector>
+                <x>0.1250000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.2500000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.3750000000</x>
+                <y>0.1250000000</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.5000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.6250000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </entry>
+            <entry>
+              <vector>
+                <x>0.3750000000</x>
+                <y>-0.3750000000</y>
+              </vector>
+            </entry>
+          </dynamic_list>
+        </param>
+      </layer>
+      <layer type="rotate" active="true" version="0.1">
+        <param name="origin">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="amount">
+          <angle value="33.690067"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Arrow"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2" desc="Edge Darken">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.4499999285"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1500000060</x>
+        <y>0.1500000060</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="90.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.1500000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.1500000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="circle" active="false" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6499999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.6000000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.5000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>-0.2500000000</x>
+        <y>0.2500000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8999999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0500000007</x>
+        <y>-0.0500000007</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="0.5600000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.1250000000</x>
+        <y>-0.1250000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/saveall_icon.sif b/synfig-studio/trunk/images/saveall_icon.sif
new file mode 100644 (file)
index 0000000..98d9282
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>SAVE
+ALL</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Arial</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.7500000000</x>
+        <y>1.0000000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/scale_icon.sif b/synfig-studio/trunk/images/scale_icon.sif
new file mode 100644 (file)
index 0000000..0ac41a9
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000080</r>
+        <g>0.416027</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>SCALE</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Sans Serif</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.7513009906</x>
+              <y>0.7733980417</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="45.000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="true" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/segment_icon.sif b/synfig-studio/trunk/images/segment_icon.sif
new file mode 100644 (file)
index 0000000..9ec6a04
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>SEG</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>1.0000000000</x>
+        <y>1.2500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/sif_icon.sif b/synfig-studio/trunk/images/sif_icon.sif
new file mode 100644 (file)
index 0000000..e761f30
--- /dev/null
@@ -0,0 +1,1236 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Page">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="PasteCanvas" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1" desc="Paper2 Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="6240A281D6EA9370DA0D0795EA2E515A">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5091290474</x>
+                            <y>1.5202518702</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>-1.2000000477</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.5202518702</x>
+                            <y>0.5133263469</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>-1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.4000000060</x>
+                            <y>0.4000000060</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="linear_gradient" active="true" version="0.0">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="p1">
+                  <vector>
+                    <x>1.0499999523</x>
+                    <y>1.0499999523</y>
+                  </vector>
+                </param>
+                <param name="p2">
+                  <vector>
+                    <x>0.6999999881</x>
+                    <y>0.6999999881</y>
+                  </vector>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>0.000000</r>
+                      <g>0.000000</g>
+                      <b>0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="loop">
+                  <bool value="false"/>
+                </param>
+                <param name="zigzag">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="Paper2 Outline">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="6240A281D6EA9370DA0D0795EA2E515A">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.5091290474</x>
+                            <y>1.5202518702</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>-1.2000000477</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.5202518702</x>
+                            <y>0.5133263469</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>-1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.4000000060</x>
+                            <y>0.4000000060</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="false"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="region" active="true" version="0.1" desc="Paper Region">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>1.000000</r>
+                    <g>1.000000</g>
+                    <b>1.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="295363DA4AE0A389F1536EBFDD654899">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.8000000119</x>
+                            <y>1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-1.7999999523</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.8000000119</x>
+                            <y>-1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-2.4000000954</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.7999999523</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.6000000238</x>
+                            <y>-1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.7999999523</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.7999999523</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.6000000238</x>
+                            <y>0.2000000030</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.7999999523</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6000000238</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6000000238</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2000000030</x>
+                            <y>1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+              </layer>
+              <layer type="linear_gradient" active="true" version="0.0">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="p1">
+                  <vector>
+                    <x>1.0499999523</x>
+                    <y>1.0499999523</y>
+                  </vector>
+                </param>
+                <param name="p2">
+                  <vector>
+                    <x>0.8500000238</x>
+                    <y>0.8500000238</y>
+                  </vector>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>0.000000</r>
+                      <g>0.000000</g>
+                      <b>0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="loop">
+                  <bool value="false"/>
+                </param>
+                <param name="zigzag">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="outline" active="true" version="0.2" desc="Paper Outline">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="0"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="offset">
+                  <vector>
+                    <x>0.0000000000</x>
+                    <y>0.0000000000</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="false"/>
+                </param>
+                <param name="antialias">
+                  <bool value="true"/>
+                </param>
+                <param name="feather">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="blurtype">
+                  <integer value="1"/>
+                </param>
+                <param name="bline">
+                  <bline type="bline_point" loop="true" guid="295363DA4AE0A389F1536EBFDD654899">
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.8000000119</x>
+                            <y>1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>-1.7999999523</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>-0.8000000119</x>
+                            <y>-1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>-2.4000000954</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>1.7999999523</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.6000000238</x>
+                            <y>-1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>1.7999999523</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.7999999523</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.6000000238</x>
+                            <y>0.2000000030</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>1.7999999523</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>1.2000000477</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-1.2000000477</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6000000238</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.6000000238</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="false"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>0.0000000000</x>
+                            <y>1.2000000477</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.0000000000</x>
+                            <y>0.6000000238</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                    <entry>
+                      <composite type="bline_point">
+                        <c1>
+                          <vector>
+                            <x>0.2000000030</x>
+                            <y>1.6000000238</y>
+                          </vector>
+                        </c1>
+                        <c2>
+                          <real value="0.0350000000" guid="2E2CD71CFBF4E3D4F625574108CBBC52"/>
+                        </c2>
+                        <c3>
+                          <real value="0.5000000000"/>
+                        </c3>
+                        <c4>
+                          <bool value="true"/>
+                        </c4>
+                        <c5>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>-0.0000000000</y>
+                          </vector>
+                        </c5>
+                        <c6>
+                          <vector>
+                            <x>-0.6000000238</x>
+                            <y>0.0000000000</y>
+                          </vector>
+                        </c6>
+                      </composite>
+                    </entry>
+                  </bline>
+                </param>
+                <param name="width">
+                  <real value="2.0000000000"/>
+                </param>
+                <param name="sharp_cusps">
+                  <bool value="true"/>
+                </param>
+                <param name="round_tip[0]">
+                  <bool value="false"/>
+                </param>
+                <param name="round_tip[1]">
+                  <bool value="true"/>
+                </param>
+                <param name="loopyness">
+                  <real value="1.0000000000"/>
+                </param>
+              </layer>
+              <layer type="circle" active="true" version="0.1">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="0.7699999809"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="13"/>
+                </param>
+                <param name="color">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="radius">
+                  <real value="1.8337486137"/>
+                </param>
+                <param name="feather">
+                  <real value="1.3500000000"/>
+                </param>
+                <param name="pos">
+                  <vector>
+                    <x>-0.2307692319</x>
+                    <y>0.7179487348</y>
+                  </vector>
+                </param>
+                <param name="invert">
+                  <bool value="true"/>
+                </param>
+                <param name="falloff">
+                  <integer value="1"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.5000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Shaded Logo">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="SINFG Logo">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>-0.4000000060</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas" use="././././logo.sif#"/>
+          <param name="zoom">
+            <real value="-0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+          <param name="children_lock">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.8500000238"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0750000030</x>
+              <y>-0.0750000030</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.1500000060</x>
+              <y>0.1500000060</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+    <param name="children_lock">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="translate" active="true" version="0.1">
+    <param name="origin">
+      <vector>
+        <x>-0.2000000030</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/sinfg_icon.sif b/synfig-studio/trunk/images/sinfg_icon.sif
new file mode 100644 (file)
index 0000000..aff3ee3
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0500000007</y>
+      </vector>
+    </param>
+    <param name="canvas" use="./././logo.sif#"/>
+    <param name="zoom">
+      <real value="0.2750000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1000000015</x>
+        <y>-0.1000000015</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.2000000030</x>
+        <y>0.2000000030</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/sketch_icon.sif b/synfig-studio/trunk/images/sketch_icon.sif
new file mode 100644 (file)
index 0000000..e4d585d
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>-0.000000</r>
+        <g>0.499984</g>
+        <b>0.479841</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.3000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>SKETCH</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Sans Serif</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.6187184453</x>
+              <y>0.6187184453</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="45.000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="true" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/smooth_move_icon.sif b/synfig-studio/trunk/images/smooth_move_icon.sif
new file mode 100644 (file)
index 0000000..0d4c879
--- /dev/null
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.647450</r>
+        <g>0.215732</g>
+        <b>0.361425</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.7500000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.4000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="text" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="text">
+            <string>SMOOTH</string>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="family">
+            <string>Sans Serif</string>
+          </param>
+          <param name="style">
+            <integer value="0"/>
+          </param>
+          <param name="weight">
+            <integer value="700"/>
+          </param>
+          <param name="compress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="vcompress">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.5855728388</x>
+              <y>0.6076698899</y>
+            </vector>
+          </param>
+          <param name="orient">
+            <vector>
+              <x>0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="use_kerning">
+            <bool value="true"/>
+          </param>
+          <param name="grid_fit">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="45.000000"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="super_sample" active="true" version="0.1">
+    <param name="width">
+      <integer value="2"/>
+    </param>
+    <param name="height">
+      <integer value="2"/>
+    </param>
+    <param name="scanline">
+      <bool value="false"/>
+    </param>
+    <param name="alpha_aware">
+      <bool value="true"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/string_icon.sif b/synfig-studio/trunk/images/string_icon.sif
new file mode 100644 (file)
index 0000000..04f81d5
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>STR</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>1.0000000000</x>
+        <y>1.1250000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/swap_colors_icon.sif b/synfig-studio/trunk/images/swap_colors_icon.sif
new file mode 100644 (file)
index 0000000..2b75b0b
--- /dev/null
@@ -0,0 +1,308 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled1</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.125000 0.125000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="outline" active="true" version="0.2" desc="Line Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="false">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.2500000000</x>
+                <y>0.3750000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.3750000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="1.5000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="2.2500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.2187500000"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="true"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon004">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.1250000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.3750000000</x>
+            <y>-0.8750000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.8750000000</x>
+            <y>-0.2500000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon003">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>0.8750000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.8750000000</x>
+            <y>0.3750000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.2500000000</x>
+            <y>-0.1250000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6000000238"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0625000000</x>
+        <y>-0.0625000000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.0625000000</x>
+        <y>0.0625000000</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="-0.0500000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/time_track_icon.sif b/synfig-studio/trunk/images/time_track_icon.sif
new file mode 100644 (file)
index 0000000..bea21fe
--- /dev/null
@@ -0,0 +1,242 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="1"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="1"/>
+  <meta name="guide_show" content="1"/>
+  <meta name="guide_snap" content="0"/>
+  <meta name="onion_skin" content="0"/>
+  <layer type="circle" active="false" version="0.1" desc="Circle067">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.265778</g>
+        <b>0.265778</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.7500000000"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="1"/>
+    </param>
+  </layer>
+  <layer type="text" active="false" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>i</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Times</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="400"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>2.2500000000</x>
+        <y>2.2500000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="polygon" active="true" version="0.1" desc="Polygon009">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.444444</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="vector_list">
+      <dynamic_list type="vector">
+        <entry>
+          <vector>
+            <x>-1.7500000000</x>
+            <y>1.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.7500000000</x>
+            <y>1.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>1.7500000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.5000000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>0.5000000000</x>
+            <y>-1.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.5000000000</x>
+            <y>-1.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-0.5000000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </entry>
+        <entry>
+          <vector>
+            <x>-1.7500000000</x>
+            <y>0.7500000000</y>
+          </vector>
+        </entry>
+      </dynamic_list>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="135.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.2000000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.1000000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/valuenode_icon.sif b/synfig-studio/trunk/images/valuenode_icon.sif
new file mode 100644 (file)
index 0000000..1a7907d
--- /dev/null
@@ -0,0 +1,240 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.400000 -1.400000 1.400000 1.400000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>DataNode Icon</name>
+  <defs>
+    <canvas id="Sphere" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>Untitled</name>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>0.300000</g>
+            <b>0.100000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0500000022"/>
+        </param>
+        <param name="feather">
+          <real value="1.3500000015"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2187500000</x>
+            <y>-0.2812500000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.3000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2031250000</x>
+            <y>-0.2656250000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.2000000030</x>
+            <y>0.2000000030</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="text" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="text">
+      <string>DYN</string>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.500000</r>
+        <g>0.750000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="family">
+      <string>Sans Serif</string>
+    </param>
+    <param name="style">
+      <integer value="0"/>
+    </param>
+    <param name="weight">
+      <integer value="700"/>
+    </param>
+    <param name="compress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="vcompress">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.6250000000</x>
+        <y>1.0000000000</y>
+      </vector>
+    </param>
+    <param name="orient">
+      <vector>
+        <x>0.5000000000</x>
+        <y>0.5000000000</y>
+      </vector>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="use_kerning">
+      <bool value="true"/>
+    </param>
+    <param name="grid_fit">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="blur" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="5.0500001907"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/vector_icon.sif b/synfig-studio/trunk/images/vector_icon.sif
new file mode 100644 (file)
index 0000000..2d2bde7
--- /dev/null
@@ -0,0 +1,250 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2952.755900" yres="2952.755900" view-box="-1.600000 -1.600000 1.600000 1.600000" antialias="2" fps="12.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Sinfg Studio Vector Icon</name>
+  <defs>
+    <canvas id="Sphere" view-box="-1.000000 -1.000000 1.000000 1.000000" bgcolor="0.500000 0.500000 0.500000 1.000000">
+      <name>Sphere</name>
+      <layer type="SolidColor" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.898889</r>
+            <g>0.100146</g>
+            <b>0.001630</b>
+            <a>0.986486</a>
+          </color>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>0.000000</r>
+            <g>0.000000</g>
+            <b>0.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.8722901741"/>
+        </param>
+        <param name="feather">
+          <real value="0.7499999993"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2187500000</x>
+            <y>-0.2812500000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="0.6499999762"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>1.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="0.2500000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.2500000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>-0.2031250000</x>
+            <y>-0.2656250000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="false"/>
+        </param>
+        <param name="falloff">
+          <integer value="2"/>
+        </param>
+      </layer>
+      <layer type="blur" active="true" version="0.2">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="0"/>
+        </param>
+        <param name="size">
+          <vector>
+            <x>0.4375000000</x>
+            <y>0.4218750000</y>
+          </vector>
+        </param>
+        <param name="type">
+          <integer value="1"/>
+        </param>
+      </layer>
+      <layer type="circle" active="true" version="0.1">
+        <param name="z_depth">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="amount">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="blend_method">
+          <integer value="1"/>
+        </param>
+        <param name="color">
+          <color>
+            <r>1.000000</r>
+            <g>1.000000</g>
+            <b>1.000000</b>
+            <a>0.000000</a>
+          </color>
+        </param>
+        <param name="radius">
+          <real value="1.0000000000"/>
+        </param>
+        <param name="feather">
+          <real value="0.0000000000"/>
+        </param>
+        <param name="pos">
+          <vector>
+            <x>0.0000000000</x>
+            <y>0.0000000000</y>
+          </vector>
+        </param>
+        <param name="invert">
+          <bool value="true"/>
+        </param>
+        <param name="falloff">
+          <integer value="0"/>
+        </param>
+      </layer>
+    </canvas>
+  </defs>
+  <layer type="SolidColor" active="false" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8999999762"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="0.9499999992"/>
+    </param>
+    <param name="feather">
+      <real value="0.3000000090"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.1000000015</x>
+        <y>0.1000000015</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas" use="Sphere"/>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="zoom" active="true" version="0.1">
+    <param name="amount">
+      <real value="0.2100000000"/>
+    </param>
+    <param name="center">
+      <vector>
+        <x>0.5749999881</x>
+        <y>0.5500000119</y>
+      </vector>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/wallpaper.sif b/synfig-studio/trunk/images/wallpaper.sif
new file mode 100644 (file)
index 0000000..66db075
--- /dev/null
@@ -0,0 +1,687 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="1152" height="864" xres="2834.645691" yres="2834.645691" view-box="-2.000000 1.500000 2.000000 -1.500000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="noise" active="true" version="0.0">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.000000">
+                <r>0.000000</r>
+                <g>0.000000</g>
+                <b>0.000000</b>
+                <a>1.000000</a>
+              </color>
+              <color pos="1.000000">
+                <r>1.000000</r>
+                <g>1.000000</g>
+                <b>1.000000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="seed">
+            <integer value="1079668228"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0149999997</x>
+              <y>0.1562500000</y>
+            </vector>
+          </param>
+          <param name="smooth">
+            <integer value="1"/>
+          </param>
+          <param name="detail">
+            <integer value="2"/>
+          </param>
+          <param name="speed">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="turbulent">
+            <bool value="false"/>
+          </param>
+          <param name="do_alpha">
+            <bool value="false"/>
+          </param>
+          <param name="super_sample">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="blur" active="false" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.1000000015</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="0"/>
+          </param>
+        </layer>
+        <layer type="rotate" active="true" version="0.1">
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="amount">
+            <angle value="60.000000"/>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.6499999762"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.470726</r>
+              <g>0.477000</g>
+              <b>0.477000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.3499999940"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.638086</r>
+              <g>0.509474</g>
+              <b>0.361408</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="noise" active="true" version="0.0">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="gradient">
+      <gradient>
+        <color pos="0.357895">
+          <r>0.531049</r>
+          <g>0.531049</g>
+          <b>0.531049</b>
+          <a>0.000000</a>
+        </color>
+        <color pos="0.677193">
+          <r>0.006310</r>
+          <g>0.000000</g>
+          <b>0.000000</b>
+          <a>0.485794</a>
+        </color>
+        <color pos="0.750000">
+          <r>0.006310</r>
+          <g>0.000000</g>
+          <b>0.000000</b>
+          <a>0.750000</a>
+        </color>
+        <color pos="0.750000">
+          <r>0.076829</r>
+          <g>0.010931</g>
+          <b>0.001345</b>
+          <a>0.652360</a>
+        </color>
+      </gradient>
+    </param>
+    <param name="seed">
+      <integer value="4234791" guid="211A6EDF0A9326582709B74248CD964D"/>
+    </param>
+    <param name="size">
+      <vector guid="84ACDBFC21260109F4CD258ED0647A80">
+        <x>1.0000000000</x>
+        <y>1.0000000000</y>
+      </vector>
+    </param>
+    <param name="smooth">
+      <integer value="2" guid="E686B76A98BBC1993B9D48B78A9A7EE4"/>
+    </param>
+    <param name="detail">
+      <integer value="7" guid="5293BA0C54D192CA8FCB959775BB76BE"/>
+    </param>
+    <param name="speed">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="turbulent">
+      <bool value="false"/>
+    </param>
+    <param name="do_alpha">
+      <bool value="false"/>
+    </param>
+    <param name="super_sample">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="linear_gradient" active="true" version="0.0" desc="Gradient002">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.6000000238"/>
+    </param>
+    <param name="blend_method">
+      <integer value="6"/>
+    </param>
+    <param name="p1">
+      <vector>
+        <x>0.0000000000</x>
+        <y>-1.5000000000</y>
+      </vector>
+    </param>
+    <param name="p2">
+      <vector>
+        <x>0.0000000000</x>
+        <y>1.5000000000</y>
+      </vector>
+    </param>
+    <param name="gradient">
+      <gradient>
+        <color pos="0.000000">
+          <r>0.000000</r>
+          <g>0.000000</g>
+          <b>0.000000</b>
+          <a>1.000000</a>
+        </color>
+        <color pos="1.000000">
+          <r>1.000000</r>
+          <g>1.000000</g>
+          <b>1.000000</b>
+          <a>1.000000</a>
+        </color>
+      </gradient>
+    </param>
+    <param name="loop">
+      <bool value="false"/>
+    </param>
+    <param name="zigzag">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="17"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="noise" active="true" version="0.0">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="gradient">
+            <gradient>
+              <color pos="0.750000">
+                <r>0.457498</r>
+                <g>0.383419</g>
+                <b>0.344119</b>
+                <a>0.000000</a>
+              </color>
+              <color pos="0.750000">
+                <r>0.500000</r>
+                <g>0.500000</g>
+                <b>0.500000</b>
+                <a>1.000000</a>
+              </color>
+            </gradient>
+          </param>
+          <param name="seed">
+            <integer value="4234791" guid="211A6EDF0A9326582709B74248CD964D"/>
+          </param>
+          <param name="size">
+            <vector guid="84ACDBFC21260109F4CD258ED0647A80">
+              <x>1.0000000000</x>
+              <y>1.0000000000</y>
+            </vector>
+          </param>
+          <param name="smooth">
+            <integer value="2" guid="E686B76A98BBC1993B9D48B78A9A7EE4"/>
+          </param>
+          <param name="detail">
+            <integer value="7" guid="5293BA0C54D192CA8FCB959775BB76BE"/>
+          </param>
+          <param name="speed">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="turbulent">
+            <bool value="false"/>
+          </param>
+          <param name="do_alpha">
+            <bool value="false"/>
+          </param>
+          <param name="super_sample">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="shade" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.295985</r>
+              <g>0.026400</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="offset">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="size">
+            <vector>
+              <x>0.0750000030</x>
+              <y>0.0750000030</y>
+            </vector>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="invert">
+            <bool value="true"/>
+          </param>
+        </layer>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="Etch Texture">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.6999999881"/>
+          </param>
+          <param name="blend_method">
+            <integer value="17"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas">
+            <canvas>
+              <layer type="noise" active="true" version="0.0" desc="Roughness">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="gradient">
+                  <gradient>
+                    <color pos="0.000000">
+                      <r>0.000000</r>
+                      <g>0.000000</g>
+                      <b>0.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                    <color pos="1.000000">
+                      <r>1.000000</r>
+                      <g>1.000000</g>
+                      <b>1.000000</b>
+                      <a>1.000000</a>
+                    </color>
+                  </gradient>
+                </param>
+                <param name="seed">
+                  <integer value="1079668228"/>
+                </param>
+                <param name="size">
+                  <vector>
+                    <x>0.0111111114</x>
+                    <y>0.0111111114</y>
+                  </vector>
+                </param>
+                <param name="smooth">
+                  <integer value="2"/>
+                </param>
+                <param name="detail">
+                  <integer value="3"/>
+                </param>
+                <param name="speed">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="turbulent">
+                  <bool value="false"/>
+                </param>
+                <param name="do_alpha">
+                  <bool value="false"/>
+                </param>
+                <param name="super_sample">
+                  <bool value="false"/>
+                </param>
+              </layer>
+              <layer type="bevel" active="true" version="0.2">
+                <param name="z_depth">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="amount">
+                  <real value="1.0000000000"/>
+                </param>
+                <param name="blend_method">
+                  <integer value="1"/>
+                </param>
+                <param name="type">
+                  <integer value="1"/>
+                </param>
+                <param name="color1">
+                  <color>
+                    <r>0.881822</r>
+                    <g>0.788820</g>
+                    <b>0.722108</b>
+                    <a>0.602041</a>
+                  </color>
+                </param>
+                <param name="color2">
+                  <color>
+                    <r>0.000000</r>
+                    <g>0.000000</g>
+                    <b>0.000000</b>
+                    <a>1.000000</a>
+                  </color>
+                </param>
+                <param name="angle">
+                  <angle value="90.000000"/>
+                </param>
+                <param name="depth">
+                  <real value="0.0075000000"/>
+                </param>
+                <param name="softness">
+                  <real value="0.0000000000"/>
+                </param>
+                <param name="use_luma">
+                  <bool value="true"/>
+                </param>
+                <param name="solid">
+                  <bool value="false"/>
+                </param>
+              </layer>
+            </canvas>
+          </param>
+          <param name="zoom">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="bevel" active="true" version="0.2" desc="Etch Depth">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>0.956527</r>
+              <g>0.878455</g>
+              <b>0.809212</b>
+              <a>0.500000</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="90.000000"/>
+          </param>
+          <param name="depth">
+            <real value="-0.0125000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.0055555557"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="circle" active="true" version="0.1" desc="Spotlight">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="1"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="radius">
+      <real value="1.4918680522"/>
+    </param>
+    <param name="feather">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="pos">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="true"/>
+    </param>
+    <param name="falloff">
+      <integer value="2"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1" desc="Logo with Bevel">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="PasteCanvas" active="true" version="0.1" desc="logo.sif">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="origin">
+            <vector>
+              <x>0.0000000000</x>
+              <y>0.0000000000</y>
+            </vector>
+          </param>
+          <param name="canvas" use="logo.sif#"/>
+          <param name="zoom">
+            <real value="-0.8000000000"/>
+          </param>
+          <param name="time_offset">
+            <time value="0f"/>
+          </param>
+        </layer>
+        <layer type="bevel" active="true" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="12"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>0.561224</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.100000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="90.000000"/>
+          </param>
+          <param name="depth">
+            <real value="-0.0250000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.0250000000"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/width_icon.sif b/synfig-studio/trunk/images/width_icon.sif
new file mode 100644 (file)
index 0000000..886143a
--- /dev/null
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-1.000000 1.000000 1.000000 -1.000000" antialias="1" fps="30.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <layer type="outline" active="true" version="0.2" desc="NewBLine003 Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.1000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="false">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.8906250000</x>
+                <y>0.7656250000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>1.0937500000</x>
+                <y>1.0000000000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>1.0937500000</x>
+                <y>1.0000000000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>-0.0000000000</x>
+                <y>0.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="9.4062940700"/>
+            </c2>
+            <c3>
+              <real value="0.4728665650"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>0.2197851539</x>
+                <y>-0.9105731249</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>0.2197851539</x>
+                <y>-0.9105731249</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.8906250000</x>
+                <y>-0.8125000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="0.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <vector>
+                <x>1.6562500000</x>
+                <y>0.7656250000</y>
+              </vector>
+            </c5>
+            <c6>
+              <vector>
+                <x>1.6562500000</x>
+                <y>0.7656250000</y>
+              </vector>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.1200000000"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="true"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/images/zoom_icon.sif b/synfig-studio/trunk/images/zoom_icon.sif
new file mode 100644 (file)
index 0000000..839c2f7
--- /dev/null
@@ -0,0 +1,1976 @@
+<?xml version="1.0"?>
+<canvas version="0.1" width="128" height="128" xres="2834.645691" yres="2834.645691" view-box="-2.000000 2.000000 2.000000 -2.000000" antialias="1" fps="24.000" begin-time="0f" end-time="0f" bgcolor="0.500000 0.500000 0.500000 1.000000">
+  <name>Untitled0</name>
+  <meta name="grid_show" content="0"/>
+  <meta name="grid_size" content="0.250000 0.250000"/>
+  <meta name="grid_snap" content="0"/>
+  <meta name="guide_snap" content="0"/>
+  <layer type="region" active="true" version="0.1" desc="Handle Region">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.436364</r>
+        <g>0.264545</g>
+        <b>0.072727</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="false" guid="73EBE2460430C9A0247438C73DFB7FC7">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.5000000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.5000000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.7500000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5070168972"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+  </layer>
+  <layer type="bevel" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="13"/>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="color1">
+      <color>
+        <r>1.000000</r>
+        <g>1.000000</g>
+        <b>1.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="color2">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="angle">
+      <angle value="90.000000"/>
+    </param>
+    <param name="depth">
+      <real value="0.1250000000"/>
+    </param>
+    <param name="softness">
+      <real value="0.1250000000"/>
+    </param>
+    <param name="use_luma">
+      <bool value="false"/>
+    </param>
+    <param name="solid">
+      <bool value="false"/>
+    </param>
+  </layer>
+  <layer type="outline" active="true" version="0.2" desc="Handle Outline">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.073955</r>
+        <g>0.016095</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+    <param name="antialias">
+      <bool value="true"/>
+    </param>
+    <param name="feather">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="blurtype">
+      <integer value="1"/>
+    </param>
+    <param name="bline">
+      <bline type="bline_point" loop="false" guid="73EBE2460430C9A0247438C73DFB7FC7">
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-0.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.5000000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.5000000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.7500000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="-47.792702"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.2500000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5070168972"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-1.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379168078"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>1.0000000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-1.2500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.7500000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-1.0000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.5000000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.7500000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.2379167864"/>
+                </c0>
+                <c1>
+                  <angle value="132.207306"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.7500000000"/>
+                </c0>
+                <c1>
+                  <angle value="90.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+        <entry>
+          <composite type="bline_point">
+            <c1>
+              <vector>
+                <x>0.2500000000</x>
+                <y>-0.5000000000</y>
+              </vector>
+            </c1>
+            <c2>
+              <real value="1.0000000000"/>
+            </c2>
+            <c3>
+              <real value="0.5000000000"/>
+            </c3>
+            <c4>
+              <bool value="false"/>
+            </c4>
+            <c5>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="-180.000000"/>
+                </c1>
+              </radial_composite>
+            </c5>
+            <c6>
+              <radial_composite type="vector">
+                <c0>
+                  <real value="0.0000000000"/>
+                </c0>
+                <c1>
+                  <angle value="0.000000"/>
+                </c1>
+              </radial_composite>
+            </c6>
+          </composite>
+        </entry>
+      </bline>
+    </param>
+    <param name="width">
+      <real value="0.1250000010"/>
+    </param>
+    <param name="sharp_cusps">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[0]">
+      <bool value="true"/>
+    </param>
+    <param name="round_tip[1]">
+      <bool value="true"/>
+    </param>
+    <param name="loopyness">
+      <real value="1.0000000000"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.4399999976"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="circle" active="true" version="0.1" desc="Circle064">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.278221</g>
+              <b>0.790321</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="1.1313756488"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>-0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="falloff">
+            <integer value="1"/>
+          </param>
+        </layer>
+        <layer type="bevel" active="false" version="0.2">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="0.4900000095"/>
+          </param>
+          <param name="blend_method">
+            <integer value="13"/>
+          </param>
+          <param name="type">
+            <integer value="1"/>
+          </param>
+          <param name="color1">
+            <color>
+              <r>1.000000</r>
+              <g>1.000000</g>
+              <b>1.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="color2">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="angle">
+            <angle value="135.000000"/>
+          </param>
+          <param name="depth">
+            <real value="0.3750000000"/>
+          </param>
+          <param name="softness">
+            <real value="0.3750000000"/>
+          </param>
+          <param name="use_luma">
+            <bool value="false"/>
+          </param>
+          <param name="solid">
+            <bool value="false"/>
+          </param>
+        </layer>
+        <layer type="SolidColor" active="true" version="0.1">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="0"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>0.000000</a>
+            </color>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="PasteCanvas" active="true" version="0.1">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="1.0000000000"/>
+    </param>
+    <param name="blend_method">
+      <integer value="0"/>
+    </param>
+    <param name="origin">
+      <vector>
+        <x>0.0000000000</x>
+        <y>0.0000000000</y>
+      </vector>
+    </param>
+    <param name="canvas">
+      <canvas>
+        <layer type="circle" active="true" version="0.1" desc="Circle063">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>1.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="1.2500000000"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>-0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="falloff">
+            <integer value="1"/>
+          </param>
+        </layer>
+        <layer type="circle" active="true" version="0.1" desc="Circle064">
+          <param name="z_depth">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="amount">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="blend_method">
+            <integer value="1"/>
+          </param>
+          <param name="color">
+            <color>
+              <r>0.000000</r>
+              <g>0.000000</g>
+              <b>0.000000</b>
+              <a>0.000000</a>
+            </color>
+          </param>
+          <param name="radius">
+            <real value="1.0000000000"/>
+          </param>
+          <param name="feather">
+            <real value="0.0000000000"/>
+          </param>
+          <param name="pos">
+            <vector>
+              <x>-0.5000000000</x>
+              <y>0.5000000000</y>
+            </vector>
+          </param>
+          <param name="invert">
+            <bool value="false"/>
+          </param>
+          <param name="falloff">
+            <integer value="1"/>
+          </param>
+        </layer>
+      </canvas>
+    </param>
+    <param name="zoom">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="time_offset">
+      <time value="0f"/>
+    </param>
+  </layer>
+  <layer type="shade" active="true" version="0.2">
+    <param name="z_depth">
+      <real value="0.0000000000"/>
+    </param>
+    <param name="amount">
+      <real value="0.8700000048"/>
+    </param>
+    <param name="blend_method">
+      <integer value="12"/>
+    </param>
+    <param name="color">
+      <color>
+        <r>0.000000</r>
+        <g>0.000000</g>
+        <b>0.000000</b>
+        <a>1.000000</a>
+      </color>
+    </param>
+    <param name="offset">
+      <vector>
+        <x>0.1250000000</x>
+        <y>-0.1250000000</y>
+      </vector>
+    </param>
+    <param name="size">
+      <vector>
+        <x>0.1562500000</x>
+        <y>0.1562500000</y>
+      </vector>
+    </param>
+    <param name="type">
+      <integer value="1"/>
+    </param>
+    <param name="invert">
+      <bool value="false"/>
+    </param>
+  </layer>
+</canvas>
diff --git a/synfig-studio/trunk/sinfgstudio.desktop.in b/synfig-studio/trunk/sinfgstudio.desktop.in
new file mode 100644 (file)
index 0000000..5fdeb2e
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Name=@PACKAGE_NAME@
+Comment=A Powerful 2D Animation and Composition Package
+Exec=@prefix@/bin/sinfgstudio
+Terminal=1
+Type=Application
+Icon=@prefix@/share/pixmaps/sinfg_icon.@imageext@
+Categories=Application;Graphics;
+StartupNotify=true
+Encoding=UTF-8
+MimeType=image/sif
diff --git a/synfig-studio/trunk/sinfgstudio.keys.in b/synfig-studio/trunk/sinfgstudio.keys.in
new file mode 100644 (file)
index 0000000..4d4c1c8
--- /dev/null
@@ -0,0 +1,23 @@
+
+image/sif:
+       open=@prefix@/bin/sinfgstudio %f
+       view=@prefix@/bin/sinfgstudio %f
+       icon-filename=@prefix@/share/pixmaps/sif_icon.@imageext@
+       description=SINFG Composition
+       default_action_type=application
+       short_list_application_ids_for_novice_user_level=sinfgstudio
+       short_list_application_ids_for_intermediate_user_level=sinfgstudio
+       short_list_application_ids_for_advanced_user_level=sinfgstudio
+#    category=Images
+                                                                                
+
+image/sifz:
+       open=@prefix@/bin/sinfgstudio %f
+       view=@prefix@/bin/sinfgstudio %f
+       icon-filename=@prefix@/share/pixmaps/sif_icon.@imageext@
+       description=Compressed SINFG Composition
+       default_action_type=application
+       short_list_application_ids_for_novice_user_level=sinfgstudio
+       short_list_application_ids_for_intermediate_user_level=sinfgstudio
+       short_list_application_ids_for_advanced_user_level=sinfgstudio
+#   category=Images
diff --git a/synfig-studio/trunk/sinfgstudio.mime.in b/synfig-studio/trunk/sinfgstudio.mime.in
new file mode 100644 (file)
index 0000000..1b95060
--- /dev/null
@@ -0,0 +1,7 @@
+# mime types for sinfg studio
+
+image/sif
+       ext: sif SIF
+
+image/sifz
+       ext: sifZ SIFZ sif.gz SIF.GZ SIF.gz
diff --git a/synfig-studio/trunk/src/Makefile.am b/synfig-studio/trunk/src/Makefile.am
new file mode 100644 (file)
index 0000000..bd320f4
--- /dev/null
@@ -0,0 +1,20 @@
+# $Header: /opt/voria/cvs/studio/src/Makefile.am,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+
+MAINTAINERCLEANFILES=Makefile.in
+EXTRA_DIST=template.cpp template.h
+
+SUBDIRS=sinfgapp gtkmm
+
+#if WINDOWSYS_GTKMM
+#WINDOWSYS_LIBS=$(top_builddir)/src/gtkmm/libwindowsys.a @GTKMM_LIBS@
+#SUBDIRS=sinfgapp gtkmm
+#else
+#WINDOWSYS_LIBS=$(top_builddir)/src/win32/libwindowsys.a @WIN32_LIBS@
+#SUBDIRS=win32
+#endif
+
+#bin_PROGRAMS  =       sinfgstudio
+#sinfgstudio_SOURCES = main.cpp app.cpp app.h instance.cpp instance.h actions.cpp actions.h toolbox.cpp toolbox.h compview.cpp compview.h canvasview.cpp canvasview.h workarea.cpp workarea.h canvasproperties.cpp canvasproperties.h
+# view.h view.cpp workarea.cpp workarea.h toolbox.cpp toolbox.h trackview.cpp trackview.h actions.cpp actions.h compview.cpp compview.h
+#sinfgstudio_LDADD = @SINFG_LIBS@ $(WINDOWSYS_LIBS)
+#sinfgstudio_LDFLAGS=-dlopen self
diff --git a/synfig-studio/trunk/src/gtkmm/Makefile.am b/synfig-studio/trunk/src/gtkmm/Makefile.am
new file mode 100644 (file)
index 0000000..c88314f
--- /dev/null
@@ -0,0 +1,53 @@
+# $Id: Makefile.am,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+
+MAINTAINERCLEANFILES=Makefile.in $(GLADE_FILES)
+
+CELLRENDERER_HH=cellrenderer_gradient.h cellrenderer_timetrack.h cellrenderer_time.h cellrenderer_value.h
+CELLRENDERER_CC=cellrenderer_gradient.cpp cellrenderer_timetrack.cpp cellrenderer_time.cpp cellrenderer_value.cpp
+
+WORKAREARENDERER_HH=renderer_bbox.h renderer_dragbox.h renderer_ducks.h renderer_grid.h renderer_guides.h renderer_timecode.h renderer_canvas.h workarearenderer.h
+WORKAREARENDERER_CC=renderer_bbox.cpp renderer_dragbox.cpp renderer_ducks.cpp renderer_grid.cpp renderer_guides.cpp renderer_timecode.cpp renderer_canvas.cpp workarearenderer.cpp
+
+PALETTE_HH=mod_palette/mod_palette.h mod_palette/dock_paledit.h mod_palette/dock_palbrowse.h
+PALETTE_CC=mod_palette/mod_palette.cpp mod_palette/dock_paledit.cpp mod_palette/dock_palbrowse.cpp
+
+MOD_MIRROR_HH=mod_mirror/mod_mirror.h mod_mirror/state_mirror.h
+MOD_MIRROR_CC=mod_mirror/mod_mirror.cpp mod_mirror/state_mirror.cpp
+
+DIALOG_HH=dialog_setup.h dialog_waypoint.h dialog_gradient.h dialog_color.h dialog_keyframe.h dialog_preview.h dialog_soundselect.h
+DIALOG_CC=dialog_setup.cpp dialog_waypoint.cpp dialog_gradient.cpp dialog_color.cpp dialog_keyframe.cpp dialog_preview.cpp dialog_soundselect.cpp
+
+DOCK_HH=dock_layergroups.h dock_children.h dock_canvasspecific.h dock_metadata.h dock_layers.h dock_params.h dock_keyframes.h dialog_tooloptions.h dock_canvases.h dock_history.h dockmanager.h dockbook.h dockdialog.h dockable.h dock_info.h dock_navigator.h dock_curves.h dock_timetrack.h
+DOCK_CC=dock_layergroups.cpp dock_children.cpp dock_canvasspecific.cpp dock_metadata.cpp dock_layers.cpp dock_params.cpp dock_keyframes.cpp dialog_tooloptions.cpp dock_canvases.cpp dock_history.cpp dockmanager.cpp dockbook.cpp dockdialog.cpp dockable.cpp dock_info.cpp dock_navigator.cpp dock_curves.cpp dock_timetrack.cpp
+
+WIDGET_HH=widget_compselect.h widget_gradient.h widget_color.h widget_enum.h widget_canvaschooser.h widget_time.h widget_filename.h widget_vector.h widget_value.h widget_defaults.h widget_coloredit.h widget_waypoint.h widget_waypointmodel.h widget_distance.h widget_sound.h widget_timeslider.h widget_curves.h
+WIDGET_CC=widget_compselect.cpp widget_gradient.cpp widget_color.cpp widget_enum.cpp widget_canvaschooser.cpp widget_time.cpp widget_filename.cpp widget_vector.cpp widget_value.cpp widget_defaults.cpp widget_coloredit.cpp widget_waypoint.cpp widget_waypointmodel.cpp widget_distance.cpp widget_sound.cpp widget_timeslider.cpp widget_curves.cpp
+
+STATE_HH=state_normal.h state_eyedrop.h state_draw.h state_stroke.h state_fill.h state_bline.h state_polygon.h state_sketch.h state_gradient.h state_circle.h state_rectangle.h state_width.h state_smoothmove.h state_scale.h state_rotate.h state_zoom.h
+STATE_CC=state_normal.cpp state_eyedrop.cpp state_draw.cpp state_stroke.cpp state_fill.cpp state_bline.cpp state_polygon.cpp state_sketch.cpp state_gradient.cpp state_circle.cpp state_rectangle.cpp state_width.cpp state_smoothmove.cpp state_scale.cpp state_rotate.cpp state_zoom.cpp
+
+TREEVIEW_HH=childrentree.h layertree.h keyframetree.h layergrouptree.h
+TREEVIEW_CC=childrentree.cpp layertree.cpp keyframetree.cpp layergrouptree.cpp
+
+TREESTORE_HH=layergrouptreestore.h metadatatreestore.h historytreestore.h keyframetreestore.h childrentreestore.h  canvastreestore.h layertreestore.h layerparamtreestore.h
+TREESTORE_CC=layergrouptreestore.cpp metadatatreestore.cpp historytreestore.cpp keyframetreestore.cpp childrentreestore.cpp canvastreestore.cpp layertreestore.cpp layerparamtreestore.cpp
+
+DUCKTRASNFORM_HH=duck.h ducktransform_translate.h ducktransform_scale.h ducktransform_rotate.h
+DUCKTRANSFORM_CC=duck.cpp
+
+EVENTS_HH=event_layerclick.h event_mouse.h
+EVENTS_CC=
+
+ACTION_MANAGERS_HH=layeractionmanager.h keyframeactionmanager.h groupactionmanager.h
+ACTION_MANAGERS_CC=layeractionmanager.cpp keyframeactionmanager.cpp groupactionmanager.cpp
+
+OTHER_HH=statemanager.h module.h ipc.h asyncrenderer.h smach.h duckmatic.h canvasoptions.h render.h app.h instance.h canvasview.h about.h iconcontroler.h toolbox.h workarea.h canvasproperties.h renddesc.h zoomdial.h eventkey.h onemoment.h devicetracker.h dialogsettings.h autorecover.h keymapsettings.h preview.h audiocontainer.h adjust_window.h valuelink.h
+OTHER_CC=statemanager.cpp module.cpp ipc.cpp asyncrenderer.cpp duckmatic.cpp main.cpp canvasoptions.cpp render.cpp app.cpp instance.cpp canvasview.cpp about.cpp iconcontroler.cpp toolbox.cpp workarea.cpp canvasproperties.cpp renddesc.cpp zoomdial.cpp onemoment.cpp devicetracker.cpp dialogsettings.cpp autorecover.cpp keymapsettings.cpp preview.cpp audiocontainer.cpp adjust_window.cpp valuelink.cpp
+
+INCLUDES=-I$(top_srcdir)/src
+
+bin_PROGRAMS   =       sinfgstudio
+sinfgstudio_SOURCES = $(MOD_MIRROR_CC) $(MOD_MIRROR_HH) $(PALETTE_CC) $(PALETTE_HH) $(WORKAREARENDERER_CC) $(WORKAREARENDERER_HH) $(ACTION_MANAGERS_HH) $(ACTION_MANAGERS_CC) $(DOCK_HH) $(DOCK_CC) $(OTHER_HH) $(OTHER_CC) $(EVENTS_HH) $(EVENTS_CC) $(DUCKTRANSFORM_HH) $(DUCKTRANSFORM_CC) $(TREEVIEW_HH) $(TREEVIEW_CC) $(TREESTORE_HH) $(TREESTORE_CC) $(STATE_CC) $(STATE_HH) $(WIDGET_CC) $(WIDGET_HH) $(DIALOG_HH) $(DIALOG_CC) $(CELLRENDERER_HH) $(CELLRENDERER_CC) 
+sinfgstudio_LDADD = -L../sinfgapp -lsinfgapp @SINFG_LIBS@ @GTKMM_LIBS@ @FMOD_LIBS@
+sinfgstudio_LDFLAGS=-dlopen self
+sinfgstudio_CXXFLAGS=@SINFG_CFLAGS@ @GTKMM_CFLAGS@
diff --git a/synfig-studio/trunk/src/gtkmm/about.cpp b/synfig-studio/trunk/src/gtkmm/about.cpp
new file mode 100644 (file)
index 0000000..819ed63
--- /dev/null
@@ -0,0 +1,289 @@
+/*! ========================================================================
+** Sinfg
+** Template File
+** $Id: about.cpp,v 1.2 2005/01/13 21:11:16 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include <ETL/stringf>
+
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+#include <gtkmm/fixed.h>
+
+#include <sinfg/general.h>
+
+#include "about.h"
+#include "app.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef VERSION
+#define VERSION        "unknown"
+#define PACKAGE        "sinfgstudio"
+#endif
+
+#ifdef WIN32
+#      ifdef IMAGE_DIR
+#              undef IMAGE_DIR
+#              define IMAGE_DIR "share\\pixmaps"
+#      endif
+#endif
+
+#ifndef IMAGE_DIR
+#      define IMAGE_DIR "/usr/local/share/pixmaps"
+#endif
+
+#ifndef IMAGE_EXT
+#      define IMAGE_EXT        "png"
+#endif
+
+/* === G L O B A L S ======================================================= */
+extern      const guint gtk_major_version;
+extern      const guint gtk_minor_version;
+extern      const guint gtk_micro_version;
+extern      const guint gtk_binary_age;
+extern      const guint gtk_interface_age;
+
+/* === P R O C E D U R E S ================================================= */
+
+class studio::AboutProgress : public sinfg::ProgressCallback
+{
+       About &about;
+       
+public:
+
+       AboutProgress(About &about):about(about) { }
+       
+       virtual bool task(const std::string &task)
+       {
+               if(about.tasklabel)
+               {
+                       about.tasklabel->set_label(task);
+                       about.tasklabel->show();
+               }
+               else
+               {
+                       cerr<<task<<endl;
+               }
+
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+
+       virtual bool error(const std::string &task)
+       {
+               if(about.tasklabel)
+               {
+                       about.tasklabel->set_label(_("ERROR:")+task);
+                       about.tasklabel->show();
+               }
+               else
+               {
+                       cerr<<task<<endl;
+               }
+
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+
+       virtual bool warning(const std::string &task)
+       {
+               if(about.tasklabel)
+               {
+                       about.tasklabel->set_label(_("WARNING:")+task);
+                       about.tasklabel->show();
+               }
+               else
+               {
+                       cerr<<task<<endl;
+               }
+
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+
+       virtual bool amount_complete(int current, int total)
+       {
+               if(about.progressbar)
+               {
+                       about.progressbar->set_fraction((float)current/(float)total);
+                       about.progressbar->show();
+               }
+               else
+                       cerr<<current<<'/'<<total<<endl;
+
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+}; // END of class AboutProgress
+
+/* === M E T H O D S ======================================================= */
+
+About::About():
+       Gtk::Window(Gtk::WINDOW_POPUP),
+       can_self_destruct(true)
+{
+       int image_w=300,image_h=350;
+
+       std::string imagepath;
+#ifdef WIN32
+       imagepath=App::get_base_path()+ETL_DIRECTORY_SEPERATOR+IMAGE_DIR;
+#else
+       imagepath=IMAGE_DIR;
+#endif
+       imagepath+=ETL_DIRECTORY_SEPERATOR;
+       
+       
+       // Create the Logo
+       Gtk::Image *Logo = manage(new class Gtk::Image());
+       Logo->set(imagepath+"about_dialog."IMAGE_EXT);
+       Logo->set_size_request(image_w,image_h);
+       Logo->set_alignment(0.5,0.5);
+       Logo->set_padding(0,0);
+       
+       // Create the Copyright Label
+       Gtk::Label *CopyrightLabel = manage(new class Gtk::Label(SINFG_COPYRIGHT));
+       CopyrightLabel->set_size_request(image_w,24);
+       CopyrightLabel->set_alignment(0.5,0.5);
+       CopyrightLabel->set_padding(0,0);
+       CopyrightLabel->set_justify(Gtk::JUSTIFY_CENTER);
+       CopyrightLabel->set_line_wrap(false);
+
+       // Create the Version information label
+       Gtk::Label *VersionLabel = manage(new class Gtk::Label("Version"));
+       VersionLabel->set_size_request(image_w,80);
+       VersionLabel->set_flags(Gtk::CAN_FOCUS);
+       VersionLabel->set_alignment(0.5,0.5);
+       VersionLabel->set_padding(0,0);
+       VersionLabel->set_justify(Gtk::JUSTIFY_CENTER);
+       VersionLabel->set_line_wrap(false);
+       
+       // Set the version label to contain the correct information
+       string ver;
+       ver+="Version "VERSION" ("__DATE__" "__TIME__")\n";
+       ver+="Using SINFG ";
+       ver+=sinfg::get_version();
+       #ifdef __GNUC__
+               ver+=strprintf(" and GNU G++ %d.%d.%d",__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
+       #endif
+
+       ver+=strprintf("\nGtk+ %d.%d.%d",gtk_major_version,gtk_minor_version,gtk_micro_version);
+
+       #ifdef _DEBUG
+               ver+="\nDEBUG BUILD";
+       #endif
+       VersionLabel->set_text(ver);
+
+       // Create the image that will be used on the close button
+       Gtk::Image *image2 = manage(new class Gtk::Image(Gtk::StockID("gtk-close"), Gtk::IconSize(4)));
+       image2->set_alignment(0.5,0.5);
+       image2->set_padding(0,0);
+       
+       // Create the close button, and attach the image to it
+       CloseButton = manage(new class Gtk::Button());
+       CloseButton->set_size_request(24,24);
+       CloseButton->set_flags(Gtk::CAN_FOCUS);
+       _tooltips.set_tip(*CloseButton, "Close", "");
+       CloseButton->set_relief(Gtk::RELIEF_NONE);
+       CloseButton->add(*image2);
+
+       // Create the progress bar
+       progressbar = manage(new class Gtk::ProgressBar());
+       progressbar->set_size_request(image_w,24);
+
+       // Create the current task label
+       tasklabel = manage(new class Gtk::Label());
+       tasklabel->set_size_request(image_w,24);
+       tasklabel->set_use_underline(false);
+       
+       // Create the Gtk::Fixed container and put all of the widgets into it
+       Gtk::Fixed *fixed1 = manage(new class Gtk::Fixed());
+       fixed1->put(*Logo, 0, 0);
+       fixed1->put(*CopyrightLabel, 0, image_h-25);
+       fixed1->put(*CloseButton, image_w-24, 0);
+       fixed1->put(*VersionLabel, 0, image_h-90);
+       fixed1->put(*progressbar, 0, image_h+24);
+       fixed1->put(*tasklabel, 0, image_h);
+
+       // Set up the parameters for this pop-up window
+       set_title("Sinfg Studio "VERSION);
+       set_modal(false);
+       property_window_position().set_value(Gtk::WIN_POS_CENTER);
+       set_resizable(false);
+       add(*fixed1);
+
+       // show everything off
+       Logo->show();
+       CopyrightLabel->show();
+       image2->show();
+       CloseButton->show();
+       VersionLabel->show();
+       fixed1->show();
+
+       // Connect relevant signals
+       CloseButton->signal_clicked().connect(sigc::mem_fun(*this, &About::close));
+
+       cb=new AboutProgress(*this);
+}
+
+About::~About()
+{
+       delete cb;
+}
+
+void About::close()
+{
+       hide();
+       if(can_self_destruct)
+               delete this;
+}
+
+void
+About::set_can_self_destruct(bool x)
+{
+       can_self_destruct=x;
+       if(x==true)
+               CloseButton->show();
+       else
+               CloseButton->hide();            
+}
+
+sinfg::ProgressCallback *
+About::get_callback()
+{
+       return cb;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/about.h b/synfig-studio/trunk/src/gtkmm/about.h
new file mode 100644 (file)
index 0000000..1766bfd
--- /dev/null
@@ -0,0 +1,77 @@
+/*! ========================================================================
+** Sinfg
+** Template Header File
+** $Id: about.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_ABOUT_H
+#define __SINFG_GTKMM_ABOUT_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include <gtk/gtk.h>
+#include <gtkmm/window.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+#include <gtkmm/button.h>
+#include <gtkmm/progressbar.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class ProgressCallback; };
+
+namespace studio {
+
+class AboutProgress;
+       
+class About : public Gtk::Window
+{
+       friend class AboutProgress;
+       
+       AboutProgress *cb;
+       
+       Gtk::Tooltips _tooltips;
+
+       Gtk::Label *tasklabel;
+       Gtk::ProgressBar *progressbar;
+       Gtk::Button *CloseButton;
+
+       void close();
+
+       bool can_self_destruct;
+       
+public:
+       
+       sinfg::ProgressCallback *get_callback();        
+
+       void set_can_self_destruct(bool x);
+
+       About();
+       ~About();
+};
+
+}
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/adjust_window.cpp b/synfig-studio/trunk/src/gtkmm/adjust_window.cpp
new file mode 100644 (file)
index 0000000..90ca220
--- /dev/null
@@ -0,0 +1,166 @@
+/* === S I N F G =========================================================== */
+/*!    \file adjust_window.cpp
+**     \brief Adjustment Window Implementation File
+**
+**     $Id: adjust_window.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "adjust_window.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+//using namespace sinfg;
+
+using studio::Adjust_Window;
+
+/* === M A C R O S ========================================================= */
+const double EPSILON = 1.0e-6;
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Adjust_Window::Adjust_Window(double value, double lower, double upper,
+                                                       double stepinc, double pageinc, double pagesize,
+                                                       Gtk::Adjustment *adj)
+: Adjustment(value,lower,upper,stepinc,pageinc,pagesize),
+       adj_child(0)
+{
+       if(adj) set_child_adjustment(adj);
+}
+
+Adjust_Window::~Adjust_Window()
+{
+       //connections should automatically be killed etc.
+}
+
+//child interface functions
+Gtk::Adjustment *Adjust_Window::get_child_adjustment()
+{
+       return adj_child;
+}
+
+const Gtk::Adjustment *Adjust_Window::get_child_adjustment() const
+{
+       return adj_child;
+}
+
+void Adjust_Window::set_child_adjustment(Gtk::Adjustment *child)
+{
+       childchanged.disconnect();
+       
+       adj_child = child;
+       
+       sinfg::info("Adjust: connecting to child signals");
+       if(child)
+       {
+               childchanged = child->signal_changed().connect(sigc::mem_fun(*this,&Adjust_Window::update_fromchild));
+               
+               update_child();
+       }
+}
+
+void Adjust_Window::on_changed()
+{
+       update_child();
+}
+
+void Adjust_Window::on_value_changed()
+{
+       update_child();
+}
+
+//SUB TIME FUNCTIONS
+double Adjust_Window::get_sub_lower() const
+{
+       return get_value();
+}
+
+double Adjust_Window::get_sub_upper() const
+{
+       return get_value() + get_page_size();
+}
+
+//---- REFRESH FUNCTIONS -----
+void Adjust_Window::update_child()
+{
+       if(adj_child)
+       {
+               bool childchanged = false;
+               
+               double v = get_value();
+               double ve = v + get_page_size();
+               
+               //reset child's values if they need to be...
+               if(abs(v - adj_child->get_lower()) > EPSILON)
+               {
+                       adj_child->set_lower(v);
+                       childchanged = true;
+               }
+               
+               if(abs(ve - adj_child->get_upper()) > EPSILON)
+               {
+                       adj_child->set_upper(ve);
+                       childchanged = true;                                                                    
+               }
+               
+               if(childchanged)
+               {
+                       adj_child->changed();
+               }
+       }
+}
+
+void Adjust_Window::update_fromchild()
+{
+       if(adj_child)
+       {               
+               double b = adj_child->get_lower();
+               double dist = adj_child->get_upper() - b;
+               
+               //reset our values if they need to be...
+               if(abs(get_value() - b) > EPSILON)
+               {
+                       set_value(b);
+                       value_changed();
+               }
+               
+               if(abs(get_page_size() - dist) > EPSILON)
+               {
+                       set_page_size(dist);
+                       changed();
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/adjust_window.h b/synfig-studio/trunk/src/gtkmm/adjust_window.h
new file mode 100644 (file)
index 0000000..5cbf4a4
--- /dev/null
@@ -0,0 +1,93 @@
+/* === S I N F G =========================================================== */
+/*!    \file adjust_window.h
+**     \brief Adjustment Window Header
+**
+**     $Id: adjust_window.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_TEMPLATE_H
+#define __SINFG_TEMPLATE_H
+
+/* === H E A D E R S ======================================================= */
+#include <gtkmm/adjustment.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+/* Sets up an adjustment that controls/communicates with another adjustment
+       (could be expanded to multiple children)
+       
+       The current value and pagesize define the lower and upper bounds of the
+       child adjustment.
+       
+       NEED TO REPLACE FUNCTIONALITY IN:
+       refresh_rend_desc
+       refresh_time_window
+       on_time_changed - possibly....
+       
+       time_zoom_in - possibly...
+       time_zoom_out - possibly...
+       
+       play - possibly...
+       
+       THINGS TO CHECK:
+       disp_audio's use of time_adjustment
+       children_tree's use of time_adjustment
+       layer_tree's use of time_adjustment
+*/
+class Adjust_Window : public Gtk::Adjustment
+{
+       Gtk::Adjustment *adj_child;
+       
+       sigc::connection childchanged; //we only care about the non-value parts of the child
+       
+       virtual void on_changed(); //value+pagesize corresponds to child upper
+       virtual void on_value_changed(); //value corresponds to child lower
+
+protected: //update interface
+       virtual void update_child();
+       virtual void update_fromchild();
+       
+public: //structors
+       Adjust_Window(double value, double lower, double upper, 
+                                       double step_increment=1, double page_increment=10, double page_size=0,
+                                       Gtk::Adjustment *adj = 0);
+
+       virtual ~Adjust_Window();
+
+public: //child interface
+       Gtk::Adjustment *get_child_adjustment();
+       const Gtk::Adjustment *get_child_adjustment() const;
+       void set_child_adjustment(Gtk::Adjustment *child);
+
+public: //Sub value interface
+       double get_sub_lower() const;
+       double get_sub_upper() const;
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp
new file mode 100644 (file)
index 0000000..b63b37d
--- /dev/null
@@ -0,0 +1,2084 @@
+/* === S I N F G =========================================================== */
+/*!    \file app.cpp
+**     \brief writeme
+**
+**     $Id: app.cpp,v 1.10 2005/01/17 06:31:12 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <fstream>
+#include <iostream>
+
+#include <gtkmm/fileselection.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/label.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/stockitem.h>
+#include <gtkmm/iconsource.h>
+#include <gtkmm/inputdialog.h>
+#include <gtkmm/accelmap.h>
+#include <gtkmm/uimanager.h>
+
+#include <gtk/gtk.h>
+
+#include <sinfg/loadcanvas.h>
+
+#include "app.h"
+#include "about.h"
+#include "instance.h"
+#include "canvasview.h"
+#include "dialog_setup.h"
+#include "dialog_gradient.h"
+#include "dialog_color.h"
+#include "toolbox.h"
+#include "compview.h"
+#include "onemoment.h"
+
+#include "dockmanager.h"
+
+#include "state_eyedrop.h"
+#include "state_normal.h"
+#include "state_draw.h"
+#include "state_fill.h"
+#include "state_bline.h"
+#include "state_polygon.h"
+#include "state_sketch.h"
+#include "state_gradient.h"
+#include "state_circle.h"
+#include "state_rectangle.h"
+#include "state_smoothmove.h"
+#include "state_scale.h"
+#include "state_width.h"
+#include "state_rotate.h"
+#include "state_zoom.h"
+
+#include "devicetracker.h"
+#include "dialog_tooloptions.h"
+
+#include "autorecover.h"
+
+#include <sinfgapp/settings.h>
+#include "dock_history.h"
+#include "dock_canvases.h"
+#include "dock_keyframes.h"
+#include "dock_layers.h"
+#include "dock_params.h"
+#include "dock_metadata.h"
+#include "dock_children.h"
+#include "dock_info.h"
+#include "dock_navigator.h"
+#include "dock_layergroups.h"
+#include "dock_timetrack.h"
+#include "dock_curves.h"
+
+#include "mod_palette/mod_palette.h"
+#include "mod_mirror/mod_mirror.h"
+
+#include <sys/stat.h>
+
+#include "ipc.h"
+
+#include "module.h"
+
+#include "statemanager.h"
+
+#ifdef WITH_FMOD
+#include <fmod.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <gtkmm/accelmap.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef DPM2DPI
+#define DPM2DPI(x)     (float(x)/39.3700787402f)
+#define DPI2DPM(x)     (float(x)*39.3700787402f)
+#endif
+
+#ifdef WIN32
+#      ifdef IMAGE_DIR
+#              undef IMAGE_DIR
+#              define IMAGE_DIR "share\\pixmaps"
+#      endif
+#endif
+
+#ifndef IMAGE_DIR
+#      define IMAGE_DIR "/usr/local/share/pixmaps"
+#endif
+
+#ifndef IMAGE_EXT
+#      define IMAGE_EXT        "tif"
+#endif
+
+#include <sinfgapp/main.h>
+
+/* === S I G N A L S ======================================================= */
+
+static sigc::signal<void> signal_present_all_;
+sigc::signal<void>&
+App::signal_present_all() { return signal_present_all_; }
+
+static sigc::signal<void> signal_recent_files_changed_;
+sigc::signal<void>&
+App::signal_recent_files_changed() { return signal_recent_files_changed_; }
+
+static sigc::signal<void,etl::loose_handle<CanvasView> > signal_canvas_view_focus_;
+sigc::signal<void,etl::loose_handle<CanvasView> >&
+App::signal_canvas_view_focus() { return signal_canvas_view_focus_; }
+
+static sigc::signal<void,etl::handle<Instance> > signal_instance_selected_;
+sigc::signal<void,etl::handle<Instance> >&
+App::signal_instance_selected() { return signal_instance_selected_; }
+
+static sigc::signal<void,etl::handle<Instance> > signal_instance_created_;
+sigc::signal<void,etl::handle<Instance> >&
+App::signal_instance_created() { return signal_instance_created_; }
+
+static sigc::signal<void,etl::handle<Instance> > signal_instance_deleted_;
+sigc::signal<void,etl::handle<Instance> >&
+App::signal_instance_deleted() { return signal_instance_deleted_; }
+
+/* === G L O B A L S ======================================================= */
+
+static std::list<std::string> recent_files;
+const std::list<std::string>& App::get_recent_files() { return recent_files; }
+
+int    App::Busy::count;
+bool App::shutdown_in_progress;
+
+sinfg::Gamma App::gamma;
+
+Glib::RefPtr<studio::UIManager>        App::ui_manager_;
+
+sinfg::Distance::System App::distance_system;
+
+studio::Dialog_Setup* App::dialog_setup;
+
+etl::handle< studio::ModPalette > mod_palette_;
+//studio::Dialog_Palette* App::dialog_palette;
+
+std::list<etl::handle<Instance> > App::instance_list;
+
+static etl::handle<sinfgapp::UIInterface> ui_interface_;
+const etl::handle<sinfgapp::UIInterface>& App::get_ui_interface() { return ui_interface_; }
+
+etl::handle<Instance> App::selected_instance;
+etl::handle<CanvasView> App::selected_canvas_view;
+
+studio::Toolbox *studio::App::toolbox=NULL;
+
+studio::AutoRecover *studio::App::auto_recover=NULL;
+
+studio::IPC *ipc=NULL;
+
+studio::DockManager* studio::App::dock_manager=0;
+
+studio::DeviceTracker* studio::App::device_tracker=0;
+
+studio::Dialog_Gradient* studio::App::dialog_gradient;
+
+studio::Dialog_Color* studio::App::dialog_color;
+
+Gtk::InputDialog* studio::App::dialog_input;
+
+studio::Dialog_ToolOptions* studio::App::dialog_tool_options;
+
+studio::Dock_History* dock_history;
+studio::Dock_Canvases* dock_canvases;
+studio::Dock_Keyframes* dock_keyframes;
+studio::Dock_Layers* dock_layers;
+studio::Dock_Params* dock_params;
+studio::Dock_MetaData* dock_meta_data;
+studio::Dock_Children* dock_children;
+studio::Dock_Info* dock_info;
+studio::Dock_LayerGroups* dock_layer_groups;
+studio::Dock_Navigator* dock_navigator;
+studio::Dock_Timetrack* dock_timetrack;
+studio::Dock_Curves* dock_curves;
+
+std::list< etl::handle< studio::Module > > module_list_;
+
+bool studio::App::use_colorspace_gamma=true;
+
+static int max_recent_files_=25;
+int studio::App::get_max_recent_files() { return max_recent_files_; }
+void studio::App::set_max_recent_files(int x) { max_recent_files_=x; }
+
+static sinfg::String app_base_path_;
+
+namespace studio {
+}; // END of namespace studio
+studio::StateManager* state_manager;
+
+
+
+
+class GlobalUIInterface : public sinfgapp::UIInterface
+{
+public:
+
+       virtual Response yes_no(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
+       {
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
+               dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+       virtual Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
+       {
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
+               dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
+               dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+       virtual Response ok_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_OK)
+       {
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
+               dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+
+       virtual bool
+       task(const std::string &task)
+       {
+               std::cerr<<task<<std::endl;
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+
+       virtual bool
+       error(const std::string &err)
+       {               
+               Gtk::Dialog dialog(
+                       "Error",                // Title
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(err);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
+               dialog.show();
+               dialog.run();
+               return true;
+       }
+
+       virtual bool
+       warning(const std::string &err)
+       {
+               std::cerr<<"warning: "<<err<<std::endl;
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+
+       virtual bool
+       amount_complete(int current, int total)
+       {
+               while(studio::App::events_pending())studio::App::iteration(false);
+               return true;
+       }
+};
+
+/* === P R O C E D U R E S ================================================= */
+
+typedef unsigned char U8;
+typedef unsigned short U16;
+typedef unsigned long U32;
+
+typedef union {
+       struct {
+               U32 serial;
+               U32 checksum;
+       } element;
+       U8      raw[8];
+} V_KeyUnwound;
+
+static inline U32 hash_U32(U32 i)
+{
+       i=i*1664525+1013904223;
+       i=i*1664525+1013904223;
+       i=i*1664525+1013904223;
+       return i;
+}
+
+inline int v_unwind_key(V_KeyUnwound* unwound, const char* key)
+{
+       int i;
+       unwound->element.serial=0;
+       unwound->element.checksum=0;
+       
+       for(i=0;i<16;i++)
+       {
+               U8 data;
+               
+               switch(key[i])
+               {
+                       case '0': data=0; break;
+                       case '1': data=1; break;
+                       case '2': data=2; break;
+                       case '3': data=3; break;
+                       case '4': data=4; break;
+                       case '5': data=5; break;
+                       case '6': data=6; break;
+                       case '7': data=7; break;
+                       case '8': data=8; break;
+                       case '9': data=9; break;
+                       case 'a': case 'A':  data=10; break;
+                       case 'b': case 'B':  data=11; break;
+                       case 'c': case 'C':  data=12; break;
+                       case 'd': case 'D':  data=13; break;
+                       case 'e': case 'E':  data=14; break;
+                       case 'f': case 'F':  data=15; break;
+                       default: return 0; break;
+               }
+               int bit=i*2;
+               unwound->element.checksum|=(((U32)data&3)<<bit);
+               unwound->element.serial|=(((U32)(data>>2)&3)<<bit);
+       }
+       return 1;
+}
+
+inline int v_key_check(const char* key, U32* serial, U32 appid)
+{
+       V_KeyUnwound unwound_key;
+       U32 appid_mask_a=hash_U32(appid);
+       U32 appid_mask_b=hash_U32(appid_mask_a);
+       
+       if(!v_unwind_key(&unwound_key, key))
+       {
+               // Invalid characters in key
+               return 0;
+       }
+       
+
+       // Undo obfuscation pass
+       {
+               U32 next=hash_U32(unwound_key.raw[7]);
+               int i;
+               for(i=0;i<7;i++)
+               {
+                       next=hash_U32(next);
+                       unwound_key.raw[i]^=(next>>24);
+               }
+       }
+       
+       unwound_key.element.serial^=appid_mask_a;
+       unwound_key.element.checksum^=appid_mask_b;
+
+       *serial=unwound_key.element.serial;
+       
+       return unwound_key.element.checksum==hash_U32(unwound_key.element.serial);
+}
+
+
+int check_license(String basedir)
+{
+       String key;
+       String license_file;
+
+#ifndef _WIN32
+       license_file="/usr/local/etc/.synfiglicense";
+#else
+       license_file=basedir+"\\etc\\.synfiglicense";
+#endif         
+       
+       try {
+               key=Glib::file_get_contents(license_file);
+       } catch (Glib::FileError) { }
+       U32 serial(0);
+       if(!v_key_check(key.c_str(),&serial,0xdeadbeef))
+       {
+               while(!v_key_check(key.c_str(),&serial,0xdeadbeef))
+               {
+                       key.clear();
+                       
+                       if(!App::dialog_entry(
+                               _("Synfig Studio Authentication"),
+                               _("Please enter your license key below. You will not\nbe able to use this software without a valid license key."),
+                               key
+                       ))
+                               throw String("No License");
+               }
+               
+               FILE* file=fopen(license_file.c_str(),"w");
+               if(file)
+               {
+                       fprintf(file,"%s",key.c_str());
+                       fclose(file);
+               }
+               else
+                       sinfg::error("Unable to save license key!");
+       }
+       sinfg::info("License Authenticated -- Serial #%05d",serial);
+       return serial;
+}
+
+/*
+void
+studio::UIManager::insert_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group, int pos)
+{
+       action_group_list.push_back(action_group);
+       Gtk::UIManager::insert_action_group(action_group, pos);
+}
+
+void
+studio::UIManager::remove_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group)
+{
+       std::list<Glib::RefPtr<Gtk::ActionGroup> >::iterator iter;
+       for(iter=action_group_list.begin();iter!=action_group_list.end();++iter)
+               if(*iter==action_group)
+               {
+                       action_group_list.erase(iter);
+                       Gtk::UIManager::remove_action_group(action_group);
+                       return;
+               }
+       sinfg::error("Unable to find action group");
+}
+
+void
+studio::add_action_group_to_top(Glib::RefPtr<studio::UIManager> ui_manager, Glib::RefPtr<Gtk::ActionGroup> group)
+{
+       ui_manager->insert_action_group(group,0);
+       return;
+       DEBUGPOINT();
+       std::list<Glib::RefPtr<Gtk::ActionGroup> > prev_groups(ui_manager->get_action_groups());
+       std::list<Glib::RefPtr<Gtk::ActionGroup> >::reverse_iterator iter;
+       
+       DEBUGPOINT();
+       for(iter=prev_groups.rbegin();iter!=prev_groups.rend();++iter)
+       {
+               DEBUGPOINT();
+               if(*iter && (*iter)->get_name()!="menus")
+               {
+                       sinfg::info("Removing action group "+(*iter)->get_name());
+                       ui_manager->remove_action_group(*iter);
+               }
+       }
+       DEBUGPOINT();
+       ui_manager->insert_action_group(group,0);
+       
+       DEBUGPOINT();
+       for(;!prev_groups.empty();prev_groups.pop_front())
+       {
+               if(prev_groups.front() && prev_groups.front()!=group && prev_groups.front()->get_name()!="menus")
+                       ui_manager->insert_action_group(prev_groups.front(),1);
+       }
+       DEBUGPOINT();
+}
+*/
+class Preferences : public sinfgapp::Settings
+{
+public:
+       virtual bool get_value(const sinfg::String& key, sinfg::String& value)const
+       {
+               if(key=="gamma")
+               {
+                       value=strprintf("%f %f %f %f",
+                               App::gamma.get_gamma_r(),
+                               App::gamma.get_gamma_g(),
+                               App::gamma.get_gamma_b(),
+                               App::gamma.get_black_level()
+                       );
+                       return true;
+               }
+               if(key=="time_format")
+               {
+                       value=strprintf("%i",App::get_time_format());
+                       return true;
+               }
+               if(key=="file_history.size")
+               {
+                       value=strprintf("%i",App::get_max_recent_files());
+                       return true;
+               }
+               if(key=="use_colorspace_gamma")
+               {
+                       value=strprintf("%i",(int)App::use_colorspace_gamma);
+                       return true;
+               }
+               if(key=="distance_system")
+               {
+                       value=strprintf("%s",Distance::system_name(App::distance_system).c_str());
+                       return true;
+               }
+               if(key=="auto_recover_backup_interval")
+               {
+                       value=strprintf("%i",App::auto_recover->get_timeout());
+                       return true;
+               }
+               
+               return sinfgapp::Settings::get_value(key,value);
+       }
+       
+       virtual bool set_value(const sinfg::String& key,const sinfg::String& value)
+       {
+               if(key=="gamma")
+               {
+                       float r,g,b,blk;
+                       
+                       strscanf(value,"%f %f %f %f",
+                               &r,
+                               &g,
+                               &b,
+                               &blk
+                       );
+
+                       App::gamma.set_all(r,g,b,blk);
+                       
+                       return true;
+               }
+               if(key=="time_format")
+               {
+                       int i(atoi(value.c_str()));
+                       App::set_time_format(static_cast<sinfg::Time::Format>(i));
+                       return true;
+               }
+               if(key=="auto_recover_backup_interval")
+               {
+                       int i(atoi(value.c_str()));
+                       App::auto_recover->set_timeout(i);
+                       return true;
+               }
+               if(key=="file_history.size")
+               {
+                       int i(atoi(value.c_str()));
+                       App::set_max_recent_files(i);
+                       return true;
+               }
+               if(key=="use_colorspace_gamma")
+               {
+                       int i(atoi(value.c_str()));
+                       App::use_colorspace_gamma=i;
+                       return true;
+               }
+               if(key=="distance_system")
+               {
+                       App::distance_system=Distance::ident_system(value);;
+                       return true;
+               }
+               
+               return sinfgapp::Settings::set_value(key,value);
+       }
+       
+       virtual KeyList get_key_list()const
+       {
+               KeyList ret(sinfgapp::Settings::get_key_list());
+               ret.push_back("gamma");
+               ret.push_back("time_format");
+               ret.push_back("distance_system");
+               ret.push_back("file_history.size");
+               ret.push_back("use_colorspace_gamma");
+               ret.push_back("auto_recover_backup_interval");
+               return ret;
+       }
+};
+
+static Preferences _preferences;
+
+void
+init_ui_manager()
+{
+       Glib::RefPtr<Gtk::ActionGroup> menus_action_group = Gtk::ActionGroup::create("menus");
+
+       Glib::RefPtr<Gtk::ActionGroup> toolbox_action_group = Gtk::ActionGroup::create("toolbox");
+
+       Glib::RefPtr<Gtk::ActionGroup> actions_action_group = Gtk::ActionGroup::create();
+       
+       menus_action_group->add( Gtk::Action::create("menu-file", "_File") );
+       menus_action_group->add( Gtk::Action::create("menu-edit", "_Edit") );
+       menus_action_group->add( Gtk::Action::create("menu-view", "_View") );
+       menus_action_group->add( Gtk::Action::create("menu-canvas", "_Canvas") );
+       menus_action_group->add( Gtk::Action::create("menu-layer", "_Layer") );
+       menus_action_group->add( Gtk::Action::create("menu-duck-mask", "Mask Ducks") );
+       menus_action_group->add( Gtk::Action::create("menu-preview-quality", "Preview Quality") );
+       menus_action_group->add( Gtk::Action::create("menu-layer-new", "New Layer") );
+       menus_action_group->add( Gtk::Action::create("menu-keyframe", "Keyframe") );
+       menus_action_group->add( Gtk::Action::create("menu-group", "Group") );
+       menus_action_group->add( Gtk::Action::create("menu-state", "State") );
+       menus_action_group->add( Gtk::Action::create("menu-toolbox", "Toolbox") );
+
+       // Add the sinfgapp actions...
+       sinfgapp::Action::Book::iterator iter;
+       for(iter=sinfgapp::Action::book().begin();iter!=sinfgapp::Action::book().end();++iter)
+       {
+               actions_action_group->add(Gtk::Action::create(
+                       "action-"+iter->second.name,
+                       get_action_stock_id(iter->second),
+                       iter->second.local_name,iter->second.local_name
+               ));
+       }
+       
+#define DEFINE_ACTION(x,stock) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
+#define DEFINE_ACTION2(x,stock,label) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock,label,label) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
+#define DEFINE_ACTION_SIG(group,x,stock,sig) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ group->add(action,sig); }
+
+       DEFINE_ACTION2("keyframe-properties", Gtk::StockID("gtk-properties"), _("Keyframe Properties"));
+       DEFINE_ACTION("about", Gtk::StockID("sinfg-about"));
+       DEFINE_ACTION("open", Gtk::Stock::OPEN);
+       DEFINE_ACTION("save", Gtk::Stock::SAVE);
+       DEFINE_ACTION("save-as", Gtk::Stock::SAVE_AS);
+       DEFINE_ACTION("revert", Gtk::Stock::REVERT_TO_SAVED);
+       DEFINE_ACTION("cvs-add", Gtk::StockID("sinfg-cvs_add"));
+       DEFINE_ACTION("cvs-update", Gtk::StockID("sinfg-cvs_update"));
+       DEFINE_ACTION("cvs-commit", Gtk::StockID("sinfg-cvs_commit"));
+       DEFINE_ACTION("cvs-revert", Gtk::StockID("sinfg-cvs_revert"));
+       DEFINE_ACTION("import", _("Import"));
+       DEFINE_ACTION("render", _("Render"));
+       DEFINE_ACTION("preview", _("Preview"));
+       DEFINE_ACTION("dialog-flipbook", _("Preview Dialog"));
+       DEFINE_ACTION("sound", _("Sound File"));
+       DEFINE_ACTION("options", _("Options"));
+       DEFINE_ACTION("close", _("Close"));
+
+
+       DEFINE_ACTION("undo", Gtk::StockID("gtk-undo"));
+       DEFINE_ACTION("redo", Gtk::StockID("gtk-redo"));
+       DEFINE_ACTION("cut", Gtk::StockID("gtk-cut"));
+       DEFINE_ACTION("copy", Gtk::StockID("gtk-copy"));
+       DEFINE_ACTION("paste", Gtk::StockID("gtk-paste"));
+       DEFINE_ACTION("select-all-ducks", _("Select All Ducks"));
+       DEFINE_ACTION("unselect-all-layers", _("Unselect All Layers"));
+       DEFINE_ACTION("properties", _("Properties"));
+
+       DEFINE_ACTION("mask-position-ducks", _("Mask Position Ducks"));
+       DEFINE_ACTION("mask-vertex-ducks", _("Mask Vertex Ducks"));
+       DEFINE_ACTION("mask-tangent-ducks", _("Mask Tangent Ducks"));
+       DEFINE_ACTION("mask-radius-ducks", _("Mask Radius Ducks"));
+       DEFINE_ACTION("mask-width-ducks", _("Mask Width Ducks"));
+       DEFINE_ACTION("mask-angle-ducks", _("Mask Angle Ducks"));
+       DEFINE_ACTION("quality-00", _("Use Parametric Renderer"));
+       DEFINE_ACTION("quality-01", _("Use Quality Level 1"));
+       DEFINE_ACTION("quality-02", _("Use Quality Level 2"));
+       DEFINE_ACTION("quality-03", _("Use Quality Level 3"));
+       DEFINE_ACTION("quality-04", _("Use Quality Level 4"));
+       DEFINE_ACTION("quality-05", _("Use Quality Level 5"));
+       DEFINE_ACTION("quality-06", _("Use Quality Level 6"));
+       DEFINE_ACTION("quality-07", _("Use Quality Level 7"));
+       DEFINE_ACTION("quality-08", _("Use Quality Level 8"));
+       DEFINE_ACTION("quality-09", _("Use Quality Level 9"));
+       DEFINE_ACTION("quality-10", _("Use Quality Level 10"));
+       DEFINE_ACTION("play", _("Play"));
+       DEFINE_ACTION("pause", _("Pause"));
+       DEFINE_ACTION("stop", _("Stop"));
+       DEFINE_ACTION("toggle-grid-show", _("Toggle Grid Show"));
+       DEFINE_ACTION("toggle-grid-snap", _("Toggle Grid Snap"));
+       DEFINE_ACTION("toggle-guide-show", _("Toggle Guide Show"));
+       DEFINE_ACTION("toggle-low-res", _("Toggle Low-Res"));
+       DEFINE_ACTION("toggle-onion-skin", _("Toggle Onion Skin"));
+       DEFINE_ACTION("canvas-zoom-in", Gtk::StockID("gtk-zoom-in"));
+       DEFINE_ACTION("canvas-zoom-out", Gtk::StockID("gtk-zoom-out"));
+       DEFINE_ACTION("canvas-zoom-fit", Gtk::StockID("gtk-zoom-fit"));
+       DEFINE_ACTION("canvas-zoom-100", Gtk::StockID("gtk-zoom-100"));
+       DEFINE_ACTION("time-zoom-in", Gtk::StockID("gtk-zoom-in"));
+       DEFINE_ACTION("time-zoom-out", Gtk::StockID("gtk-zoom-out"));
+       DEFINE_ACTION("jump-next-keyframe", _("Jump to Next Keyframe"));
+       DEFINE_ACTION("jump-prev-keyframe", _("Jump to Prev Keyframe"));
+       DEFINE_ACTION("seek-next-frame", _("Next Frame"));
+       DEFINE_ACTION("seek-prev-frame", _("Prev Frame"));
+       DEFINE_ACTION("seek-next-second", _("Seek Forward"));
+       DEFINE_ACTION("seek-prev-second", _("Seek Backward"));
+       DEFINE_ACTION("seek-begin", _("Seek to Begin"));
+       DEFINE_ACTION("seek-end", _("Seek to End"));
+
+       DEFINE_ACTION("action-group_add", _("Add group"));
+
+       DEFINE_ACTION("canvas-new", _("New Canvas"));
+
+       DEFINE_ACTION("amount-inc", _("Increase Amount"));
+       DEFINE_ACTION("amount-dec", _("Decrease Amount"));
+
+#undef DEFINE_ACTION
+
+
+// Set up sinfgapp actions
+       /*{
+               sinfgapp::Action::Book::iterator iter;
+       
+               for(iter=sinfgapp::Action::book().begin();iter!=sinfgapp::Action::book().end();++iter)
+               {
+                       Gtk::StockID stock_id;
+                       
+                       if(!(iter->second.category&sinfgapp::Action::CATEGORY_HIDDEN))
+                       {
+                               //Gtk::Image* image(manage(new Gtk::Image()));
+                               if(iter->second.task=="raise")                  stock_id=Gtk::Stock::GO_UP;
+                               else if(iter->second.task=="lower")             stock_id=Gtk::Stock::GO_DOWN;
+                               else if(iter->second.task=="move_top")  stock_id=Gtk::Stock::GOTO_TOP;
+                               else if(iter->second.task=="move_bottom")       stock_id=Gtk::Stock::GOTO_BOTTOM;
+                               else if(iter->second.task=="remove")    stock_id=Gtk::Stock::DELETE;
+                               else if(iter->second.task=="set_on")    stock_id=Gtk::Stock::YES;
+                               else if(iter->second.task=="set_off")   stock_id=Gtk::Stock::NO;
+                               //else if(iter->second.task=="duplicate")       stock_id=Gtk::Stock::COPY;
+                               else if(iter->second.task=="remove")    stock_id=Gtk::Stock::DELETE;
+                               else                                                                    stock_id=Gtk::StockID("sinfg-"+iter->second.task);
+       
+                               actions_action_group->add(Gtk::Action::create(
+                                       "action-"+iter->second.name,
+                                       stock_id,
+                                       iter->second.local_name,iter->second.local_name
+                               ));
+                       }
+               }
+       }
+*/
+
+
+    Glib::ustring ui_info =
+"<ui>"
+"      <popup name='menu-toolbox' action='menu-toolbox'>"
+"      <menu action='menu-file'>"
+"      </menu>"
+"      </popup>"
+"      <popup name='menu-main' action='menu-main'>"
+"      <menu action='menu-file'>"
+"              <menuitem action='save' />"
+"              <menuitem action='save-as' />"
+"              <menuitem action='revert' />"
+"              <separator name='bleh01'/>"
+"              <menuitem action='cvs-add' />"
+"              <menuitem action='cvs-update' />"
+"              <menuitem action='cvs-commit' />"
+"              <menuitem action='cvs-revert' />"
+"              <separator name='bleh02'/>"
+"              <menuitem action='import' />"
+"              <separator name='bleh03'/>"
+"              <menuitem action='render' />"
+"              <menuitem action='preview' />"
+"              <menuitem action='sound' />"
+"              <separator name='bleh04'/>"
+"              <menuitem action='options' />"
+"              <menuitem action='close' />"
+"      </menu>"
+"      <menu action='menu-edit'>"
+"              <menuitem action='undo'/>"
+"              <menuitem action='redo'/>"
+"              <separator name='bleh05'/>"
+"              <menuitem action='cut'/>"
+"              <menuitem action='copy'/>"
+"              <menuitem action='paste'/>"
+"              <separator name='bleh06'/>"
+"              <menuitem action='select-all-ducks'/>"
+"              <menuitem action='unselect-all-layers'/>"
+"              <separator name='bleh07'/>"
+"              <menuitem action='properties'/>"
+"      </menu>"
+"      <menu action='menu-view'>"
+"              <menu action='menu-duck-mask'>"
+"                      <menuitem action='mask-position-ducks' />"
+"                      <menuitem action='mask-vertex-ducks' />"
+"                      <menuitem action='mask-tangent-ducks' />"
+"                      <menuitem action='mask-radius-ducks' />"
+"                      <menuitem action='mask-width-ducks' />"
+"                      <menuitem action='mask-angle-ducks' />"
+"              </menu>"
+"              <menu action='menu-preview-quality'>"
+"                      <menuitem action='quality-00' />"
+"                      <menuitem action='quality-01' />"
+"                      <menuitem action='quality-02' />"
+"                      <menuitem action='quality-03' />"
+"                      <menuitem action='quality-04' />"
+"                      <menuitem action='quality-05' />"
+"                      <menuitem action='quality-06' />"
+"                      <menuitem action='quality-07' />"
+"                      <menuitem action='quality-08' />"
+"                      <menuitem action='quality-09' />"
+"                      <menuitem action='quality-10' />"
+"              </menu>"
+"              <separator name='bleh08'/>"
+"              <menuitem action='play'/>"
+"              <menuitem action='pause'/>"
+"              <menuitem action='stop'/>"
+"              <menuitem action='dialog-flipbook'/>"
+"              <separator name='bleh09'/>"
+"              <menuitem action='toggle-grid-show'/>"
+"              <menuitem action='toggle-grid-snap'/>"
+"              <menuitem action='toggle-guide-show'/>"
+"              <menuitem action='toggle-low-res'/>"
+"              <menuitem action='toggle-onion-skin'/>"
+"              <separator name='bleh10'/>"
+"              <menuitem action='canvas-zoom-in'/>"
+"              <menuitem action='canvas-zoom-out'/>"
+"              <menuitem action='canvas-zoom-fit'/>"
+"              <menuitem action='canvas-zoom-100'/>"
+"              <separator name='bleh11'/>"
+"              <menuitem action='time-zoom-in'/>"
+"              <menuitem action='time-zoom-out'/>"
+"              <separator name='bleh12'/>"
+"              <menuitem action='jump-next-keyframe'/>"
+"              <menuitem action='jump-prev-keyframe'/>"
+"              <menuitem action='seek-next-frame'/>"
+"              <menuitem action='seek-prev-frame'/>"
+"              <menuitem action='seek-next-second'/>"
+"              <menuitem action='seek-prev-second'/>"
+"              <menuitem action='seek-begin'/>"
+"              <menuitem action='seek-end'/>"
+"      </menu>"
+"      <menu action='menu-canvas'>"
+"              <menuitem action='canvas-new'/>"
+       "       <menuitem action='amount-inc'/>"
+       "       <menuitem action='amount-dec'/>"
+"      </menu>"
+"      <menu name='menu-state' action='menu-state'>"
+"      </menu>"
+"      <menu action='menu-group'>"
+"              <menuitem action='action-group_add'/>"
+"      </menu>"
+"      <menu action='menu-layer'>"
+//"            <menuitem action='cut'/>"
+//"            <menuitem action='copy'/>"
+//"            <menuitem action='paste'/>"
+//"            <separator name='bleh06'/>"
+"              <menu action='menu-layer-new'></menu>"
+"      </menu>"
+"      <menu action='menu-keyframe'>"
+"              <menuitem action='keyframe-properties'/>"
+"      </menu>"
+"      </popup>"
+
+"</ui>"
+;
+/*             "<ui>"
+        "  <menubar name='MenuBar'>"
+        "    <menu action='MenuFile'>"
+        "      <menuitem action='New'/>"
+        "      <menuitem action='Open'/>"
+        "      <separator/>"
+        "      <menuitem action='Quit'/>"
+        "    </menu>"
+        "    <menu action='MenuEdit'>"
+        "      <menuitem action='Cut'/>"
+        "      <menuitem action='Copy'/>"
+        "      <menuitem action='Paste'/>"
+        "    </menu>"
+        "  </menubar>"
+        "  <toolbar  name='ToolBar'>"
+        "    <toolitem action='Open'/>"
+        "    <toolitem action='Quit'/>"
+        "  </toolbar>"
+        "</ui>";
+*/
+       try
+       {
+               actions_action_group->set_sensitive(false);
+               App::ui_manager()->set_add_tearoffs(true);
+               App::ui_manager()->insert_action_group(menus_action_group,1);
+               App::ui_manager()->insert_action_group(actions_action_group,1);
+               App::ui_manager()->add_ui_from_string(ui_info);
+
+               //App::ui_manager()->get_accel_group()->unlock();
+       }
+       catch(const Glib::Error& ex)
+       {
+               sinfg::error("building menus and toolbars failed: " + ex.what());
+       }
+
+       // Add default keyboard accelerators
+#define ACCEL(path,accel)      { Gtk::AccelKey accel_key(accel,path); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); }
+#define ACCEL2(accel)  { Gtk::AccelKey accel_key(accel); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); }
+       ACCEL("<Actions>//select-all-ducks","<Control>a");
+       ACCEL("<Actions>//unselect-all-layers","<Control>d");
+       ACCEL("<Actions>//render","F9");
+       ACCEL("<Actions>//preview","F11");
+       ACCEL("<Actions>//properties","F8");
+       ACCEL("<Actions>//options","F12");
+       ACCEL("<Actions>//import","<control>i");
+       ACCEL2(Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0),"<Actions>//stop"));
+       ACCEL("<Actions>//toggle-grid-show","<Control>g");
+       ACCEL("<Actions>//toggle-grid-snap","<Control>l");
+       ACCEL2(Gtk::AccelKey('`',Gdk::CONTROL_MASK,"<Actions>//toggle-low-res"));
+       ACCEL("<Actions>//mask-position-ducks", "<Mod1>1");
+       ACCEL("<Actions>//mask-vertex-ducks", "<Mod1>2");
+       ACCEL("<Actions>//mask-tangent-ducks", "<Mod1>3");
+       ACCEL("<Actions>//mask-radius-ducks", "<Mod1>4");
+       ACCEL("<Actions>//mask-width-ducks", "<Mod1>5");
+       ACCEL("<Actions>//mask-angle-ducks", "<Mod1>6");
+
+
+       ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,"<Actions>//action-layer_raise"));
+       ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,"<Actions>//action-layer_lower"));
+
+       ACCEL("<Actions>//quality-01","<Control>1");
+       ACCEL("<Actions>//quality-02","<Control>2");
+       ACCEL("<Actions>//quality-03","<Control>3");
+       ACCEL("<Actions>//quality-04","<Control>4");
+       ACCEL("<Actions>//quality-05","<Control>5");
+       ACCEL("<Actions>//quality-06","<Control>6");
+       ACCEL("<Actions>//quality-07","<Control>7");
+       ACCEL("<Actions>//quality-08","<Control>8");
+       ACCEL("<Actions>//quality-09","<Control>9");
+       ACCEL("<Actions>//quality-10","<Control>0");
+       ACCEL("<Actions>//undo","<Control>z");
+       ACCEL("<Actions>//redo","<Control>r");
+       ACCEL("<Actions>//action-layer_remove","Delete");
+
+/*     ACCEL2(Gtk::AccelKey(']',static_cast<Gdk::ModifierType>(0),"<Actions>//jump-next-keyframe"));
+       ACCEL2(Gtk::AccelKey('[',static_cast<Gdk::ModifierType>(0),"<Actions>//jump-prev-keyframe"));
+       ACCEL2(Gtk::AccelKey('=',static_cast<Gdk::ModifierType>(0),"<Actions>//canvas-zoom-in"));
+       ACCEL2(Gtk::AccelKey('-',static_cast<Gdk::ModifierType>(0),"<Actions>//canvas-zoom-out"));
+       ACCEL("<Actions>//time-zoom-in","+");
+       ACCEL("<Actions>//time-zoom-out","_");
+*/
+       ACCEL2(Gtk::AccelKey('(',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-dec"));
+       ACCEL2(Gtk::AccelKey(')',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-inc"));
+
+       ACCEL2(Gtk::AccelKey(']',Gdk::CONTROL_MASK,"<Actions>//jump-next-keyframe"));
+       ACCEL2(Gtk::AccelKey('[',Gdk::CONTROL_MASK,"<Actions>//jump-prev-keyframe"));
+       ACCEL2(Gtk::AccelKey('=',Gdk::CONTROL_MASK,"<Actions>//canvas-zoom-in"));
+       ACCEL2(Gtk::AccelKey('-',Gdk::CONTROL_MASK,"<Actions>//canvas-zoom-out"));
+       ACCEL2(Gtk::AccelKey('+',Gdk::CONTROL_MASK,"<Actions>//time-zoom-in"));
+       ACCEL2(Gtk::AccelKey('_',Gdk::CONTROL_MASK,"<Actions>//time-zoom-out"));
+       ACCEL2(Gtk::AccelKey('.',Gdk::CONTROL_MASK,"<Actions>//seek-next-frame"));
+       ACCEL2(Gtk::AccelKey(',',Gdk::CONTROL_MASK,"<Actions>//seek-prev-frame"));
+       ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,"<Actions>//seek-next-second"));
+       ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,"<Actions>//seek-prev-second"));
+       ACCEL2(Gtk::AccelKey('o',Gdk::CONTROL_MASK,"<Actions>//toggle-onion-skin"));
+       ACCEL("<Actions>//seek-begin","Home");
+       ACCEL("<Actions>//seek-end","End");
+       ACCEL("<Actions>//state-normal","<Mod1>a");
+       ACCEL("<Actions>//state-rotate","<Mod1>s");
+       ACCEL("<Actions>//state-scale","<Mod1>d");
+       ACCEL("<Actions>//state-bline","<Mod1>b");
+       ACCEL("<Actions>//state-fill","<Mod1>f");
+       ACCEL("<Actions>//state-eyedrop","<Mod1>e");
+       ACCEL("<Actions>//state-gradient","<Mod1>g");
+       ACCEL("<Actions>//state-zoom","<Mod1>z");
+       ACCEL("<Actions>//canvas-zoom-fit","<Control><Shift>z");
+       
+#undef ACCEL
+}
+
+#ifdef _WIN32
+#define mkdir(x,y) mkdir(x)
+#endif
+
+/* === M E T H O D S ======================================================= */
+
+App::App(int *argc, char ***argv):
+       Gtk::Main(argc,argv),
+       IconControler(etl::dirname((*argv)[0]))
+{
+       app_base_path_=etl::dirname(etl::dirname((*argv)[0]));
+       
+       int serial_;
+       serial_=check_license(app_base_path_);
+       
+       
+       ui_interface_=new GlobalUIInterface();
+
+       gdk_rgb_init();
+
+       Glib::thread_init();
+
+       distance_system=Distance::SYSTEM_UNITS;
+               
+       if(mkdir(get_user_app_directory().c_str(),ACCESSPERMS)<0)
+       {
+               if(errno!=EEXIST)
+                       sinfg::error("UNABLE TO CREATE \"%s\"",get_user_app_directory().c_str());
+       }
+       else
+       {
+               sinfg::info("Created directory \"%s\"",get_user_app_directory().c_str());
+       }
+       
+       
+       ipc=new IPC();
+       
+       try
+       {
+               if(!SINFG_CHECK_VERSION())
+               {
+               cerr<<"FATAL: Sinfg Version Mismatch"<<endl;
+               dialog_error_blocking("SINFG Studio",
+                       "This copy of SINFG Studio was compiled against a\n"
+                       "different version of libsinfg than what is currently\n"
+                       "installed. Sinfg Studio will now abort. Try downloading\n"
+                       "the latest version from the SINFG Development Website at\n"
+                       "http://dev.sinfg.com/ "
+               );
+               throw 40;
+               }
+       }
+       catch(sinfg::SoftwareExpired)
+       {
+               cerr<<"FATAL: Software Expired"<<endl;
+               dialog_error_blocking("SINFG Studio",
+                       "This copy of SINFG Studio has expired.\n"
+                       "Please erase this copy, or download and\n"
+                       "install the latest copy from the SINFG\n"
+                       "Development Website at http://dev.sinfg.com/ ."
+               );
+               throw 39;
+       }
+       Glib::set_application_name(_("SINFG Studio"));
+       
+       About about_window;
+       about_window.set_can_self_destruct(false);
+       about_window.show();
+
+       shutdown_in_progress=false;
+       SuperCallback sinfg_init_cb(about_window.get_callback(),0,9000,10000);
+       SuperCallback studio_init_cb(about_window.get_callback(),9000,10000,10000);
+       
+       // Initialize the Sinfg library
+       try { sinfgapp_main=etl::smart_ptr<sinfgapp::Main>(new sinfgapp::Main(etl::dirname((*argv)[0]),&sinfg_init_cb)); }
+       catch(...)
+       {
+               get_ui_interface()->error("Failed to initialize sinfg!");
+               throw;
+       }
+
+       // add the preferences to the settings
+       sinfgapp::Main::settings().add_domain(&_preferences,"pref");
+       
+       try
+       {
+               studio_init_cb.task("Init UI Manager...");
+               App::ui_manager_=studio::UIManager::create();
+               init_ui_manager();
+               
+               studio_init_cb.task("Init Dock Manager...");
+               dock_manager=new studio::DockManager();
+
+               studio_init_cb.task("Init State Manager...");
+               state_manager=new StateManager();
+
+               studio_init_cb.task("Init Toolbox...");
+               toolbox=new studio::Toolbox();
+
+               studio_init_cb.task("Init Tool Options...");
+               dialog_tool_options=new studio::Dialog_ToolOptions();
+               dock_manager->register_dockable(*dialog_tool_options);
+
+               studio_init_cb.task("Init History...");
+               dock_history=new studio::Dock_History();
+               dock_manager->register_dockable(*dock_history);
+
+               studio_init_cb.task("Init Canvases...");
+               dock_canvases=new studio::Dock_Canvases();
+               dock_manager->register_dockable(*dock_canvases);
+
+               studio_init_cb.task("Init Keyframes...");
+               dock_keyframes=new studio::Dock_Keyframes();
+               dock_manager->register_dockable(*dock_keyframes);
+
+               studio_init_cb.task("Init Layers...");
+               dock_layers=new studio::Dock_Layers();
+               dock_manager->register_dockable(*dock_layers);
+
+               studio_init_cb.task("Init Params...");
+               dock_params=new studio::Dock_Params();
+               dock_manager->register_dockable(*dock_params);
+
+               studio_init_cb.task("Init MetaData...");
+               dock_meta_data=new studio::Dock_MetaData();
+               dock_manager->register_dockable(*dock_meta_data);
+
+               studio_init_cb.task("Init Children...");
+               dock_children=new studio::Dock_Children();
+               dock_manager->register_dockable(*dock_children);
+               
+               studio_init_cb.task("Init Info...");
+               dock_info = new studio::Dock_Info();
+               dock_manager->register_dockable(*dock_info);
+               
+               studio_init_cb.task("Init Navigator...");
+               dock_navigator = new studio::Dock_Navigator();
+               dock_manager->register_dockable(*dock_navigator);
+
+               studio_init_cb.task("Init Timetrack...");
+               dock_timetrack = new studio::Dock_Timetrack();
+               dock_manager->register_dockable(*dock_timetrack);
+
+               studio_init_cb.task("Init Curve Editor...");
+               dock_curves = new studio::Dock_Curves();
+               dock_manager->register_dockable(*dock_curves);
+
+               studio_init_cb.task("Init Layer Groups...");
+               dock_layer_groups = new studio::Dock_LayerGroups();
+               dock_manager->register_dockable(*dock_layer_groups);
+               
+               
+               studio_init_cb.task("Init Color Dialog...");
+               dialog_color=new studio::Dialog_Color();
+
+               studio_init_cb.task("Init Gradient Dialog...");
+               dialog_gradient=new studio::Dialog_Gradient();
+
+               studio_init_cb.task("Init DeviceTracker...");
+               device_tracker=new studio::DeviceTracker();
+
+               studio_init_cb.task("Init Tools...");
+               state_manager->add_state(&state_normal);
+               state_manager->add_state(&state_smooth_move);
+               state_manager->add_state(&state_scale);
+               state_manager->add_state(&state_rotate);
+
+               state_manager->add_state(&state_bline);
+               state_manager->add_state(&state_polygon);
+               state_manager->add_state(&state_circle);
+               state_manager->add_state(&state_rectangle);
+
+               state_manager->add_state(&state_draw);
+               state_manager->add_state(&state_sketch);
+
+               state_manager->add_state(&state_eyedrop);
+               state_manager->add_state(&state_fill);
+               
+               state_manager->add_state(&state_width);
+               state_manager->add_state(&state_gradient);
+               
+               state_manager->add_state(&state_zoom);
+
+               studio_init_cb.task("Init ModPalette...");
+               module_list_.push_back(new ModPalette()); module_list_.back()->start();
+
+               studio_init_cb.task("Init ModMirror...");
+               module_list_.push_back(new ModMirror()); module_list_.back()->start();
+
+
+               studio_init_cb.task("Init Setup Dialog...");
+               dialog_setup=new studio::Dialog_Setup();
+               
+               studio_init_cb.task("Init Input Dialog...");
+               dialog_input=new Gtk::InputDialog();
+
+               studio_init_cb.task("Init auto recovery...");
+               auto_recover=new AutoRecover();
+
+               studio_init_cb.amount_complete(9250,10000);
+               studio_init_cb.task("Loading Settings...");
+               load_settings();
+               studio_init_cb.task("Checking auto-recover...");
+       
+               studio_init_cb.amount_complete(9900,10000);
+       
+               if(auto_recover->recovery_needed())
+               {
+                       about_window.hide();
+                       if(
+                               get_ui_interface()->yes_no(
+                                       "Auto Recovery",
+                                       "SINFG Studio seems to have crashed\n"
+                                       "before you could save all your files.\n"
+                                       "Would you like to re-open those files\n"
+                                       "and recover your unsaved changes?"
+                               )==sinfgapp::UIInterface::RESPONSE_YES
+                       )
+                       {
+                               if(!auto_recover->recover())
+                               {
+                                       get_ui_interface()->error(_("Unable to fully recover from previous crash"));
+                               }
+                               else
+                               get_ui_interface()->error(
+                                       _("SINFG Studio has attempted to recover\n"
+                                       "from a previous crash. The files that it has\n"
+                                       "recovered are NOT YET SAVED. It would be a good\n"
+                                       "idea to review them and save them now.")
+                               );
+                       }
+                       about_window.show();
+               }
+               
+               // Look for any files given on the command line,
+               // and load them if found.
+               for(;*argc>=1;(*argc)--)
+                       if((*argv)[*argc] && (*argv)[*argc][0]!='-')
+                       {
+                               studio_init_cb.task("Loading files...");
+                               about_window.hide();
+                               open((*argv)[*argc]);
+                               about_window.show();
+                       }
+               
+               studio_init_cb.task("Done.");
+               studio_init_cb.amount_complete(10000,10000);
+       
+               toolbox->present();
+       }
+       catch(...)
+       {
+               get_ui_interface()->error(_("Unknown exception caught when constructing App.\nThis software may be unstable."));
+       }
+}
+
+StateManager* App::get_state_manager() { return state_manager; }
+
+App::~App()
+{
+       shutdown_in_progress=true;
+
+       save_settings();
+
+       sinfgapp::Main::settings().remove_domain("pref");
+       
+       selected_instance=0;
+
+       // Unload all of the modules
+       for(;!module_list_.empty();module_list_.pop_back());
+       
+       delete state_manager;
+
+       delete ipc;
+       
+       delete auto_recover;
+
+       toolbox->hide();
+
+//     studio::App::iteration(false); 
+       
+       delete toolbox;
+       
+//     studio::App::iteration(false); 
+
+//     studio::App::iteration(false); 
+
+       delete dialog_setup;
+
+       delete dialog_gradient;
+
+       delete dialog_color;
+
+       delete dialog_input;
+
+       delete dock_manager;
+
+       instance_list.clear();
+
+//     studio::App::iteration(false);
+}
+
+String
+App::get_user_app_directory()
+{
+       return Glib::build_filename(Glib::get_home_dir(),"sinfg");
+}
+
+sinfg::String
+App::get_config_file(const sinfg::String& file)
+{
+       return Glib::build_filename(get_user_app_directory(),file);
+}
+
+void
+App::add_recent_file(const std::string &file_name)
+{
+       std::string filename(file_name);
+
+       assert(!filename.empty());
+       
+       if(filename.empty())
+               return;
+       
+       // Toss out any "hidden" files
+       if(basename(filename)[0]=='.')
+               return;
+               
+       // If we aren't an absolute path, turn outselves into one
+       if(!is_absolute_path(filename))
+               filename=absolute_path(filename);
+       
+       list<string>::iterator iter;
+       // Check to see if the file is already on the list.
+       // If it is, then remove it from the list
+       for(iter=recent_files.begin();iter!=recent_files.end();iter++)
+               if(*iter==filename)
+               {
+                       recent_files.erase(iter);
+                       break;
+               }
+
+       
+       // Push the filename to the front of the list
+       recent_files.push_front(filename);
+               
+       // Clean out the files at the end of the list.
+       while(recent_files.size()>(unsigned)get_max_recent_files())
+               recent_files.pop_back();
+       
+       signal_recent_files_changed_();
+       
+       return;
+}
+
+static Time::Format _App_time_format(Time::FORMAT_NORMAL);
+
+Time::Format
+App::get_time_format()
+{
+       return _App_time_format;
+}
+
+void
+App::set_time_format(sinfg::Time::Format x)
+{
+       _App_time_format=x;
+}
+
+
+void
+App::save_settings()
+{
+       try
+       {
+               {
+                       std::string filename=get_config_file("accelrc");
+                       Gtk::AccelMap::save(filename);
+               }
+               do{
+                       std::string filename=get_config_file("recentfiles");
+
+                       std::ofstream file(filename.c_str());
+               
+                       if(!file)
+                       {
+                               sinfg::warning("Unable to save %s",filename.c_str());
+                               break;
+                       }
+               
+                       list<string>::reverse_iterator iter;
+       
+                       for(iter=recent_files.rbegin();iter!=recent_files.rend();iter++)
+                               file<<*iter<<endl;
+               }while(0);
+
+               std::string filename=get_config_file("settings");
+               sinfgapp::Main::settings().save_to_file(filename);
+       }
+       catch(...)
+       {
+               sinfg::warning("Caught exception when attempting to save settings.");
+       }
+}
+
+void
+App::load_settings()
+{
+       try
+       {
+               {
+                       std::string filename=get_config_file("accelrc");
+                       Gtk::AccelMap::load(filename);
+               }
+               {
+                       std::string filename=get_config_file("recentfiles");
+
+                       std::ifstream file(filename.c_str());
+       
+                       while(file)
+                       {
+                               std::string recent_file;
+                               getline(file,recent_file);
+                               if(!recent_file.empty())
+                                       add_recent_file(recent_file);
+                       }
+               }
+               std::string filename=get_config_file("settings");
+               if(!sinfgapp::Main::settings().load_from_file(filename))
+               {
+                       //std::string filename=Glib::build_filename(Glib::get_home_dir(),".sinfgrc");
+                       //if(!sinfgapp::Main::settings().load_from_file(filename))
+                       {
+                               gamma.set_gamma(1.0/2.2);
+                               sinfgapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
+                               sinfgapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
+                               sinfgapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
+                               sinfgapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
+                               sinfgapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
+                               sinfgapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
+                               sinfgapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
+                               sinfgapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
+                               sinfgapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
+                               sinfgapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
+                               sinfgapp::Main::settings().set_value("pref.distance_system","pt");
+                               sinfgapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
+                               sinfgapp::Main::settings().set_value("window.toolbox.pos","4 4");
+                       }
+               }
+               
+       }
+       catch(...)
+       {
+               sinfg::warning("Caught exception when attempting to load settings.");
+       }
+}
+
+bool
+App::shutdown_request(GdkEventAny*)
+{
+       quit();
+       return true;
+       //return !shutdown_in_progress;
+}
+
+void
+App::quit()
+{
+       if(shutdown_in_progress)return;
+               
+       
+       get_ui_interface()->task("Quit Request");
+       if(Busy::count)
+       {
+               dialog_error_blocking("Cannot quit!","Tasks are currently running.\nPlease cancel the current tasks and try again");
+               return;
+       }
+
+       std::list<etl::handle<Instance> >::iterator iter;
+       for(iter=instance_list.begin();!instance_list.empty();iter=instance_list.begin())
+       {
+               if(!(*iter)->safe_close())
+                       return;
+
+/*
+               if((*iter)->sinfgapp::Instance::get_action_count())
+               {
+                       handle<sinfgapp::UIInterface> uim;
+                       uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface();
+                       assert(uim);
+                       string str=strprintf(_("Would you like to save your changes to %s?"),(*iter)->get_file_name().c_str() );
+                       switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES))
+                       {
+                               case sinfgapp::UIInterface::RESPONSE_NO:
+                                       break;
+                               case sinfgapp::UIInterface::RESPONSE_YES:
+                                       (*iter)->save();
+                                       break;
+                               case sinfgapp::UIInterface::RESPONSE_CANCEL:
+                                       return;
+                               default:
+                                       assert(0);
+                                       return;
+                       }
+               }
+
+
+               if((*iter)->sinfgapp::Instance::is_modified())
+               {
+                       handle<sinfgapp::UIInterface> uim;
+                       uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface();
+                       assert(uim);
+                       string str=strprintf(_("%s has changes not yet on the CVS repository.\nWould you like to commit these changes?"),(*iter)->get_file_name().c_str() );
+                       switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES))
+                       {
+                               case sinfgapp::UIInterface::RESPONSE_NO:
+                                       break;
+                               case sinfgapp::UIInterface::RESPONSE_YES:
+                                       (*iter)->dialog_cvs_commit();
+                                       break;
+                               case sinfgapp::UIInterface::RESPONSE_CANCEL:
+                                       return;
+                               default:
+                                       assert(0);
+                                       return;
+                       }
+               }
+*/             
+               
+               // This next line causes things to crash for some reason
+               //(*iter)->close(); 
+       }
+       
+       shutdown_in_progress=true;
+
+       instance_list.clear();
+
+       while(studio::App::events_pending())studio::App::iteration(false);
+               
+       Gtk::Main::quit();
+       auto_recover->normal_shutdown();
+
+       get_ui_interface()->task("Quit Request sent");
+}
+
+void
+App::show_setup()
+{
+       dialog_setup->refresh();
+       dialog_setup->show();
+}
+
+gint Signal_Open_Ok(GtkWidget *widget, int *val){*val=1;return 0;}
+gint Signal_Open_Cancel(GtkWidget *widget, int *val){*val=2;return 0;}
+
+//#ifdef WIN32
+//#define USE_WIN32_FILE_DIALOGS 1
+//#endif
+
+#ifdef USE_WIN32_FILE_DIALOGS
+static OPENFILENAME ofn={};
+#endif
+
+#ifdef WIN32
+#include <gdk/gdkwin32.h>
+#endif
+       
+bool
+App::dialog_open_file(const std::string &title, std::string &filename)
+{
+#ifdef USE_WIN32_FILE_DIALOGS
+       static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
+
+       GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
+       HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
+       HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
+       
+       ofn.lStructSize=sizeof(OPENFILENAME);
+       ofn.hwndOwner = hWnd;
+       ofn.hInstance = hInstance;
+       ofn.lpstrFilter = szFilter;
+//     ofn.lpstrCustomFilter=NULL;
+//     ofn.nMaxCustFilter=0;
+//     ofn.nFilterIndex=0;
+//     ofn.lpstrFile=NULL;
+       ofn.nMaxFile=MAX_PATH;
+//     ofn.lpstrFileTitle=NULL;
+//     ofn.lpstrInitialDir=NULL;
+//     ofn.lpstrTitle=NULL;
+       ofn.Flags=OFN_HIDEREADONLY;
+//     ofn.nFileOffset=0;
+//     ofn.nFileExtension=0;
+       ofn.lpstrDefExt=TEXT("sif");
+//     ofn.lCustData = 0l;
+       ofn.lpfnHook=NULL;
+//     ofn.lpTemplateName=NULL;
+       
+       CHAR szFilename[MAX_PATH];
+       CHAR szTitle[500];
+       strcpy(szFilename,filename.c_str());
+       strcpy(szTitle,title.c_str());
+       
+       ofn.lpstrFile=szFilename;
+       ofn.lpstrFileTitle=szTitle;
+       
+       if(GetOpenFileName(&ofn))
+       {
+               filename=szFilename;
+               return true;
+       }
+       return false;
+       
+#else
+       sinfg::String prev_path;
+       if(!_preferences.get_value("curr_path",prev_path))
+               prev_path=".";
+       
+       GtkWidget *ok;
+       GtkWidget *cancel;
+       int val=0;
+       
+       GtkWidget *fileselection;
+       fileselection = gtk_file_selection_new(title.c_str());
+
+       
+       if(basename(filename)==filename)
+       {
+               gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),(prev_path+ETL_DIRECTORY_SEPERATOR).c_str());         
+       }
+       else
+               gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),dirname(filename).c_str());
+
+       gtk_file_selection_complete(GTK_FILE_SELECTION(fileselection),basename(filename).c_str());
+
+       ok=GTK_FILE_SELECTION(fileselection)->ok_button;
+       cancel=GTK_FILE_SELECTION(fileselection)->cancel_button;
+
+       gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Ok),&val);              
+       gtk_signal_connect(GTK_OBJECT(cancel),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Cancel),&val);              
+
+       gtk_widget_show(fileselection);
+
+       while(!val)
+               iteration();            
+       
+       
+       if(val==1)
+       {
+               filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection));
+               _preferences.set_value("curr_path",dirname(filename));
+       }
+       else
+       {
+               gtk_widget_destroy(fileselection);
+               return false;
+       }
+       gtk_widget_destroy(fileselection);
+       return true;
+#endif
+}
+
+bool
+App::dialog_save_file(const std::string &title, std::string &filename)
+{
+#ifdef USE_WIN32_FILE_DIALOGS
+       static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
+       
+       GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
+       HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
+       HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
+       
+       ofn.lStructSize=sizeof(OPENFILENAME);
+       ofn.hwndOwner = hWnd;
+       ofn.hInstance = hInstance;
+       ofn.lpstrFilter = szFilter;
+//     ofn.lpstrCustomFilter=NULL;
+//     ofn.nMaxCustFilter=0;
+//     ofn.nFilterIndex=0;
+//     ofn.lpstrFile=NULL;
+       ofn.nMaxFile=MAX_PATH;
+//     ofn.lpstrFileTitle=NULL;
+//     ofn.lpstrInitialDir=NULL;
+//     ofn.lpstrTitle=NULL;
+       ofn.Flags=OFN_OVERWRITEPROMPT;
+//     ofn.nFileOffset=0;
+//     ofn.nFileExtension=0;
+       ofn.lpstrDefExt=TEXT("sif");
+//     ofn.lCustData = 0l;
+       ofn.lpfnHook=NULL;
+//     ofn.lpTemplateName=NULL;
+       
+       CHAR szFilename[MAX_PATH];
+       CHAR szTitle[500];
+       strcpy(szFilename,filename.c_str());
+       strcpy(szTitle,title.c_str());
+       
+       ofn.lpstrFile=szFilename;
+       ofn.lpstrFileTitle=szTitle;
+       
+       if(GetSaveFileName(&ofn))
+       {
+               filename=szFilename;
+               return true;
+       }
+       return false;
+#else
+       return dialog_open_file(title, filename);
+#endif
+}
+
+bool
+App::dialog_saveas_file(const std::string &title, std::string &filename)
+{
+#if USE_WIN32_FILE_DIALOGS
+       static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
+       
+       GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
+       HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
+       HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
+       
+       ofn.lStructSize=sizeof(OPENFILENAME);
+       ofn.hwndOwner = hWnd;
+       ofn.hInstance = hInstance;
+       ofn.lpstrFilter = szFilter;
+//     ofn.lpstrCustomFilter=NULL;
+//     ofn.nMaxCustFilter=0;
+//     ofn.nFilterIndex=0;
+//     ofn.lpstrFile=NULL;
+       ofn.nMaxFile=MAX_PATH;
+//     ofn.lpstrFileTitle=NULL;
+//     ofn.lpstrInitialDir=NULL;
+//     ofn.lpstrTitle=NULL;
+       ofn.Flags=OFN_OVERWRITEPROMPT;
+//     ofn.nFileOffset=0;
+//     ofn.nFileExtension=0;
+       ofn.lpstrDefExt=TEXT("sif");
+//     ofn.lCustData = 0l;
+       ofn.lpfnHook=NULL;
+//     ofn.lpTemplateName=NULL;
+       
+       CHAR szFilename[MAX_PATH];
+       CHAR szTitle[500];
+       strcpy(szFilename,filename.c_str());
+       strcpy(szTitle,title.c_str());
+       
+       ofn.lpstrFile=szFilename;
+       ofn.lpstrFileTitle=szTitle;
+       
+       if(GetSaveFileName(&ofn))
+       {
+               filename=szFilename;
+               return true;
+       }
+       return false;
+#else
+       return dialog_open_file(title, filename);
+#endif
+}
+
+void
+App::dialog_error_blocking(const std::string &title, const std::string &message)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(message);
+       label.show();
+       
+       dialog.get_vbox()->pack_start(label);
+       dialog.add_button(Gtk::StockID("gtk-ok"),1);
+       dialog.show();
+       dialog.run();
+}
+
+void
+App::dialog_warning_blocking(const std::string &title, const std::string &message)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(message);
+       label.show();
+
+       dialog.get_vbox()->pack_start(label);
+       dialog.add_button(Gtk::StockID("gtk-ok"),1);
+       dialog.show();
+       dialog.run();
+}
+
+bool
+App::dialog_yes_no(const std::string &title, const std::string &message)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(message);
+       label.show();
+       
+       dialog.get_vbox()->pack_start(label);
+       dialog.add_button(Gtk::StockID("gtk-yes"),1);
+       dialog.add_button(Gtk::StockID("gtk-no"),0);
+       dialog.show();
+       return dialog.run();
+}
+
+int
+App::dialog_yes_no_cancel(const std::string &title, const std::string &message)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(message);
+       label.show();
+
+       dialog.get_vbox()->pack_start(label);
+       dialog.add_button(Gtk::StockID("gtk-yes"),1);
+       dialog.add_button(Gtk::StockID("gtk-no"),0);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),2);
+       dialog.show();
+       return dialog.run();
+}
+
+void
+App::dialog_not_implemented()
+{
+       Gtk::Dialog dialog(
+               "Feature not available",                // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label("Sorry, this feature has not yet been implemented.");
+       label.show();
+       
+       dialog.get_vbox()->pack_start(label);
+       dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
+       dialog.show();
+       dialog.run();
+}
+
+bool
+App::dialog_entry(const std::string &title, const std::string &message,std::string &text)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(message);
+       label.show();
+       dialog.get_vbox()->pack_start(label);
+
+       Gtk::Entry entry;
+       entry.set_text(text);
+       entry.show();
+       entry.set_activates_default(true);
+       dialog.get_vbox()->pack_start(entry);
+
+       dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL);
+       dialog.set_default_response(Gtk::RESPONSE_OK);
+       entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK));
+       dialog.show();
+
+       if(dialog.run()!=Gtk::RESPONSE_OK)
+               return false;
+
+       text=entry.get_text();
+
+       return true;
+}
+
+
+
+
+bool
+App::open(std::string filename)
+{
+       return open_as(filename,filename);
+}
+
+bool
+App::open_as(std::string filename,std::string as)
+{
+       try
+       {
+               OneMoment one_moment;
+       
+               etl::handle<sinfg::Canvas> canvas(open_canvas_as(filename,as));
+               if(canvas && get_instance(canvas))
+               {
+                       get_instance(canvas)->find_canvas_view(canvas)->present();
+                       throw (String)strprintf(_("\"%s\" appears to already be open!"),filename.c_str());              
+               }
+               if(!canvas)
+                       throw (String)strprintf(_("Unable to open file \"%s\""),filename.c_str());
+
+               add_recent_file(as);
+               
+               handle<Instance> instance(Instance::create(canvas));
+
+               if(!instance)
+                       throw (String)strprintf(_("Unable to create instance for \"%s\""),filename.c_str());
+               
+               one_moment.hide();
+               
+               if(instance->is_updated() && App::dialog_yes_no(_("CVS Update"), _("There appears to be a newer version of this file available on the CVS repository.\nWould you like to update now? (It would probably be a good idea)")))
+                       instance->dialog_cvs_update();
+       }
+       catch(String x)
+       {
+               dialog_error_blocking(_("Error"), x);
+               return false;
+       }
+       catch(...)
+       {
+               dialog_error_blocking(_("Error"), _("Uncaught error on file open (BUG)"));
+               return false;
+       }
+
+       _preferences.set_value("curr_path",dirname(as));
+       
+       return true;
+}
+
+
+void
+App::new_instance()
+{
+       handle<sinfg::Canvas> canvas=sinfg::Canvas::create();
+       canvas->set_name(strprintf("Untitled%d",Instance::get_count()));
+
+       String file_name(strprintf("untitled%d.sif",Instance::get_count()));
+       
+       canvas->rend_desc().set_frame_rate(24.0);
+       canvas->rend_desc().set_time_start(0.0);
+       canvas->rend_desc().set_time_end(00.0);
+       canvas->rend_desc().set_x_res(DPI2DPM(72.0f));
+       canvas->rend_desc().set_y_res(DPI2DPM(72.0f));
+       canvas->rend_desc().set_tl(Vector(-4,2.25));
+       canvas->rend_desc().set_br(Vector(4,-2.25));
+       canvas->rend_desc().set_w(480);
+       canvas->rend_desc().set_h(270);
+       canvas->rend_desc().set_antialias(1);
+       canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
+       canvas->set_file_name(file_name);
+       
+       Instance::create(canvas)->find_canvas_view(canvas)->canvas_properties.present();
+}
+
+void
+App::dialog_open()
+{
+       string filename="*.sif";
+
+       while(dialog_open_file("Open", filename))
+       {
+               // If the filename still has wildcards, then we should
+               // continue looking for the file we want
+               if(find(filename.begin(),filename.end(),'*')!=filename.end())
+                       continue;
+
+               if(open(filename))
+                       break;
+
+               get_ui_interface()->error(_("Unable to open file"));
+       }
+}
+
+void
+App::set_selected_instance(etl::loose_handle<Instance> instance)
+{
+/*     if(get_selected_instance()==instance)
+       {
+               selected_instance=instance;
+               signal_instance_selected()(instance);
+               return;
+       }
+       else
+       {
+*/
+               selected_instance=instance;
+               if(get_selected_canvas_view() && get_selected_canvas_view()->get_instance()!=instance)
+               {
+                       if(instance)
+                       {
+                               instance->focus(instance->get_canvas());
+                       }
+                       else
+                               set_selected_canvas_view(0);
+               }
+               signal_instance_selected()(instance);
+}
+
+void
+App::set_selected_canvas_view(etl::loose_handle<CanvasView> canvas_view)
+{
+       selected_canvas_view=canvas_view;
+       signal_canvas_view_focus()(selected_canvas_view);
+       if(canvas_view)
+       {
+               selected_instance=canvas_view->get_instance();
+               signal_instance_selected()(canvas_view->get_instance());
+       }
+/*
+       if(get_selected_canvas_view()==canvas_view)
+       {
+               signal_canvas_view_focus()(selected_canvas_view);
+               signal_instance_selected()(canvas_view->get_instance());
+               return;
+       }
+       selected_canvas_view=canvas_view;
+       if(canvas_view && canvas_view->get_instance() != get_selected_instance())
+               set_selected_instance(canvas_view->get_instance());
+       signal_canvas_view_focus()(selected_canvas_view);
+*/
+}
+
+etl::loose_handle<Instance>
+App::get_instance(Canvas::Handle canvas)
+{
+       if(!canvas) return 0;
+       canvas=canvas->get_root();
+
+       std::list<etl::handle<Instance> >::iterator iter;
+       for(iter=instance_list.begin();iter!=instance_list.end();++iter)
+       {
+               if((*iter)->get_canvas()==canvas)
+                       return *iter;
+       }
+       return 0;
+}
+
+void
+App::dialog_about()
+{
+       (new class About())->show();
+}
+
+void
+studio::App::undo()
+{
+       if(selected_instance)
+               selected_instance->undo();
+}
+
+void
+studio::App::redo()
+{
+       if(selected_instance)
+               selected_instance->redo();
+}
+
+sinfg::String
+studio::App::get_base_path()
+{
+       return app_base_path_;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/app.h b/synfig-studio/trunk/src/gtkmm/app.h
new file mode 100644 (file)
index 0000000..decaaf8
--- /dev/null
@@ -0,0 +1,330 @@
+/* === S I N F G =========================================================== */
+/*!    \file app.h
+**     \brief writeme
+**
+**     $Id: app.h,v 1.2 2005/01/13 21:11:16 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_APP_H
+#define __SINFG_STUDIO_APP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/compatibility.h>
+#include <sigc++/bind.h>
+
+#include <gtkmm/main.h>
+#include <string>
+#include <list>
+
+#include <ETL/smart_ptr>
+
+#include <sinfg/distance.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+#include <gtkmm/uimanager.h>
+
+#include <sinfgapp/instance.h>
+#include "iconcontroler.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk
+{
+       class InputDialog;
+       class UIManager;
+       class ActionGroup;
+};
+
+namespace sinfgapp
+{
+       class UIInterface;
+       class Main;
+};
+
+class Preferences;
+       
+namespace studio {
+
+typedef Gtk::UIManager UIManager;
+
+class Toolbox;
+class Instance;
+class CanvasView;
+class Dialog_Setup;
+class Dialog_Gradient;
+class Dialog_Color;
+class Dialog_ToolOptions;
+class DeviceTracker;
+class AutoRecover;
+
+class DockManager;
+
+class Dock_History;
+class Dock_Canvases;
+
+class Dock_Keyframes;
+class Dock_Params;
+class Dock_Layers;
+class Dock_MetaData;
+class Dock_Children;
+class Dock_Info;
+class Dock_Navigator;
+class Dock_LayerGroups;
+class IPC;
+       
+class Module;
+
+class StateManager;
+class IconControler;
+       
+class App : public Gtk::Main, private IconControler
+{
+       friend class Preferences;
+       friend class Dialog_Setup;
+               
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       struct Busy
+       {
+               static int count;
+               Busy(){count++;}
+               ~Busy(){count--;}
+       };
+
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+       //static etl::handle<sinfgapp::UIInterface> ui_interface_;
+       //static int max_recent_files;
+
+/*
+       static Dock_Keyframes *dock_keyframes;
+       static Dock_Layers *dock_layers;
+       static Dock_Params *dock_params;
+       static Dock_MetaData *dock_meta_data;
+       static Dock_Children *dock_children;
+       static Dock_Info *dock_info;
+       static Dock_Navigator *dock_navigator;
+       static Dock_History *dock_history;
+       static Dock_Canvases *dock_canvases;
+       static Dock_LayerGroups *dock_layer_groups;
+
+       static IPC *ipc;
+*/
+
+       etl::smart_ptr<sinfgapp::Main> sinfgapp_main;
+
+
+       static etl::handle<Instance> selected_instance;
+       static etl::handle<CanvasView> selected_canvas_view;
+
+       static Glib::RefPtr<UIManager>  ui_manager_;
+       
+//     static std::list< etl::handle< Module > > module_list_;
+
+       /*
+ -- ** -- P U B L I C   D A T A -----------------------------------------------
+       */
+
+public:
+       static Gtk::InputDialog* dialog_input;
+
+       static DeviceTracker*   device_tracker;
+       static AutoRecover*     auto_recover;
+       static DockManager* dock_manager;
+
+       static DockManager* get_dock_manager() { return dock_manager; }
+
+       static Dialog_Setup* dialog_setup;
+       static Dialog_Gradient* dialog_gradient;
+       static Dialog_Color* dialog_color;
+//     static Dialog_Palette* dialog_palette;
+       static Dialog_ToolOptions *dialog_tool_options;
+
+       static sinfg::Distance::System distance_system;
+
+       static sinfg::Gamma gamma;
+
+       static Toolbox *toolbox;
+
+       static std::list<etl::handle<Instance> > instance_list;
+
+       static bool shutdown_in_progress;       
+
+       static bool use_colorspace_gamma;
+
+       /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+       */
+/*
+       static sigc::signal<
+               void,
+               etl::loose_handle<CanvasView>
+       > signal_canvas_view_focus_;
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > signal_instance_selected_;
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > signal_instance_created_;
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > signal_instance_deleted_;
+       static sigc::signal<void> signal_recent_files_changed_;
+       static sigc::signal<void> signal_present_all_;
+*/
+public:
+
+       static sigc::signal<void> &signal_present_all();
+
+       static sigc::signal<void> &signal_recent_files_changed();
+
+       static sigc::signal<
+               void,
+               etl::loose_handle<CanvasView>
+       >& signal_canvas_view_focus();
+
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > &signal_instance_selected();
+
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > &signal_instance_created();
+
+       static sigc::signal<
+               void,
+               etl::handle<Instance>
+       > &signal_instance_deleted();
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       App(int *argc, char ***argv);
+       virtual ~App();
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       static StateManager* get_state_manager();
+
+       static Glib::RefPtr<UIManager>& ui_manager() { return ui_manager_; }
+
+       static void add_recent_file(const std::string &filename);
+
+       static sinfg::String get_base_path();
+       static void save_settings();
+       static void load_settings();
+
+       static const std::list<std::string>& get_recent_files();
+
+       static const etl::handle<sinfgapp::UIInterface>& get_ui_interface();
+
+
+       static void set_selected_instance(etl::loose_handle<Instance> instance);
+       static void set_selected_canvas_view(etl::loose_handle<CanvasView>);
+
+       static etl::loose_handle<Instance> get_instance(etl::handle<sinfg::Canvas> canvas);
+
+       static etl::loose_handle<Instance> get_selected_instance() { return selected_instance; }
+       static etl::loose_handle<CanvasView> get_selected_canvas_view() { return selected_canvas_view; }
+
+       static bool open(std::string filename);
+
+       static bool open_as(std::string filename,std::string as);
+
+       static void new_instance();
+
+       static void dialog_open();
+
+       static void dialog_about();
+       
+       static void quit();
+       
+       static void show_setup();
+
+       static void undo();
+       static void redo();
+       
+       static int get_max_recent_files();
+       static void set_max_recent_files(int x);
+
+
+       static sinfg::Time::Format get_time_format();
+       static void set_time_format(sinfg::Time::Format x);
+
+       static bool shutdown_request(GdkEventAny*bleh=NULL);
+       
+//     static bool dialog_file(const std::string &title, std::string &filename);
+
+       static bool dialog_open_file(const std::string &title, std::string &filename);
+       static bool dialog_save_file(const std::string &title, std::string &filename);
+       static bool dialog_saveas_file(const std::string &title, std::string &filename);
+
+       static void dialog_error_blocking(const std::string &title, const std::string &message);
+
+       static void dialog_warning_blocking(const std::string &title, const std::string &message);
+
+       static bool dialog_entry(const std::string &title, const std::string &message,std::string &text);
+
+       static bool dialog_yes_no(const std::string &title, const std::string &message);
+
+       static int dialog_yes_no_cancel(const std::string &title, const std::string &message);
+       
+       static void dialog_not_implemented();
+
+       static sinfg::String get_user_app_directory();
+       static sinfg::String get_config_file(const sinfg::String& file);
+}; // END of class App
+
+}; // END namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp b/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp
new file mode 100644 (file)
index 0000000..9c41444
--- /dev/null
@@ -0,0 +1,486 @@
+/* === S I N F G =========================================================== */
+/*!    \file asyncrenderer.cpp
+**     \brief Template File
+**
+**     $Id: asyncrenderer.cpp,v 1.5 2005/01/12 07:03:42 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "asyncrenderer.h"
+#include <glibmm/thread.h>
+#include <glibmm/dispatcher.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <sinfg/general.h>
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+#define BOREDOM_TIMEOUT                50
+
+#define REJOIN_ON_STOP 1
+
+// The Glib::Dispatcher class is broken as of Glibmm 2.4.5.
+// Defining this macro enables the workaround.
+#define GLIB_DISPATCHER_BROKEN 1
+
+/* === C L A S S E S ======================================================= */
+
+class AsyncTarget_Tile : public sinfg::Target_Tile
+{
+public:
+       etl::handle<sinfg::Target_Tile> warm_target;
+       
+       struct tile_t
+       {
+               Surface surface;
+               int x,y;
+               tile_t(const Surface& surface,int x, int y):
+                       surface(surface),
+                       x(x),y(y)
+               {
+               }
+       };
+       std::list<tile_t> tile_queue;
+       Glib::Mutex mutex;
+       
+#ifndef GLIB_DISPATCHER_BROKEN
+       Glib::Dispatcher tile_ready_signal;
+#endif
+       Glib::Cond cond_tile_queue_empty;
+       bool alive_flag;
+       
+       sigc::connection ready_connection;
+       
+public:
+       AsyncTarget_Tile(etl::handle<sinfg::Target_Tile> warm_target):
+               warm_target(warm_target)
+       {
+               set_avoid_time_sync(warm_target->get_avoid_time_sync());
+               set_tile_w(warm_target->get_tile_w());
+               set_tile_h(warm_target->get_tile_h());
+               set_canvas(warm_target->get_canvas());
+               set_quality(warm_target->get_quality());
+               set_remove_alpha(warm_target->get_remove_alpha());
+               set_threads(warm_target->get_threads());
+               set_clipping(warm_target->get_clipping());
+               set_rend_desc(&warm_target->rend_desc());
+               alive_flag=true;
+#ifndef GLIB_DISPATCHER_BROKEN
+               ready_connection=tile_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready));
+#endif
+       }
+               
+       ~AsyncTarget_Tile()
+       {
+               ready_connection.disconnect();
+       }
+       void set_dead()
+       {
+               Glib::Mutex::Lock lock(mutex);
+               alive_flag=false;
+       }
+       
+       virtual int total_tiles()const
+       {
+               return warm_target->total_tiles();
+       }
+       
+       virtual int next_tile(int& x, int& y)
+       {
+               if(!alive_flag)
+                       return 0;
+               
+               return warm_target->next_tile(x,y);
+       }
+
+       virtual int next_frame(Time& time)
+       {
+               if(!alive_flag)
+                       return 0;
+               return warm_target->next_frame(time);
+       }
+       
+       virtual bool start_frame(sinfg::ProgressCallback *cb=0)
+       {
+               if(!alive_flag)
+                       return false;
+               return warm_target->start_frame(cb);
+       }
+       
+       virtual bool add_tile(const sinfg::Surface &surface, int gx, int gy)
+       {
+               assert(surface);
+               if(!alive_flag)
+                       return false;
+               Glib::Mutex::Lock lock(mutex);
+               tile_queue.push_back(tile_t(surface,gx,gy));
+               if(tile_queue.size()==1)
+               {
+#ifdef GLIB_DISPATCHER_BROKEN
+               ready_connection=Glib::signal_timeout().connect(
+                       sigc::bind_return(
+                               sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready),
+                               false
+                       )
+                       ,0
+               );
+#else
+               tile_ready_signal();
+#endif
+               }
+               
+               return alive_flag;
+       }
+
+       void tile_ready()
+       {
+               Glib::Mutex::Lock lock(mutex);
+               if(!alive_flag)
+               {
+                       tile_queue.clear();
+                       cond_tile_queue_empty.signal();
+                       return;
+               }
+               while(!tile_queue.empty() && alive_flag)
+               {
+                       tile_t& tile(tile_queue.front());
+                       
+                       alive_flag=warm_target->add_tile(tile.surface,tile.x,tile.y);
+                       
+                       tile_queue.pop_front();
+               }
+               cond_tile_queue_empty.signal();
+       }
+
+       virtual void end_frame()
+       {
+               while(alive_flag)
+               {
+                       Glib::Mutex::Lock lock(mutex);
+                       if(!tile_queue.empty() && alive_flag)
+                       {
+                               if(cond_tile_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
+                                       break;
+                       }
+                       else
+                               break;
+               }
+               Glib::Mutex::Lock lock(mutex);
+               if(!alive_flag)
+                       return;
+               return warm_target->end_frame();
+       }
+};
+
+
+
+class AsyncTarget_Scanline : public sinfg::Target_Scanline
+{
+public:
+       etl::handle<sinfg::Target_Scanline> warm_target;
+       
+       int scanline_;
+       Surface surface;
+
+       Glib::Mutex mutex;
+       
+#ifndef GLIB_DISPATCHER_BROKEN
+       Glib::Dispatcher frame_ready_signal;
+#endif
+       Glib::Cond cond_frame_queue_empty;
+       bool alive_flag;
+       bool ready_next;
+       sigc::connection ready_connection;
+
+
+public:
+       AsyncTarget_Scanline(etl::handle<sinfg::Target_Scanline> warm_target):
+               warm_target(warm_target)
+       {
+               set_avoid_time_sync(warm_target->get_avoid_time_sync());
+               set_canvas(warm_target->get_canvas());
+               set_quality(warm_target->get_quality());
+               set_remove_alpha(warm_target->get_remove_alpha());
+               set_threads(warm_target->get_threads());
+               set_rend_desc(&warm_target->rend_desc());
+               alive_flag=true;
+#ifndef GLIB_DISPATCHER_BROKEN
+               ready_connection=frame_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready));
+#endif
+               surface.set_wh(warm_target->rend_desc().get_w(),warm_target->rend_desc().get_h());
+       }
+       
+       ~AsyncTarget_Scanline()
+       {
+               ready_connection.disconnect();
+       }
+
+       virtual int next_frame(Time& time)
+       {
+               if(!alive_flag)
+                       return 0;
+               return warm_target->next_frame(time);
+
+       }
+
+       void set_dead()
+       {
+               Glib::Mutex::Lock lock(mutex);
+               alive_flag=false;
+       }
+       
+       virtual bool start_frame(sinfg::ProgressCallback *cb=0)
+       {               
+               return alive_flag;
+       }
+       
+       virtual void end_frame()
+       {
+               {
+                       Glib::Mutex::Lock lock(mutex);
+
+                       if(!alive_flag)
+                               return;
+                       ready_next=false;
+
+#ifdef GLIB_DISPATCHER_BROKEN
+               ready_connection=Glib::signal_timeout().connect(
+                       sigc::bind_return(
+                               sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready),
+                               false
+                       )
+                       ,0
+               );
+#else
+                       frame_ready_signal();
+#endif
+                       }
+
+               while(alive_flag && !ready_next)
+               {
+                       Glib::Mutex::Lock lock(mutex);
+                       if(cond_frame_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
+                               break;
+               }
+       }
+
+       
+       virtual Color * start_scanline(int scanline)
+       {
+               Glib::Mutex::Lock lock(mutex);
+
+               return surface[scanline];
+       }
+       
+       virtual bool end_scanline()
+       {
+               return alive_flag;
+       }
+
+       void frame_ready()
+       {
+               Glib::Mutex::Lock lock(mutex);
+               if(alive_flag)
+                       alive_flag=warm_target->add_frame(&surface);
+               cond_frame_queue_empty.signal();
+               ready_next=true;
+       }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+AsyncRenderer::AsyncRenderer(etl::handle<sinfg::Target> target_,sinfg::ProgressCallback *cb):
+       error(false),
+       success(false),
+       cb(cb)
+{
+       render_thread=0;
+       if(etl::handle<sinfg::Target_Tile>::cast_dynamic(target_))
+       {
+               etl::handle<AsyncTarget_Tile> wrap_target(
+                       new AsyncTarget_Tile(etl::handle<sinfg::Target_Tile>::cast_dynamic(target_))
+               );
+               
+               signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Tile::set_dead));
+               
+               target=wrap_target;
+       }
+       else if(etl::handle<sinfg::Target_Scanline>::cast_dynamic(target_))
+       {
+               etl::handle<AsyncTarget_Scanline> wrap_target(
+                       new AsyncTarget_Scanline(
+                               etl::handle<sinfg::Target_Scanline>::cast_dynamic(target_)
+                       )
+               );
+       
+               signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Scanline::set_dead));
+               
+               target=wrap_target;
+       }
+}
+
+AsyncRenderer::~AsyncRenderer()
+{
+       stop();
+}
+
+void
+AsyncRenderer::stop()
+{
+       if(target)
+       {
+               Glib::Mutex::Lock lock(mutex);
+               done_connection.disconnect();
+       
+               if(render_thread)
+               {
+                       signal_stop_();
+               
+#if REJOIN_ON_STOP
+                       render_thread->join();
+#endif
+                       
+                       // Make sure all the dispatch crap is cleared out
+                       //Glib::MainContext::get_default()->iteration(false);
+                       
+                       if(success)
+                               signal_success_();
+                               
+                       signal_finished_();
+       
+                       target=0;
+                       render_thread=0;
+               }
+       }
+}
+
+void
+AsyncRenderer::pause()
+{
+}
+
+void
+AsyncRenderer::resume()
+{
+}
+
+void
+AsyncRenderer::start()
+{
+       done_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       mem_fun(*this,&AsyncRenderer::start_),
+                       false
+               )
+               ,50
+       );
+}
+
+void
+AsyncRenderer::start_()
+{
+       error=false;success=false;
+       if(target)
+       {
+#ifndef GLIB_DISPATCHER_BROKEN
+               done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop));
+#endif
+               
+               render_thread=Glib::Thread::create(
+                       sigc::mem_fun(*this,&AsyncRenderer::render_target),
+#if REJOIN_ON_STOP
+                       true
+#else
+                       false
+#endif
+               );
+               assert(render_thread);
+       }
+       else
+       {
+               stop();
+       }
+}
+
+void
+AsyncRenderer::render_target()
+{
+       etl::handle<Target> target(AsyncRenderer::target);
+       
+       if(target && target->render())
+       {
+               success=true;
+       }
+       else
+       {
+               error=true;
+#ifndef REJOIN_ON_STOP
+               return;
+#endif
+       }
+
+       if(mutex.trylock())
+       {
+#ifdef GLIB_DISPATCHER_BROKEN
+               done_connection=Glib::signal_timeout().connect(
+                       sigc::bind_return(
+                               mem_fun(*this,&AsyncRenderer::stop),
+                               false
+                       )
+                       ,0
+               );
+#else
+               signal_done_.emit();
+#endif
+               mutex.unlock();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/asyncrenderer.h b/synfig-studio/trunk/src/gtkmm/asyncrenderer.h
new file mode 100644 (file)
index 0000000..f9721c9
--- /dev/null
@@ -0,0 +1,109 @@
+/* === S I N F G =========================================================== */
+/*!    \file asyncrenderer.h
+**     \brief Template Header
+**
+**     $Id: asyncrenderer.h,v 1.3 2005/01/12 07:03:42 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_ASYNCRENDERER_H
+#define __SINFG_ASYNCRENDERER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <sigc++/signal.h>
+#include <sigc++/trackable.h>
+#include <sigc++/connection.h>
+
+#include <sinfg/target_scanline.h>
+#include <sinfg/target_tile.h>
+#include <sinfg/surface.h>
+#include <glibmm/main.h>
+#include <ETL/ref_count>
+#include <glibmm/thread.h>
+#include <glibmm/dispatcher.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class AsyncRenderer : public etl::shared_object, public sigc::trackable
+{
+       sigc::signal<void> signal_finished_;
+       sigc::signal<void> signal_success_;
+
+       std::list<sigc::connection> activity_connection_list;
+       
+       //etl::handle<sinfg::Target_Scanline> target_scanline;
+       //etl::handle<sinfg::Target_Tile> target_tile;
+       etl::handle<sinfg::Target> target;
+
+       bool error;
+       bool success;
+       
+       sinfg::ProgressCallback *cb;
+       
+       sigc::signal<void> signal_stop_;
+
+       Glib::Thread* render_thread;
+       Glib::Dispatcher signal_done_;
+       Glib::Mutex mutex;
+       sigc::connection done_connection;
+
+       /*
+ --    ** -- P A R E N T   M E M B E R S -----------------------------------------
+       */
+public:
+
+       AsyncRenderer(etl::handle<sinfg::Target> target,sinfg::ProgressCallback *cb=0);
+       virtual ~AsyncRenderer();
+
+       void start();
+       void stop();
+       void pause();
+       void resume();
+
+       bool has_error()const { return error; }
+       bool has_success()const { return success; }
+
+       sigc::signal<void>& signal_finished() { return signal_finished_; }
+       sigc::signal<void>& signal_success() { return signal_success_; }
+
+private:
+
+       void render_target();
+       void start_();
+
+       /*
+ --    ** -- C H I L D   M E M B E R S -------------------------------------------
+       */
+
+protected:
+       
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp b/synfig-studio/trunk/src/gtkmm/audiocontainer.cpp
new file mode 100644 (file)
index 0000000..dd3b295
--- /dev/null
@@ -0,0 +1,1393 @@
+/* === S I N F G =========================================================== */
+/*!    \file audiocontainer.cpp
+**     \brief Audio Container implementation File
+**
+**     $Id: audiocontainer.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <algorithm>
+#include <sigc++/signal.h>
+
+#include <ETL/stringf>
+#include <ETL/clock>
+//#include <ETL/thread>
+#include <glibmm/thread.h>
+
+#include <sinfg/general.h>
+
+#include <glibmm/main.h>
+
+#include "audiocontainer.h"
+
+#include <cstdio>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <set>
+#include <vector>
+
+#ifdef WITH_FMOD
+#include <fmod.h>
+#endif
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+#ifdef __WIN32
+#else //linux...
+#define AUDIO_OUTPUT   FSOUND_OUTPUT_OSS
+#endif
+
+/* === G L O B A L S ======================================================= */
+const double delay_factor = 3;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+//Help constructing stuff
+struct FSOUND_SAMPLE;
+using studio::AudioContainer;
+
+bool build_profile(FSOUND_SAMPLE *sample, double &samplerate, std::vector<char> &samples)
+{
+#ifdef WITH_FMOD
+       
+       float sps = samplerate;
+       
+       //trivial rejection...
+       if(!sample || sps < 1)
+       {
+               sinfg::warning("build_profile: Sample rate was too low or sample was invalid");
+               return false;
+       }
+       
+       //lock for all samples and process them into a subset
+       unsigned int mode = FSOUND_Sample_GetMode(sample);
+       
+       //make sure that it's 8 bit... I hope this works...
+       
+       //sample rate of the actual song...
+       int allsamplerate = 0;
+       FSOUND_Sample_GetDefaults(sample,&allsamplerate,0,0,0);
+       
+       //get the size of the sample defaults from the mode
+       int channels = 1;
+       int channelsize = 1; //number of bytes
+       
+       if(mode & FSOUND_16BITS) channelsize = 2; //this shouldn't happen
+       if(mode & FSOUND_STEREO) channels = 2;
+                       
+       //Get the sample information
+       int samplesize = channels*channelsize; //the only two things that increase samplesize
+       int numsamples = FSOUND_Sample_GetLength(sample); //number of samples in the sound
+       int sizeall = samplesize*numsamples; //should be the size of the entire song...
+       
+       if(sizeall <= 0)
+       {
+               sinfg::warning("ProfileAudio: Sample buffer cannot be size smaller than 1 (%X)",FSOUND_GetError());
+               return false;
+       }
+       
+       //be sure that the new sample rate is less than or equal to the original
+       if(sps > allsamplerate) sps = allsamplerate;
+               
+       float stride = allsamplerate/(float)sps;
+       
+       //down sampling to 8 bit min/max values 
+       sinfg::warning("About to downsample from %d Hz to %.1f Hz, sample stride: %f", allsamplerate, sps, stride);
+       
+       char *sampledata=0,*useless = 0;
+       unsigned int len1,len2;
+       // vector<char> samples;
+       {
+               if(!FSOUND_Sample_Lock(sample,0,sizeall,(void**)&sampledata,(void**)&useless,&len1,&len2))
+               {
+                       sinfg::warning("ProfileAudio: Unable to lock the sound buffer... (%X)",FSOUND_GetError());
+                       return false;
+               }
+               sinfg::warning("Locked: %X: %d bytes, %X: %d bytes",sampledata,len1,useless,len2);
+               
+               if(channelsize == 1)
+               {
+                       //process the data
+                       char *iter = sampledata;
+                       char *end = iter + sizeall;
+                       
+                       float curaccum = 0;
+                       float numinc = sps/(float)allsamplerate;
+                       
+                       /* Loop per sample DDA alg.
+                       */
+                       
+                       int i = 0;
+                       
+                       //HACK - to prevent if statement inside inner loop
+                       //sinfg::warning("wo baby wo baby, inc: %d, stride: %f, size: %d", inc, stride, sizeall);
+                       while(iter < end)
+                       {
+                               int maxs = 0, mins = 0;
+                               
+                               for(;curaccum < 1; curaccum += numinc)
+                               {
+                                       for(i = 0; iter < end && i < channels; ++i, iter += channelsize)
+                                       {
+                                               maxs = std::max(maxs,(int)*iter);
+                                               mins = std::min(mins,(int)*iter);
+                                       }
+                               }
+                               //insert onto new list
+                               samples.push_back(maxs);
+                               samples.push_back(mins);
+                                               
+                               //and flush all the used samples for curaccum
+                               curaccum -= 1;
+                       }
+               }else if(channelsize == 2)
+               {
+                       //process the data
+                       char *iter = sampledata;
+                       char *end = iter + sizeall;
+                       
+                       float curaccum = 0;
+                       float numinc = sps/(float)allsamplerate;
+                       
+                       /* Loop per sample DDA alg.
+                       */
+                       
+                       int i = 0;
+                       
+                       //HACK - to prevent if statement inside inner loop
+                       //sinfg::warning("wo baby wo baby, inc: %d, stride: %f, size: %d", inc, stride, sizeall);
+                       while(iter < end)
+                       {
+                               int maxs = 0, mins = 0;
+                               
+                               for(;curaccum < 1; curaccum += numinc)
+                               {
+                                       for(i = 0; iter < end && i < channels; ++i, iter += channelsize)
+                                       {
+                                               maxs = std::max(maxs,(int)*(short*)iter);
+                                               mins = std::min(mins,(int)*(short*)iter);
+                                       }
+                               }
+                               //insert onto new list
+                               samples.push_back(maxs / 256);
+                               samples.push_back(mins / 256);
+                                               
+                               //and flush all the used samples for curaccum
+                               curaccum -= 1;
+                       }
+               }
+       }
+       
+       sinfg::warning("Stats: %f seconds with %d bytes now %d bytes", (samples.size()/2)/sps, sizeall, samples.size());
+       sinfg::warning("                %f seconds before", numsamples/(float)allsamplerate);
+       
+       //we're done yay!, unlock
+       FSOUND_Sample_Unlock(sample,sampledata,useless,len1,len2);
+       sinfg::info("Unlocked");
+       
+       //FSOUND_PlaySound(FSOUND_FREE,sound); //test
+       
+       //we're done
+       samplerate = sps*2; //it must be x2 because we are sampling max and min
+       
+       return true;
+       
+       #else
+       
+       return false;
+       
+       #endif
+}
+
+
+//FMOD Systemwide Specific data mostly here...
+
+struct scrubinfo;
+       
+#ifdef WITH_FMOD
+static double  buffer_length_sec = 0;
+
+//------- Scrubbing --------------
+/* Scrubbing works as follows:
+
+       The sound is played using PlaySoundEx
+               we specify a user created DSP for scrubbing
+               set it initially to inactive
+
+       When the program initiates it
+               we set the initial data in the shared structure and activate the dsp unit
+               then for each cursor update we get we set the value in the shared structure
+*/
+
+/* Things to check:
+       If IsPlaying just governs the channel play/stop value or if it also concerns the pause state
+       
+*/
+
+//so we can know where to create all this stuff
+struct scrubinfo
+{
+       /*      Linearly fit the frequency to hit the desired zero point...
+       */      
+       /*struct scrubelement
+       {
+               double  pos;
+               double  dt;
+               //the amount of time left til the cursor hits this one
+               //      it's incremental so that the cursor must pass previous 
+               //      ones before decrementing this value
+       };      
+       */
+       
+       //the time it should take to get to the next position...
+       
+       //to prevent from writing to the same location at once... (pos, deltatime, delaystart)
+       //Glib::Mutex   lock;
+       
+       //the queue system would provide a more accurate representation...
+       volatile double pos;
+       volatile double deltatime;
+       
+       volatile double delaystart; //the amount of time we need to go before we start interpolating...
+       
+       volatile int    channel;
+
+       /*std::list<scrubelement>       queue;
+       
+       volatile int    channel;
+       
+       //current position is FSOUND_GetCurrentPosition and current time is always 0...
+       
+       void add(const scrubelement &elem)
+       {
+               lock.LockWrite();
+               
+               queue.push_back(elem);
+               
+               lock.UnlockWrite();
+       }
+       
+       //Function to safely get rid of all the old samples (dt < 0)
+       void flush()
+       {
+               lock.LockWrite();
+               
+               while(queue.size() && queue.front().dt < 0)
+               {
+                       queue.pop_front();
+               }
+               
+               lock.UnlockWrite();             
+       }*/
+       
+       void Lock()
+       {
+               //lock.lock();
+       }
+       
+       void Unlock()
+       {
+               //lock.unlock();
+       }
+       
+       //All parameters and state should be set by the time we get here...
+       void scrub_dsp_process()
+       {
+               const double epsilon = 1e-5;
+               
+               //Trivial reject... we go nowhere if we aren't playing (hit boundary...)
+               if(!FSOUND_IsPlaying(channel)) return;
+                       
+               //Get rid of all the old samples
+               //flush();
+               
+               //Trivial reject #2 - We also go nowhere with no future samples (pause)
+               /*if(queue.size() <= 0)
+               {
+                       FSOUND_SetPaused(channel,true);
+                       return;
+               }*/
+               
+               double dt = buffer_length_sec;
+               
+               //Lock ourselves so we don't die
+               Lock();
+               
+               //printf("DSP data: delay = %.3f s, pos = %d, dt = %.3f\n", delaystart, (int)pos, deltatime);
+               
+               //Check delay
+               if(delaystart > 0)
+               {
+                       delaystart -= dt;
+                       
+                       if(delaystart < 0)
+                       {
+                               dt = -delaystart; //add time back...
+                               delaystart = 0;
+                       }
+               }
+               
+               //Trivial reject for if we're past current sample...
+               if(delaystart > 0 || deltatime <= 0)
+               {
+                       FSOUND_SetPaused(channel,true);
+                       Unlock();
+                       return;
+               }
+                       
+               //Calculate stretched frequency based on delayed future sample...
+               
+               //NOTE: BY NOT TRACKING POSITION AS A FLOAT AND JUST USING THE SOUNDS VALUE
+               //              WE ARE LOSING A TINY AMOUNT OF PRECISION ACCURACY EVERY UPDATE 
+               //              (THIS SHOULDN'T BE A PROBLEM)
+               const double p0 = FSOUND_GetCurrentPosition(channel);           
+               double curdp = 0;
+               
+               if(!FSOUND_GetPaused(channel))
+               {
+                       curdp = FSOUND_GetFrequency(channel) * deltatime;
+               }
+
+               //need to rescale derivative...         
+
+               //Extrapolate from difference in position and deltatime vs dt...
+               const double pa = p0 + curdp/2;
+               
+               const double p1 = pos;
+               
+               //const double pb = p0/3 + p1*2/3;
+               
+               //will extrapolate if needed... (could be funky on a curve)
+               double t = 0;
+               if(deltatime > epsilon)
+               {
+                       t = dt / deltatime;
+               }
+               
+               //Decrement deltatime (we may have gone past but that's what happens when we don't get input...)
+               deltatime -= dt;
+               
+               //we don't need to look at the current variables anymore...
+               Unlock();
+                               
+               const double invt = 1-t;
+               //double deltapos = (p1-p0)*t; //linear version
+               double deltapos = invt*invt*p0 + 2*t*invt*pa + t*t*p1 - p0; //quadratic smoothing version
+               
+               //Attempted cubic smoothing
+               //const double invt2 = invt*invt;
+               //const double t2 = t*t;
+               //double deltapos = invt2*invt*p0 + 3*t*invt2*pa + 3*t2*invt*pb + t2*t*p1;
+               //double deltapos = p0 + t*(3*(pa-p0) + t*(3*(p0+2*pa+pb) + t*((p1-3*pb+3*ba-p0)))); //unwound cubic
+                               
+               //printf("\ttime = %.2f; p(%d,%d,%d) dp:%d - delta = %d\n",t,(int)p0,(int)p1,(int)p2,(int)curdp,(int)deltapos);
+               
+               //Based on the delta info calculate the stretched frequency
+               const int dest_samplesize = FSOUND_DSP_GetBufferLength();
+               
+               //rounded to nearest frequency... (hopefully...)
+               int freq = (int)(deltapos * FSOUND_GetOutputRate() / (double)dest_samplesize);
+               
+               //NOTE: WE MIGHT WANT TO DO THIS TO BE MORE ACCURATE BUT YEAH... ISSUES WITH SMALL NUMBERS
+               //double newdp = deltapos / t;
+
+               //printf("\tfreq = %d Hz\n", freq);
+               
+               // !If I failed... um assume we have to pause it... ?
+               if(abs(freq) < 100)
+               {
+                       FSOUND_SetPaused(channel,true);
+               }else
+               {
+                       //sinfg::info("DSP f = %d Hz", freq);
+                       FSOUND_SetPaused(channel,false);
+                       if(!FSOUND_SetFrequency(channel,freq))
+                       {
+                               //ERROR WILL ROBINSON!!!...                     
+                               printf("Error in Freq... what do I do?\n");
+                       }
+               }
+       }       
+};
+
+struct scrubuserdata
+{
+       /* //for use with multiple
+       //each one is a 'handle' to a pointer that will be effected by something else
+       typedef scrubinfo**     value_type;
+       typedef std::set< value_type > scrubslist;
+       scrubslist              scrubs;
+       
+       //so we can lock access to the list...
+       ReadWriteLock   lock;
+       
+       void AddScrub(scrubinfo **i)
+       {
+               lock.LockWrite();
+               scrubs.insert(i);
+               lock.UnLockWrite();
+       }
+       
+       void RemoveScrub(scrubinfo **i)
+       {
+               lock.LockWrite();
+               scrubs.erase(i);
+               lock.UnLockWrite();             
+       }*/
+       
+       scrubinfo * volatile *  scrub;
+};
+
+//Scrubbing data structures
+static const int               default_scrub_priority = 5; //between clear and sfx/music mix
+static scrubuserdata   g_scrubdata = {0};
+static FSOUND_DSPUNIT  *scrubdspunit = 0;
+
+void * scrubdspwrap(void *originalbuffer, void *newbuffer, int length, void *userdata)
+{
+       //std::string   dsp = "DSP";
+       if(userdata)
+       {
+               scrubuserdata &sd = *(scrubuserdata*)userdata;
+               
+               /* //For use with multiple scrubs...
+               //Lock so no one can write to it while we're reading from it...
+               sd.lock.LockRead();
+               
+               //make a copy of it...          
+               std::vector<scrubinfo**>        v(sd.scrubs.begin(),sd.scrubs.end());
+               
+               //other things can do stuff with it again...
+               sd.lock.UnLockRead();
+               
+               //loop through the list and process all the active scrub units          
+               std::vector<scrubinfo**>::iterator      i = v.begin(),
+                                                                                       end = v.end();          
+               for(;i != end; ++i)
+               {
+                       //check to make sure this object is active...
+                       if(*i && **i)
+                       {
+                               (**i)->scrub_dsp_process();
+                       }
+               }
+               */
+               
+               if(sd.scrub && *sd.scrub)
+               {
+                       //dsp += " processing...";
+                       scrubinfo * info = (*sd.scrub);                 
+                       info->scrub_dsp_process();
+               }
+       }
+       
+       //sinfg::info(dsp);
+
+       return newbuffer;
+}
+
+//------- Class for loading fmod on demand -------
+
+class FMODInitializer
+{
+       bool loaded;
+       int     refcount;
+       
+public:
+       FMODInitializer():loaded(false),refcount(0) {}
+       ~FMODInitializer() 
+       {
+               clear();
+       }
+       
+       void addref()
+       {
+               if(!loaded)
+               {
+                       #ifdef WITH_FMOD
+                       sinfg::info("Initializing FMOD on demand...");
+                       
+                       {
+                               FSOUND_SetOutput(AUDIO_OUTPUT);
+                               
+                               /*int numdrivers = FSOUND_GetNumDrivers();
+                               sinfg::info("Num FMOD drivers = %d",numdrivers);
+                               sinfg::info("Current Driver is #%d", FSOUND_GetDriver());
+                               
+                               for(int i = 0; i < numdrivers; ++i)
+                               {
+                                       unsigned int caps = 0;
+                                       FSOUND_GetDriverCaps(i,&caps);
+                                       
+                                       sinfg::info("   Caps for driver %d (%s) = %x",i,FSOUND_GetDriverName(i),caps);
+                               }
+                               
+                               FSOUND_SetDriver(0);*/
+                               
+                               //Modify buffer size...
+                               //FSOUND_SetBufferSize(100);
+                               
+                               if(!FSOUND_Init(44100, 32, 0))
+                               {
+                                       sinfg::warning("Unable to load FMOD");
+                               }else
+                               {
+                                       loaded = true;
+                                       
+                                       //Create the DSP for processing scrubbing...
+                                       scrubdspunit = FSOUND_DSP_Create(&scrubdspwrap,default_scrub_priority,&g_scrubdata);
+                                       
+                                       //Load the number of sec per buffer into the global variable...
+                                       buffer_length_sec = FSOUND_DSP_GetBufferLength() / (double)FSOUND_GetOutputRate();
+                               }
+                       }
+                       #endif
+               }
+               
+               //add to the refcount
+               ++refcount;
+               //sinfg::info("Audio: increment fmod refcount %d", refcount);
+       }
+       
+       void decref()
+       {
+               if(refcount <= 0)
+               {
+                       sinfg::warning("FMOD refcount is already 0...");
+               }else
+               {
+                       --refcount;
+                       //sinfg::info("Audio: decrement fmod refcount %d", refcount);
+                       
+                       //NOTE: UNCOMMENT THIS IF YOU WANT FMOD TO UNLOAD ITSELF WHEN IT ISN'T NEEDED ANYMORE...
+                       flush();
+               }
+       }
+
+       bool is_loaded() const { return loaded; }
+       
+       void clear()
+       {
+               refcount = 0;
+               flush();
+       }
+       
+       void flush()
+       {
+               if(loaded && refcount <= 0)
+               {
+                       #ifdef WITH_FMOD
+                       sinfg::info("Unloading FMOD");
+                       if(scrubdspunit) FSOUND_DSP_Free(scrubdspunit);
+                       FSOUND_Close();                 
+                       #endif
+                       loaded = false;
+               }
+       }
+};
+
+//The global counter for FMOD....
+FMODInitializer                fmodinit;
+
+#endif
+
+//----- AudioProfile Implementation -----------
+void studio::AudioProfile::clear()
+{
+       samplerate = 0;
+       samples.clear();
+}
+
+handle<AudioContainer> studio::AudioProfile::get_parent() const
+{
+       return parent;
+}
+
+void studio::AudioProfile::set_parent(etl::handle<AudioContainer> i)
+{
+       parent = i;
+}
+
+double studio::AudioProfile::get_offset() const
+{
+       if(parent)
+               return parent->get_offset();
+       return 0;
+}
+
+//---------- AudioContainer definitions ---------------------
+
+struct studio::AudioContainer::AudioImp
+{      
+       //Sample load time information
+       FSOUND_SAMPLE *         sample;
+       int                                     channel;
+       int                                     sfreq;
+       int                                     length;
+       
+       //Time information
+       double                          offset; //time offset for playing...
+       
+       //We don't need it now that we've adopted the play(t) time schedule...
+       //current time... and playing info.... 
+       //float                         seekpost;
+       //bool                          useseekval;
+       
+       //Make sure to sever our delayed start if we are stopped prematurely
+       sigc::connection        delaycon;
+       
+       //Action information
+       bool                            playing;
+       double                          curscrubpos;
+       etl::clock                      timer;  //for getting the time diff between scrub input points
+               
+       //Scrubbing information...
+       //the current position of the sound will be sufficient for normal stuff...
+       #ifdef WITH_FMOD
+       scrubinfo                       scrinfo;
+       #endif
+       
+       scrubinfo                       *scrptr;
+       
+       bool is_scrubbing() const {return scrptr != 0;}
+       void set_scrubbing(bool s)
+       {
+               #ifdef WITH_FMOD
+               if(s)
+                       scrptr = &scrinfo;
+               else 
+               #endif
+               scrptr = 0;
+       }
+       
+       //helper to make sure we are actually playing (and to get a new channel...)
+       bool init_play()
+       {
+               #ifdef WITH_FMOD
+               if(!FSOUND_IsPlaying(channel))
+               {
+                       if(sample)
+                       {
+                               //play sound paused etc.
+                               channel = FSOUND_PlaySoundEx(FSOUND_FREE,sample,0,true);
+                               if(channel < 0 || FSOUND_GetError() != FMOD_ERR_NONE)
+                               {
+                                       sinfg::warning("Could not play the sample...");
+                                       return false;
+                               }
+                       }
+               }else
+               {
+                       FSOUND_SetPaused(channel,true);
+                       FSOUND_SetFrequency(channel,sfreq);
+               }
+               return true;
+               
+               #else
+               
+               return false;
+               
+               #endif
+       }
+       
+public: //structors
+       AudioImp()
+       :sample(0),
+       channel(0),
+       sfreq(0),
+       length(0),
+       offset(0),
+       playing(false),
+       scrptr(0)       
+       {
+               //reuse the channel...
+               #ifdef WITH_FMOD
+               channel = FSOUND_FREE;
+               #endif
+       }
+       
+       ~AudioImp()
+       {
+               clear();
+       }
+       
+public: //helper/accessor funcs
+       bool start_playing_now() //callback for timer...
+       {
+               #ifdef WITH_FMOD
+               if(playing)
+               {
+                       //Make sure the sound is playing and if it is un pause it...
+                       if(init_play())
+                               FSOUND_SetPaused(channel,false);
+               }
+               #endif
+               
+               return false; //so the timer doesn't repeat itself
+       }       
+       
+       bool isRunning()
+       {
+               #ifdef WITH_FMOD
+               return FSOUND_IsPlaying(channel);
+               #else
+               return false;
+               #endif
+       }
+       
+       bool isPaused()
+       { 
+#ifdef WITH_FMOD
+               return FSOUND_GetPaused(channel);
+#else
+               return false;
+#endif
+       }
+               
+       
+public: //forward interface
+       
+       //Accessors for the offset - in seconds
+       const double &get_offset() const {return offset;}
+       void set_offset(const double &d) 
+       {
+               offset = d;
+       }
+       
+       //Will override the parameter timevalue if the sound is running, and not if it's not...
+       bool get_current_time(double &out)
+       {
+               if(isRunning())
+               {
+                       #ifdef WITH_FMOD
+                       unsigned int pos = FSOUND_GetCurrentPosition(channel);
+                       
+                       //adjust back by 1 frame... HACK....
+                       //pos -= FSOUND_DSP_GetBufferLength();
+                       
+                       //set the position
+                       out = pos/(double)sfreq + offset;
+                       #endif
+                       
+                       return true;
+               }
+               return false;
+       }
+       
+       //Big implementation functions...
+       bool load(const std::string &filename, const std::string &filedirectory);
+       void clear();
+       
+       //playing functions
+       void play(double t);
+       void stop();
+       
+       //scrubbing functions
+       void start_scrubbing(double t);
+       void scrub(double t);
+       void stop_scrubbing();
+       
+       double scrub_time()
+       {
+               return curscrubpos;
+       }
+};
+
+//--------------- Audio Container definitions --------------------------
+studio::AudioContainer::AudioContainer()
+{
+       imp = 0;
+}
+
+studio::AudioContainer::~AudioContainer()
+{
+       if(imp) delete (imp);
+}
+
+bool studio::AudioContainer::load(const string &filename,const string &filedirectory)
+{
+       if(!imp)
+       {
+               imp = new AudioImp;
+       }
+       
+       profilevalid = false;
+       return imp->load(filename,filedirectory);
+}
+
+handle<studio::AudioProfile> studio::AudioContainer::get_profile(float samplerate)
+{
+       #ifdef WITH_FMOD
+       
+       //if we already have done our work, then we're good
+       if(profilevalid && prof)
+       {
+               //sinfg::info("Using already built profile");
+               return prof;
+       }
+       
+       //sinfg::info("Before profile");
+       //make a new profile at current sample rate
+       
+       //NOTE: We might want to reuse the structure already there...   
+       prof = new AudioProfile;
+       prof->set_parent(this); //Our parent is THIS!!!
+       
+       if(!prof)
+       {
+               sinfg::warning("Couldn't allocate audioprofile...");
+               return handle<studio::AudioProfile>();
+       }
+       
+       //setting the info for the sample rate
+       //sinfg::info("Setting info...");
+       
+       sinfg::info("Building Profile...");
+       prof->samplerate = samplerate;
+       if(build_profile(imp->sample,prof->samplerate,prof->samples))
+       {
+               sinfg::info("   Success!");
+               profilevalid = true;
+               return prof;
+       }else
+       {
+               return handle<studio::AudioProfile>();
+       }
+       
+       #else
+       
+       return handle<studio::AudioProfile>();
+       
+       #endif
+}
+
+void studio::AudioContainer::clear()
+{
+       if(imp) 
+       {
+               delete imp;
+               imp = 0;
+       }
+       
+       profilevalid = false;
+}
+       
+void studio::AudioContainer::play(double t)
+{
+       if(imp) imp->play(t);
+}
+
+void studio::AudioContainer::stop()
+{
+       if(imp) imp->stop();
+}
+
+bool studio::AudioContainer::get_current_time(double &out)
+{
+       if(imp) return imp->get_current_time(out);
+       else return false;
+}
+
+void AudioContainer::set_offset(const double &s)
+{
+       if(imp) imp->set_offset(s);
+}
+
+double AudioContainer::get_offset() const
+{
+       static double zero = 0;
+       if(imp)
+               return imp->get_offset();
+       return zero;
+}
+
+bool AudioContainer::is_playing() const
+{
+       if(imp) 
+               return imp->playing;
+       return false;
+}
+
+bool AudioContainer::is_scrubbing() const
+{
+       if(imp) 
+               return imp->is_scrubbing();
+       return false;
+}
+
+void AudioContainer::start_scrubbing(double t)
+{
+       if(imp) imp->start_scrubbing(t);
+}
+
+void AudioContainer::stop_scrubbing()
+{
+       if(imp) imp->stop_scrubbing();
+}
+
+void AudioContainer::scrub(double t)
+{
+       if(imp) imp->scrub(t);
+}
+
+double AudioContainer::scrub_time() const
+{
+       if(imp) return imp->scrub_time();
+       else return 0;
+}
+
+bool AudioContainer::isRunning() const
+{
+       if(imp) return imp->isRunning();
+       else return false;
+}
+
+bool AudioContainer::isPaused() const
+{
+       if(imp) return imp->isPaused();
+       else return false;
+}
+
+//----------- Audio imp information -------------------
+
+bool studio::AudioContainer::AudioImp::load(const std::string &filename, 
+                                                                                       const std::string &filedirectory)
+{
+       clear();
+
+       #ifdef WITH_FMOD
+       
+       //And continue with the sound loading...
+       string  file = filename;
+       
+       //Trivial reject... (fixes stat call problem... where it just looks at directory and not file...)
+       if(file.length() == 0) return false;
+       
+       //we don't need the file directory?
+       if(!is_absolute_path(file))
+       {
+               file=filedirectory+filename;
+               sinfg::warning("Not absolute hoooray");
+       }
+       sinfg::info("Loading Audio file: %s", file.c_str());
+       
+       //check to see if file exists
+       {
+               struct stat     s;
+               if(stat(file.c_str(),&s) == -1 && errno == ENOENT)
+               {
+                       sinfg::info("There was no audio file...");                      
+                       return false;
+               }
+       }
+       
+       //load fmod if we can...
+       //sinfg::warning("I'm compiled with FMOD!");
+       fmodinit.addref();
+       
+       //load the stream
+       int ch = FSOUND_FREE;
+       FSOUND_SAMPLE *sm = FSOUND_Sample_Load(FSOUND_FREE,file.c_str(),FSOUND_LOOP_OFF|FSOUND_MPEGACCURATE,0,0);
+       
+       if(!sm)
+       {
+               sinfg::warning("Could not open the audio file as a sample: %s",file.c_str());
+               goto error;
+       }
+       
+       //sinfg::warning("Opened a file as a sample! :)");
+       
+       /*{
+               int bufferlen = FSOUND_DSP_GetBufferLength();
+               sinfg::info("Buffer length = %d samples, %.3lf s",bufferlen, bufferlen / (double)FSOUND_GetOutputRate());
+       }*/
+       
+       //set all the variables since everything has worked out...
+       //get the length of the stream
+       {
+               length = FSOUND_Sample_GetLength(sm);
+               
+               int volume = 0;
+               FSOUND_Sample_GetDefaults(sm,&sfreq,&volume,0,0);
+               
+               //double len = length / (double)sfreq;          
+               //sinfg::info("Sound info: %.2lf s long, %d Hz, %d Vol",(double)length,sfreq,volume);
+       }
+       
+       //sinfg::warning("Got all info, and setting up everything, %.2f sec.", length);
+       //sinfg::warning("      BigSample: composed of %d samples", FSOUND_Sample_GetLength(sm));
+       sinfg::info("Successfully opened %s as a sample and initialized it.",file.c_str());
+       
+       //set up the playable info
+       sample = sm;
+       channel = ch;
+       
+       //the length and sfreq params have already been initialized
+       
+       return true;
+       
+error:
+       if(sm) FSOUND_Sample_Free(sm);
+       file = "";
+       
+       fmodinit.decref();
+       
+       return false;
+       
+       #else
+       return false;
+       #endif
+}
+
+void studio::AudioContainer::AudioImp::play(double t)
+{
+       #ifdef WITH_FMOD
+       if(!sample) return;
+       
+       //stop scrubbing if we are...
+       if(is_scrubbing()) stop_scrubbing();
+       
+       //t -= offset;
+       t -= get_offset();
+       playing = true;
+       
+       if(t < 0)
+       {
+               unsigned int timeout = (int)floor(-t * 1000 + 0.5);
+               //sinfg::info("Playing audio delayed by %d ms",timeout);
+               //delay for t seconds...
+               delaycon = Glib::signal_timeout().connect(
+                                               sigc::mem_fun(*this,&studio::AudioContainer::AudioImp::start_playing_now),timeout);             
+               
+               init_play();
+               FSOUND_SetFrequency(channel,sfreq);
+               FSOUND_SetCurrentPosition(channel,0);
+               return;
+       }
+       
+       unsigned int position = (int)floor(t*sfreq + 0.5);
+       
+       if(position >= FSOUND_Sample_GetLength(sample))
+       {
+               sinfg::warning("Can't play audio when past length...");
+               return;
+       }
+       
+       init_play();
+       FSOUND_SetFrequency(channel,sfreq);
+       FSOUND_SetCurrentPosition(channel,position);
+       FSOUND_SetPaused(channel,false);
+       
+       //sinfg::info("Playing audio with position %d samples",position);
+       
+       #endif          
+}
+
+void studio::AudioContainer::AudioImp::stop()
+{
+       delaycon.disconnect();
+
+       #ifdef WITH_FMOD
+       if(fmodinit.is_loaded() && playing && isRunning())
+       {               
+               FSOUND_SetPaused(channel,true);
+       }
+       #endif
+       
+       playing = false;
+}
+
+void studio::AudioContainer::AudioImp::clear()
+{
+       #ifdef WITH_FMOD
+       delaycon.disconnect();
+       
+       stop();
+       stop_scrubbing();
+                       
+       if(sample)
+       {
+               if(FSOUND_IsPlaying(channel))
+               {
+                       FSOUND_StopSound(channel);
+               }
+               channel = FSOUND_FREE;
+               FSOUND_Sample_Free(sample);
+               fmodinit.decref();
+       }
+       
+       playing = false;
+       
+       #else
+       channel = 0;
+       #endif
+       
+       sample = 0;
+       playing = false;        
+}
+
+void AudioContainer::AudioImp::start_scrubbing(double t)
+{
+       //sinfg::info("Start scrubbing: %lf", t);
+       if(playing) stop();
+                       
+       set_scrubbing(true);
+       
+       #ifdef WITH_FMOD
+       //make sure the other one is not scrubbing...
+       if(g_scrubdata.scrub)
+       {
+               *g_scrubdata.scrub = 0; //nullify the pointer...
+       }
+       
+       //Set up the initial state for the delayed audio position
+       scrinfo.delaystart = 0;
+       scrinfo.pos = 0;
+       scrinfo.deltatime = 0;
+       
+       //set it to point to our pointer (dizzy...)
+       g_scrubdata.scrub = &scrptr;
+
+       //setup position info so we can know what to do on boundary conditions...
+       curscrubpos = (t - get_offset()) * sfreq;
+       
+       //So we can get an accurate difference...
+       timer.reset();
+       
+       //reposition the sound if it won't be when scrubbed (if it's already in the range...)   
+       int curi = (int)curscrubpos;
+       if(curi >= 0 && curi < length)
+       {
+               init_play();
+               FSOUND_SetCurrentPosition(channel,curi);
+               
+               //Set the values...
+               scrinfo.pos = curscrubpos;
+               scrinfo.delaystart = delay_factor*buffer_length_sec;
+                               
+               //sinfg::info("\tStarting at %d samps, with %d p %.3f delay",
+               //                              FSOUND_GetCurrentPosition(channel), (int)scrinfo.pos, scrinfo.delaystart);
+       }
+       
+       
+       
+       //enable the dsp...
+       //sinfg::info("\tActivating DSP");
+       FSOUND_DSP_SetActive(scrubdspunit,true);
+       #endif
+}
+
+void AudioContainer::AudioImp::stop_scrubbing()
+{
+       //sinfg::info("Stop scrubbing");
+       
+       if(is_scrubbing())
+       {
+               set_scrubbing(false);
+               
+               #ifdef WITH_FMOD
+               g_scrubdata.scrub = 0;
+       
+               //stop the dsp...
+               //sinfg::info("\tDeactivating DSP");
+               FSOUND_DSP_SetActive(scrubdspunit,false);
+               if(FSOUND_IsPlaying(channel)) FSOUND_SetPaused(channel,true);
+               #endif
+       }
+       
+       curscrubpos = 0;
+}
+
+void AudioContainer::AudioImp::scrub(double t)
+{
+       #ifdef WITH_FMOD
+       //sinfg::info("Scrub to %lf",t);
+       if(is_scrubbing())
+       {               
+               //What should we do?
+               
+               /* Different special cases
+                       All outside, all inside,
+                       coming in (left or right),
+                       going out (left or right)
+               */
+               double oldpos = curscrubpos;
+               double newpos = (t - get_offset()) * sfreq;
+               
+               curscrubpos = newpos;
+               
+               //Ok the sound is running, now we need to tweek it              
+               if(newpos > oldpos)
+               {
+                       //Outside so completely stopped...
+                       if(newpos < 0 || oldpos >= length)
+                       {
+                               //sinfg::info("\tOut +");
+                               if(FSOUND_IsPlaying(channel))
+                               {
+                                       FSOUND_SetPaused(channel,true);
+                               }
+
+                               //Zero out the data!
+                               scrinfo.Lock();
+                               scrinfo.delaystart = 0;
+                               scrinfo.deltatime = 0;
+                               scrinfo.Unlock();
+                               
+                               return;
+                       }
+                       
+                       //going in? - start the sound at the beginning...
+                       /*else if(oldpos < 0)
+                       {
+                               //Set up the sound to be playing paused at the start...
+                               init_play();
+                               FSOUND_SetCurrentPosition(channel,0);
+                               
+                               sinfg::info("\tIn + %d", FSOUND_GetCurrentPosition(channel));
+                               
+                               scrinfo.Lock();
+                               scrinfo.pos = 0;
+                               scrinfo.delaystart = delay_factor*buffer_length_sec;
+                               scrinfo.deltatime = 0;
+                               scrinfo.Unlock();
+                       }*/
+                       //don't need to deal with leaving... automatically dealt with...
+                       
+                       else //We're all inside...
+                       {
+                               //Set new position and decide what to do with time...
+                               scrinfo.Lock();
+                               scrinfo.pos = newpos;
+                       
+                               //should we restart the delay cycle... (is it done?)                            
+                               if(!isRunning() || (scrinfo.delaystart <= 0 && scrinfo.deltatime <= 0 && isPaused()))
+                               {
+                                       //sinfg::info("Starting + at %d",(int)newpos);
+                                       scrinfo.deltatime = 0;
+                                       scrinfo.delaystart = delay_factor*buffer_length_sec;
+                                       scrinfo.Unlock();
+                                       
+                                       //Set up the sound paused at the current position
+                                       init_play();
+                                       int setpos = min(max((int)newpos,0),length);
+                                       FSOUND_SetCurrentPosition(channel,setpos);
+                                       timer.reset();
+                                       return;
+                               }
+                               
+                               //No! just increment the time delta...
+                               scrinfo.deltatime += timer.pop_time();
+                               
+                               //Nope... continue and just increment the deltatime and reset position...
+                               scrinfo.Unlock();
+                                                       
+                               //set channel and unpause
+                               FSOUND_SetPaused(channel,false);
+                               scrinfo.channel = channel;
+                                                               
+                       }
+               }else if(newpos < oldpos)
+               {
+                       //completely stopped...
+                       if(newpos >= length || oldpos < 0)
+                       {
+                               //sinfg::info("Out -");
+                               if(FSOUND_IsPlaying(channel))
+                               {
+                                       FSOUND_SetPaused(channel,true);
+                               }
+                               
+                               //Zero out the data!
+                               scrinfo.Lock();
+                               scrinfo.delaystart = 0;
+                               scrinfo.deltatime = 0;
+                               scrinfo.Unlock();
+                       }
+                       
+                       //going in? - start going backwards at the end...
+                       /*else if(oldpos >= length)
+                       {
+                               sinfg::info("In -");
+                               //Set up the sound to be playing paused at the start...
+                               init_play();
+                               FSOUND_SetCurrentPosition(channel,length-1);                            
+                               
+                               scrinfo.Lock();
+                               scrinfo.pos = length-1;
+                               scrinfo.delaystart = delay_factor*buffer_length_sec;
+                               scrinfo.deltatime = 0;
+                               scrinfo.Unlock();
+                       }*/
+                       //we don't have to worry about the leaving case...
+                       
+                       else //We're all inside...
+                       {
+                               //Set new position and decide what to do with time...
+                               scrinfo.Lock();
+                               scrinfo.pos = newpos;
+                       
+                               //should we restart the delay cycle... (is it done?)                            
+                               if(!isRunning() ||(scrinfo.delaystart <= 0 && scrinfo.deltatime <= 0 && isPaused()))
+                               {
+                                       //sinfg::info("Starting - at %d",(int)newpos);
+                                       scrinfo.deltatime = 0;
+                                       scrinfo.delaystart = delay_factor*buffer_length_sec;
+                                       scrinfo.Unlock();
+                                       
+                                       //reset timing so next update will be a valid diff... 
+                                       init_play();
+                                       int setpos = min(max((int)newpos,0),length);
+                                       FSOUND_SetCurrentPosition(channel,setpos);
+                                       timer.reset();
+                                       return;
+                               }
+                               
+                               //No! just increment the time delta...
+                               scrinfo.deltatime += timer.pop_time();
+                               
+                               //Nope... continue and just increment the deltatime and reset position...
+                               scrinfo.Unlock();
+                                                       
+                               //set channel and unpause
+                               FSOUND_SetPaused(channel,false);
+                               scrinfo.channel = channel;
+                       }
+               }
+       }
+       #endif
+}
diff --git a/synfig-studio/trunk/src/gtkmm/audiocontainer.h b/synfig-studio/trunk/src/gtkmm/audiocontainer.h
new file mode 100644 (file)
index 0000000..cc449e8
--- /dev/null
@@ -0,0 +1,138 @@
+/* === S I N F G =========================================================== */
+/*!    \file audiocontainer.h
+**     \brief Sound info header
+**
+**     $Id: audiocontainer.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_AUDIOCONTAINER_H
+#define __SINFG_AUDIOCONTAINER_H
+
+/* === H E A D E R S ======================================================= */
+#include <sigc++/signal.h>
+
+#include <ETL/handle>
+
+#include <vector>
+#include <string>
+
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+const float DEF_DISPLAYSAMPLERATE = 400;
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class AudioContainer;
+
+//Note: Might want to abstract something to share data between profile and parent
+class AudioProfile : public etl::shared_object
+{
+public:
+       typedef std::vector<char>       SampleProfile;
+       
+private:
+       SampleProfile   samples;
+       double                  samplerate; //samples / second of the profile
+
+       //reference our parent for any native sound info
+       etl::loose_handle<AudioContainer>       parent;
+
+public:        //samples interface
+
+       SampleProfile::const_iterator   begin() const   {return samples.begin();}
+       SampleProfile::const_iterator   end() const     {return samples.end();}
+       
+       void clear();
+       unsigned int size() const {return samples.size();}
+       
+       char operator[](int i) const
+       {
+               if(i >= 0 && i < (int)samples.size()) return samples[i];
+               else return 0;
+       }
+       
+public: //
+       
+       double get_samplerate() const {return samplerate;}
+       void set_samplerate(double f) {samplerate = f;}
+       
+       double get_offset() const;
+       
+       etl::handle<AudioContainer>     get_parent() const;
+       void set_parent(etl::handle<AudioContainer> i);
+       friend class AudioContainer;
+};
+
+/*     Audio container actually implements all the cool stuff
+       Note: May be a bit to monolithic...
+*/
+class AudioContainer : public sigc::trackable, public etl::shared_object
+{
+       etl::handle<AudioProfile>       prof;
+       
+       struct  AudioImp;
+       AudioImp *imp;
+       
+       bool    profilevalid; //this is only half useful 
+               //it makes it so we don't always have to realloc memory when the file switches...
+       
+public: //structors
+
+       AudioContainer();
+       ~AudioContainer();
+
+public: //accessor interface
+       void set_offset(const double &s);
+       double get_offset() const;
+
+public: //info gather interface
+       etl::handle<AudioProfile>       get_profile(float samplerate = DEF_DISPLAYSAMPLERATE);
+       bool get_current_time(double &out);
+
+public: //operational interface
+       bool load(const std::string &filename, const std::string &filedirectory = "");
+       void clear();
+
+       //play functions...
+       void play(double t);
+       void stop();
+       //Note: this refers to the wrapper concept of the audio, the actual sound may or may not be playing...
+       bool is_playing() const;
+       
+       //scrubbing functions...
+       void start_scrubbing(double t);
+       void stop_scrubbing();
+       void scrub(double t); //!< if we are not currently scrubbing this will not work
+       bool is_scrubbing() const;
+
+       double scrub_time() const;
+
+       bool isRunning() const;
+       bool isPaused() const;
+};
+       
+} // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/autorecover.cpp b/synfig-studio/trunk/src/gtkmm/autorecover.cpp
new file mode 100644 (file)
index 0000000..06c1db3
--- /dev/null
@@ -0,0 +1,320 @@
+/* === S I N F G =========================================================== */
+/*!    \file autorecover.cpp
+**     \brief Template File
+**
+**     $Id: autorecover.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "autorecover.h"
+
+//#include <unistd.h>
+#include "app.h"
+#include <sinfg/savecanvas.h>
+#include <sinfg/loadcanvas.h>
+#include <fstream>
+#include <iostream>
+#include "instance.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifdef _WIN32
+#define mkdir(x,y) mkdir(x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+AutoRecover::AutoRecover()
+{
+       // Three Minutes
+       set_timeout(3*60*1000);
+       
+       if(mkdir(get_shadow_directory().c_str(),ACCESSPERMS)<0)
+       {
+               if(errno!=EEXIST)
+                       sinfg::error("UNABLE TO CREATE \"%s\"",get_shadow_directory().c_str());
+       }
+       else
+       {
+               sinfg::info("Created directory \"%s\"",get_shadow_directory().c_str());
+       }
+}
+
+AutoRecover::~AutoRecover()
+{
+}
+
+sinfg::String
+AutoRecover::get_shadow_directory()
+{
+       return Glib::build_filename(App::get_user_app_directory(),"tmp");
+}
+
+int
+AutoRecover::pid()
+{
+//     return getpid();
+       return 0;
+}
+
+void
+AutoRecover::set_timeout(int milliseconds)
+{
+       timeout=milliseconds;
+       auto_backup_connect.disconnect();
+       if(timeout)
+               auto_backup_connect=Glib::signal_timeout().connect(sigc::ptr_fun(&AutoRecover::auto_backup),timeout);
+//             auto_backup_connect=App::main.get_context()->signal_timeout().connect(sigc::mem_fun(&AutoRecover::auto_backup),timeout);
+}
+
+sinfg::String
+AutoRecover::get_shadow_file_name(const sinfg::String& filename)
+{
+       unsigned int hash1(0xdeadbeef);
+       unsigned int hash2(0x83502529);
+       char* str_hash1(reinterpret_cast<char*>(&hash1));
+       char* str_hash2(reinterpret_cast<char*>(&hash2));
+       
+       // First we need to hash up the directory
+       {
+               String pool(dirname(filename));
+               
+               while(pool.size()>4)
+               {
+                       str_hash1[0]^=pool[1];str_hash1[1]^=pool[2];str_hash1[2]^=pool[3];str_hash1[3]^=pool[0];
+                       str_hash2[3]+=pool[0];str_hash2[2]+=pool[1];str_hash2[1]+=pool[2];str_hash2[0]+=pool[3];
+                       swap(hash1,hash2);
+                       pool=String(pool,4,pool.size());
+               }
+               while(pool.size())
+               {
+                       str_hash1[0]^=pool[0];
+                       str_hash1[2]^=pool[0];
+                       str_hash2[1]^=pool[0];
+                       str_hash2[3]^=pool[0];
+                       swap(hash1,hash2);
+                       pool=String(pool,1,pool.size());
+               }
+       }
+       hash1^=hash2;
+       
+       return Glib::build_filename(get_shadow_directory(),strprintf("%08X-%s",hash1,basename(filename).c_str()));
+       
+//     return dirname(filename) + ETL_DIRECTORY_SEPERATOR + ".shadow_" + basename(filename);
+}
+
+bool
+AutoRecover::cleanup_pid(int pid)
+{
+#ifdef HAVE_FORK
+       int status=0;
+       if(waitpid(pid,&status,WNOHANG)==-1)
+       {
+               sinfg::info("PID %d isn't a zombie yet",pid);
+               return true;
+       }
+       if(WEXITSTATUS(status)!=0)
+       {
+               sinfg::error("Autobackup seems to have failed! (PID=%d)",pid);
+       }
+       else
+               sinfg::info("PID=%d has been cleaned up",pid);
+#endif
+       return false;
+}
+
+bool
+AutoRecover::auto_backup()
+{
+       int pid(0);
+
+#ifdef HAVE_FORK
+       pid=fork();
+#endif
+       
+       if(pid<=0)
+       {
+#ifdef HAVE_SETPRIORITY
+               // make us low priority so that we don't
+               // cause the machine to slow down too much
+               setpriority(PRIO_PROCESS,0,15);
+#endif
+               
+               try
+               {
+                       std::list<etl::handle<Instance> >::iterator iter;
+       
+                       std::string filename=App::get_config_file("autorecovery");
+                       std::ofstream file(filename.c_str());
+                       
+                       int savecount(0);
+                       
+                       for(iter=App::instance_list.begin();iter!=App::instance_list.end();++iter)
+                       {
+                               // If this file hasn't even been changed
+                               // since it was last saved, then don't bother
+                               // backing it up.
+                               if((*iter)->get_action_count()==0)
+                                       continue;
+                                       
+                               Canvas::Handle canvas((*iter)->get_canvas());
+                               file<<canvas->get_file_name()<<endl;
+                               save_canvas(get_shadow_file_name(canvas->get_file_name()),canvas);
+                               savecount++;
+                       }
+                       
+                       if(savecount)
+                               sinfg::info("AutoRecover::auto_backup(): %d Files backed up.",savecount);
+               }
+               catch(...)
+               {
+                       sinfg::error("AutoRecover::auto_backup(): UNKNOWN EXCEPTION THROWN.");
+                       sinfg::error("AutoRecover::auto_backup(): FILES NOT BACKED UP.");
+               }
+               
+#ifdef HAVE_FORK
+               if(pid==0)
+               {
+                       _exit(0);
+               }
+#endif
+       }
+
+#ifdef HAVE_FORK
+       Glib::signal_timeout().connect(
+               sigc::bind(
+                       sigc::ptr_fun(&AutoRecover::cleanup_pid),
+                       pid
+               ),
+               60*1000
+       );
+#endif 
+       
+       // Also go ahead and save the settings
+       App::save_settings();
+       
+       return true;
+}
+
+bool
+AutoRecover::recovery_needed()const
+{
+       std::string filename=App::get_config_file("autorecovery");
+       std::ifstream file(filename.c_str());
+       if(!file)
+               return false;
+
+       while(file)
+       {
+               std::string filename;
+               getline(file,filename);
+               if(!filename.empty())
+                       return true;
+       }
+       
+       return false;
+}
+
+bool
+AutoRecover::recover()
+{
+       std::string filename=App::get_config_file("autorecovery");
+       std::ifstream file(filename.c_str());
+       if(!file)
+               return false;
+       bool success=true;
+       
+       while(file)
+       {
+               std::string filename;
+               getline(file,filename);
+               if(filename.empty())
+                       continue;
+
+               // Open the file
+               if(App::open_as(get_shadow_file_name(filename),filename))
+               {
+                       // Correct the file name
+                       App::instance_list.back()->set_file_name(filename);
+                       
+                       // This file isn't saved! mark it as such
+                       App::instance_list.back()->inc_action_count();
+               }
+               else
+                       success=false;
+       }
+
+       return success;
+}
+
+void
+AutoRecover::normal_shutdown()
+{
+       // Turn off the timer
+       auto_backup_connect.disconnect();
+
+       std::string filename=App::get_config_file("autorecovery");
+       remove(filename.c_str());
+}
+
+void
+AutoRecover::clear_backup(sinfg::Canvas::Handle canvas)
+{
+       if(canvas)
+               remove(get_shadow_file_name(canvas->get_file_name()).c_str());
+}
diff --git a/synfig-studio/trunk/src/gtkmm/autorecover.h b/synfig-studio/trunk/src/gtkmm/autorecover.h
new file mode 100644 (file)
index 0000000..c6a4ed0
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file autorecover.h
+**     \brief Template Header
+**
+**     $Id: autorecover.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_AUTORECOVER_H
+#define __SINFG_AUTORECOVER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/string.h>
+#include <sinfg/canvas.h>
+#include <sigc++/connection.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class AutoRecover
+{
+       int timeout;
+       SigC::Connection auto_backup_connect;
+public:
+       AutoRecover();
+       ~AutoRecover();
+
+       static int pid();
+       static sinfg::String get_shadow_file_name(const sinfg::String& filename);
+
+       static bool auto_backup();
+
+       static bool cleanup_pid(int pid);
+
+       void set_timeout(int milliseconds);
+       int get_timeout()const { return timeout; }
+       
+       static sinfg::String get_shadow_directory();
+       
+       bool recovery_needed()const;
+       bool recover();
+       
+       void normal_shutdown();
+       
+       void clear_backup(sinfg::Canvas::Handle canvas);
+}; // END of class AutoRecover
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/canvasoptions.cpp b/synfig-studio/trunk/src/gtkmm/canvasoptions.cpp
new file mode 100644 (file)
index 0000000..44d47a7
--- /dev/null
@@ -0,0 +1,182 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasoptions.cpp
+**     \brief Template File
+**
+**     $Id: canvasoptions.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvasoptions.h"
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+#include "canvasview.h"
+#include "workarea.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CanvasOptions::CanvasOptions(loose_handle<studio::CanvasView> canvas_view):
+       Gtk::Dialog(_("Canvas Options"),*canvas_view,false,true),
+       canvas_view_(canvas_view),
+       toggle_grid_snap(_("Grid Snap")),
+       toggle_grid_show(_("Grid Show")),
+       toggle_time_snap(_("Snap-To-Frame"))
+{
+       vector_grid_size.set_canvas(canvas_view->get_canvas());
+       
+       Gtk::Notebook *notebook=manage(new class Gtk::Notebook());
+
+       toggle_grid_snap.signal_toggled().connect(sigc::mem_fun(*this, &studio::CanvasOptions::on_grid_snap_toggle));
+       toggle_grid_show.signal_toggled().connect(sigc::mem_fun(*this, &studio::CanvasOptions::on_grid_show_toggle));
+
+       Gtk::Table *grid_page=manage(new class Gtk::Table(2,2,false));
+       notebook->append_page(*grid_page,_("Grids"));
+       grid_page->attach(vector_grid_size, 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       grid_page->attach(toggle_grid_snap, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       grid_page->attach(toggle_grid_show, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       
+       Gtk::Table *time_page=manage(new class Gtk::Table(2,2,false));
+       notebook->append_page(*time_page,_("Time"));
+       time_page->attach(toggle_time_snap, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       
+       Gtk::Table *unit_page=manage(new class Gtk::Table(2,2,false));
+       notebook->append_page(*unit_page,_("Units"));
+       unit_page->attach(*manage(new Gtk::Label(_("Not yet implemented"))), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);   
+       
+       
+       Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+       ok_button->show();
+       add_action_widget(*ok_button,2);
+       ok_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasOptions::on_ok_pressed));
+
+       Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       apply_button->show();
+       add_action_widget(*apply_button,1);
+       apply_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasOptions::on_apply_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasOptions::on_cancel_pressed));
+
+       //set_default_response(1);
+       
+       
+       get_vbox()->pack_start(*notebook);
+       notebook->show_all();
+       
+       signal_show().connect(sigc::mem_fun(*this, &studio::CanvasOptions::refresh));
+
+       vector_grid_size.set_digits(5);
+       
+       update_title();
+}
+
+CanvasOptions::~CanvasOptions()
+{
+}
+
+void
+CanvasOptions::update_title()
+{
+       set_title(_("Options")+String(" - ")+canvas_view_->get_canvas()->get_name());
+}
+
+void
+CanvasOptions::refresh()
+{
+       if(canvas_view_->work_area->grid_status())
+               toggle_grid_show.set_active(true);
+       else
+               toggle_grid_show.set_active(false);
+               
+       if(canvas_view_->work_area->get_grid_snap())
+               toggle_grid_snap.set_active(true);
+       else
+               toggle_grid_snap.set_active(false);
+       
+       vector_grid_size.set_value(canvas_view_->work_area->get_grid_size());
+       
+       tooltips.set_tip(toggle_time_snap,_("Not yet implemented"));
+       toggle_time_snap.set_sensitive(false);
+
+       update_title();
+}
+
+void
+CanvasOptions::on_grid_snap_toggle()
+{
+}
+
+void
+CanvasOptions::on_grid_show_toggle()
+{
+}
+
+void
+CanvasOptions::on_apply_pressed()
+{
+       if(toggle_grid_snap.get_active())
+               canvas_view_->work_area->enable_grid_snap();
+       else
+               canvas_view_->work_area->disable_grid_snap();
+               
+       if(toggle_grid_show.get_active())
+               canvas_view_->work_area->enable_grid();
+       else
+               canvas_view_->work_area->disable_grid();
+
+       canvas_view_->work_area->set_grid_size(vector_grid_size.get_value());
+}
+
+void
+CanvasOptions::on_ok_pressed()
+{
+       on_apply_pressed();
+       hide();
+}
+
+void
+CanvasOptions::on_cancel_pressed()
+{
+       refresh();
+       hide();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/canvasoptions.h b/synfig-studio/trunk/src/gtkmm/canvasoptions.h
new file mode 100644 (file)
index 0000000..c34847b
--- /dev/null
@@ -0,0 +1,81 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasoptions.h
+**     \brief Template Header
+**
+**     $Id: canvasoptions.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_CANVASOPTIONS_H
+#define __SINFG_GTKMM_CANVASOPTIONS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/tooltips.h>
+#include "widget_value.h"
+#include "widget_vector.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio
+{
+
+class CanvasView;
+       
+class CanvasOptions  :  public Gtk::Dialog
+{
+       Gtk::Tooltips tooltips;
+
+       etl::loose_handle<CanvasView> canvas_view_;
+
+       Gtk::CheckButton toggle_grid_snap;
+       Gtk::CheckButton toggle_grid_show;
+
+       Widget_Vector vector_grid_size;
+
+       Gtk::CheckButton toggle_time_snap;
+       
+public:
+       CanvasOptions(etl::loose_handle<CanvasView> canvas_view);
+       ~CanvasOptions();
+
+       void refresh();
+       void update_title();
+private:
+
+       void on_grid_snap_toggle();
+       void on_grid_show_toggle();
+
+       void on_ok_pressed();
+       void on_apply_pressed();
+       void on_cancel_pressed();
+}; // END of class CanvasOptions
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/canvasproperties.cpp b/synfig-studio/trunk/src/gtkmm/canvasproperties.cpp
new file mode 100644 (file)
index 0000000..46ecc17
--- /dev/null
@@ -0,0 +1,229 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasproperties.cpp
+**     \brief Template File
+**
+**     $Id: canvasproperties.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvasproperties.h"
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+#include <sinfgapp/canvasinterface.h>
+#include "metadatatreestore.h"
+#include <gtkmm/treeview.h>
+#include <gtkmm/scrolledwindow.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CanvasProperties::CanvasProperties(Gtk::Window& parent,handle<sinfgapp::CanvasInterface> canvas_interface):
+       Gtk::Dialog(_("Canvas Properties"),parent,false,true),
+       canvas_interface_(canvas_interface)
+{
+       widget_rend_desc.show();
+
+       widget_rend_desc.signal_changed().connect(sigc::mem_fun(*this,&studio::CanvasProperties::on_rend_desc_changed));
+
+       Gtk::Frame *info_frame=manage(new Gtk::Frame(_("Canvas Info")));
+       
+       Gtk::Table *info_table=manage(new Gtk::Table(2,2,false));
+       info_frame->add(*info_table);
+
+       // The root canvas doesn't have an ID, so don't
+       // display it if this is a root canvas.
+       if(!canvas_interface_->get_canvas()->is_root())
+       {
+               info_table->attach(*manage(new Gtk::Label(_("ID"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+               info_table->attach(entry_id, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       }
+       info_table->attach(*manage(new Gtk::Label(_("Name"))), 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       info_table->attach(*manage(new Gtk::Label(_("Description"))), 0, 1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       info_table->attach(entry_name, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       info_table->attach(entry_description, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+
+       info_frame->show_all();
+       
+       get_vbox()->pack_start(*info_frame);
+       
+       Gtk::Notebook* notebook(manage(new Gtk::Notebook()));
+       notebook->show();
+       notebook->append_page(widget_rend_desc,_("RendDesc"));
+       //notebook->append_page(create_meta_data_view(),_("MetaData"));
+       
+       get_vbox()->pack_start(*notebook);
+
+       canvas_interface_->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&studio::CanvasProperties::refresh));
+
+       Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+       ok_button->show();
+       add_action_widget(*ok_button,2);
+       ok_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasProperties::on_ok_pressed));
+
+       Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       apply_button->show();
+       add_action_widget(*apply_button,1);
+       apply_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasProperties::on_apply_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasProperties::on_cancel_pressed));
+
+       //set_default_response(1);
+       
+       refresh();
+
+       update_title();
+}
+
+Gtk::Widget&
+CanvasProperties::create_meta_data_view()
+{
+       MetaDataTreeStore::Model model;
+       meta_data_tree_view=(manage(new class Gtk::TreeView()));
+               
+       meta_data_tree_view->append_column(_("Key"),model.key);
+       meta_data_tree_view->append_column_editable(_("Data"),model.data);
+       meta_data_tree_view->set_model(MetaDataTreeStore::create(canvas_interface_));
+       meta_data_tree_view->set_rules_hint();
+       meta_data_tree_view->show();
+       
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*meta_data_tree_view);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show();
+
+       
+       
+       Gtk::Table *table=manage(new Gtk::Table());
+       table->attach(*scrolledwindow, 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       Gtk::Button* button_add(manage(new Gtk::Button(Gtk::StockID("gtk-add"))));
+       button_add->show();
+       button_add->signal_clicked().connect(sigc::mem_fun(*this,&CanvasProperties::on_button_meta_data_add));
+       table->attach(*button_add, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+
+       Gtk::Button* button_delete(manage(new Gtk::Button(Gtk::StockID("gtk-delete"))));
+       button_delete->show();
+       button_delete->signal_clicked().connect(sigc::mem_fun(*this,&CanvasProperties::on_button_meta_data_delete));    
+       table->attach(*button_delete, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       
+       table->show();
+       return *table;
+}
+
+void
+CanvasProperties::on_button_meta_data_add()
+{
+       sinfg::String key;
+       if(App::dialog_entry("New MetaData Entry", "Please enter the name of the key",key) && !key.empty())
+       {
+               canvas_interface_->set_meta_data(key," ");
+       }
+
+}
+
+void
+CanvasProperties::on_button_meta_data_delete()
+{
+}
+
+void
+CanvasProperties::update_title()
+{
+       set_title(_("Properties")+String(" - ")+canvas_interface_->get_canvas()->get_name());
+}
+
+void
+CanvasProperties::refresh()
+{
+       widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
+       entry_id.set_text(canvas_interface_->get_canvas()->get_id());
+       entry_name.set_text(canvas_interface_->get_canvas()->get_name());
+       entry_description.set_text(canvas_interface_->get_canvas()->get_description());
+       
+       dirty_rend_desc=false;
+
+       update_title();
+}
+
+CanvasProperties::~CanvasProperties()
+{
+}
+
+void
+CanvasProperties::on_rend_desc_changed()
+{
+       dirty_rend_desc=true;
+}
+
+void
+CanvasProperties::on_apply_pressed()
+{
+       if(dirty_rend_desc)
+               canvas_interface_->set_rend_desc(widget_rend_desc.get_rend_desc());
+       if(entry_id.get_text()!=canvas_interface_->get_canvas()->get_id())
+               canvas_interface_->set_id(entry_id.get_text());
+       if(entry_name.get_text()!=canvas_interface_->get_canvas()->get_name())
+               canvas_interface_->set_name(entry_name.get_text());
+       if(entry_description.get_text()!=canvas_interface_->get_canvas()->get_description())
+               canvas_interface_->set_description(entry_description.get_text());
+       
+       dirty_rend_desc=false;
+}
+
+void
+CanvasProperties::on_ok_pressed()
+{
+       on_apply_pressed();
+       hide();
+}
+
+void
+CanvasProperties::on_cancel_pressed()
+{
+       refresh();
+       hide();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/canvasproperties.h b/synfig-studio/trunk/src/gtkmm/canvasproperties.h
new file mode 100644 (file)
index 0000000..057ddf1
--- /dev/null
@@ -0,0 +1,86 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasproperties.h
+**     \brief Template Header
+**
+**     $Id: canvasproperties.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_CANVASPROPERTIES_H
+#define __SINFG_GTKMM_CANVASPROPERTIES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/tooltips.h>
+
+#include "renddesc.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class TreeView; };
+namespace sinfgapp { class CanvasInterface; };
+
+namespace studio
+{      
+class CanvasProperties  :  public Gtk::Dialog
+{
+       Gtk::Tooltips tooltips;
+
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+       Widget_RendDesc widget_rend_desc;
+       Gtk::Entry entry_id;
+       Gtk::Entry entry_name;
+       Gtk::Entry entry_description;
+
+       bool dirty_rend_desc;
+       
+       Gtk::TreeView* meta_data_tree_view;
+       void on_button_meta_data_add();
+       void on_button_meta_data_delete();
+       
+public:
+       CanvasProperties(Gtk::Window& parent,etl::handle<sinfgapp::CanvasInterface> canvas_interface);
+       ~CanvasProperties();
+
+       void refresh();
+       void update_title();
+private:
+       void on_rend_desc_changed();
+
+       Gtk::Widget& create_meta_data_view();
+
+       void on_ok_pressed();
+       void on_apply_pressed();
+       void on_cancel_pressed();
+}; // END of class CanvasProperties
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/canvastreestore.cpp b/synfig-studio/trunk/src/gtkmm/canvastreestore.cpp
new file mode 100644 (file)
index 0000000..4a4ea6f
--- /dev/null
@@ -0,0 +1,617 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvastreestore.cpp
+**     \brief Template File
+**
+**     $Id: canvastreestore.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvastreestore.h"
+#include <sinfg/valuenode.h>
+#include "iconcontroler.h"
+#include <sinfg/valuenode_timedswap.h>
+#include <sinfg/valuenode_animated.h>
+#include <gtkmm/button.h>
+#include <sinfgapp/instance.h>
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static CanvasTreeStore::Model& ModelHack()
+{
+       static CanvasTreeStore::Model* model(0);
+       if(!model)model=new CanvasTreeStore::Model;
+       return *model;
+}
+
+CanvasTreeStore::CanvasTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore(ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+}
+
+CanvasTreeStore::~CanvasTreeStore()
+{
+}
+
+void
+CanvasTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.value.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<sinfg::ValueBase> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if(!value_desc)
+               {
+                       x.set(ValueBase());
+               }
+               else
+               if(value_desc.is_const())
+                       x.set(value_desc.get_value());
+               else
+               if(value_desc.is_value_node())
+                       x.set((*value_desc.get_value_node())(canvas_interface()->get_time()));
+               else
+               {
+                       sinfg::error(__FILE__":%d: Unable to figure out value",__LINE__);
+                       return;
+               }
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_value_node.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc && value_desc.is_value_node());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_shared.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_exported.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(value_desc.is_value_node() && value_desc.get_value_node()->is_exported());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_canvas.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(!value_desc && (Canvas::Handle)(*iter)[model.canvas]);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.id.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if(value_desc && value_desc.is_value_node())
+                       x.set(value_desc.get_value_node()->get_id());
+               else if(!value_desc && Canvas::Handle((*iter)[model.canvas]))
+                       x.set(Canvas::Handle((*iter)[model.canvas])->get_id());
+               else
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);      
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_editable.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(!value_desc.is_value_node() || sinfgapp::is_editable(value_desc.get_value_node()));
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.type.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               // Set the type
+               if(!value_desc)
+               {
+                       if((*iter)[model.is_canvas])
+                               x.set(_("Canvas"));
+               }
+               else
+               {
+                       if(!value_desc.is_value_node() || value_desc.get_value_node()->get_name()=="constant")
+                       {
+                               x.set(ValueBase::type_name(value_desc.get_value_type()));
+                       }
+                       else
+                       {
+                               x.set(value_desc.get_value_node()->get_local_name());
+                       }
+               }
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.label.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               // Set the type
+               if(!value_desc)
+               {
+                       Canvas::Handle canvas((*iter)[model.canvas]);
+                       if(canvas)
+                       {
+                               if(!canvas->get_id().empty())
+                                       x.set(canvas->get_id());
+                               else
+                               if(!canvas->get_name().empty())
+                                       x.set(canvas->get_name());      
+                               else
+                                       x.set(_("[Unnamed]"));          
+                               x.set(_("Canvas"));
+                       }
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+               }
+               else
+               {
+                       ValueNode::Handle value_node=value_desc.get_value_node();
+                       
+                       // Setup the row's label
+                       if(value_node->get_id().empty())
+                               x.set(Glib::ustring((*iter)[model.name]));      
+                       else if(Glib::ustring((*iter)[model.name]).empty())
+                               x.set(value_node->get_id());
+                       else
+                               x.set(Glib::ustring((*iter)[model.name])+" ("+value_node->get_id()+')');                        
+               }
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.icon.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+               if(!value_desc)
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               x.set(get_tree_pixbuf(value_desc.get_value_type()));
+
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+bool
+CanvasTreeStore::find_first_value_desc(const sinfgapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+       iter=children().begin();
+       while(iter && value_desc!=(*iter)[model.value_desc])
+       {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+                       iter==iter->parent();
+               else
+                       iter=iter2;
+       }
+       return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+bool
+CanvasTreeStore::find_next_value_desc(const sinfgapp::ValueDesc& value_desc, Gtk::TreeIter& iter)
+{
+       if(!iter) return find_first_value_desc(value_desc,iter);
+               
+       if(iter) do {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       if(iter2 && value_desc==(*iter2)[model.value_desc] || find_next_value_desc(value_desc, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+               {
+                       iter==iter->parent();
+                       if(iter)++iter;
+               }
+               else
+                       iter=iter2;
+       } while(iter && value_desc!=(*iter)[model.value_desc]);
+       return (bool)iter && value_desc==(*iter)[model.value_desc];
+}
+
+
+
+
+
+
+bool
+CanvasTreeStore::find_first_value_node(const ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+       iter=children().begin();
+       while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node])
+       {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       if(iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node] || find_next_value_node(value_node, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+                       iter==iter->parent();
+               else
+                       iter=iter2;
+       }
+       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+bool
+CanvasTreeStore::find_next_value_node(const ValueNode::Handle& value_node, Gtk::TreeIter& iter)
+{
+       if(!iter) return find_first_value_node(value_node,iter);
+               
+       if(iter) do {
+               if(!iter->children().empty())
+               {
+                       Gtk::TreeIter iter2(iter->children().begin());
+                       if(iter2 && value_node==(ValueNode::Handle)(*iter2)[model.value_node] || find_next_value_node(value_node, iter2))
+                       {
+                               iter=iter2;
+                               return true;
+                       }
+               }
+               Gtk::TreeIter iter2(++iter);
+               if(!iter2)
+               {
+                       iter==iter->parent();
+                       if(iter)++iter;
+               }
+               else
+                       iter=iter2;
+       } while(iter && value_node!=(ValueNode::Handle)(*iter)[model.value_node]);
+       return (bool)iter && value_node==(ValueNode::Handle)(*iter)[model.value_node];
+}
+
+void
+CanvasTreeStore::set_row(Gtk::TreeRow row,sinfgapp::ValueDesc value_desc, bool do_children)
+{
+       Gtk::TreeModel::Children children = row.children();
+       while(!children.empty() && erase(children.begin()));
+
+       row[model.value_desc]=value_desc;
+       try
+       {
+               //row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());
+               
+               if(value_desc.is_value_node())
+               {
+                       ValueNode::Handle value_node=value_desc.get_value_node();
+
+                       assert(value_node);
+
+                       row[model.value_node] = value_node;
+                       //row[model.is_canvas] = false;
+                       //row[model.is_value_node] = true;
+                       //row[model.is_editable] = sinfgapp::is_editable(value_node);
+                       //row[model.id]=value_node->get_id();
+                       
+                       // Set the canvas
+                       if(value_desc.parent_is_canvas())
+                               row[model.canvas]=value_desc.get_canvas();
+                       else
+                               row[model.canvas]=canvas_interface()->get_canvas();
+                               
+                       LinkableValueNode::Handle linkable;
+                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+       
+                       if(linkable && do_children)
+                       {
+                               row[model.link_count] = linkable->link_count();
+                               for(int i=0;i<linkable->link_count();i++)
+                               {
+                                       Gtk::TreeRow child_row=*(append(row.children()));
+                                       child_row[model.link_id] = i;
+                                       child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
+                                       child_row[model.name] = linkable->link_local_name(i);
+                                       set_row(child_row,sinfgapp::ValueDesc(linkable,i));
+                               }
+                       }
+                       return;
+               }
+               else
+               {
+                       //row[model.is_value_node] = false;
+                       //row[model.is_editable] = true;
+                       //row[model.label] = Glib::ustring(row[model.name]);
+                       return;
+               }
+       }
+       catch(sinfg::Exception::IDNotFound x)
+       {
+               sinfg::error(__FILE__":%d: IDNotFound thrown",__LINE__);
+               erase(row);
+               return;
+       }
+       
+       // We should never get to this point
+       assert(0);
+}
+
+void
+CanvasTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+       sinfgapp::ValueDesc value_desc=row[model.value_desc];
+
+       if(value_desc)
+       {
+               if((bool)row[model.is_value_node] != value_desc.is_value_node() ||
+                       (!bool(row[model.is_value_node]) && row[model.link_count]!=0))
+               {
+                       set_row(row,value_desc,do_children);
+                       return;                         
+               }
+               
+               if(row[model.is_value_node])
+               {
+                       ValueNode::Handle value_node(value_desc.get_value_node());
+       
+                       if(ValueNode::Handle(row[model.value_node])!=value_node)
+                       {
+                               rebuild_row(row,do_children);
+                               return;
+                       }
+       
+                       //row[model.id]=value_node->get_id();
+       
+                       // Setup the row's label
+                       /*
+                       if(value_node->get_id().empty())
+                               row[model.label] = Glib::ustring(row[model.name]);                                      
+                       else if(Glib::ustring(row[model.name]).empty())
+                               row[model.label] = value_node->get_id();
+                       else
+                               row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';                        
+                       */
+                       
+                       LinkableValueNode::Handle linkable;
+                       linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+                       if(do_children && linkable && ((int)row[model.link_count] != linkable->link_count()))
+                       {
+       //                      Gtk::TreeModel::Children children = row.children();
+       //                      while(!children.empty() && erase(children.begin()));
+                               
+                               set_row(row,value_desc);
+                               return;                         
+                       }
+               }
+               else
+               {
+                       //row[model.label] = Glib::ustring(row[model.name]);                                    
+                       //row[model.is_value_node] = false;
+                       //row[model.is_editable] = true;
+               }
+       }
+       if(!do_children)
+               return; 
+       
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeRow row=*iter;
+               refresh_row(row);
+       }
+}
+
+void
+CanvasTreeStore::rebuild_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+       sinfgapp::ValueDesc value_desc=(sinfgapp::ValueDesc)row[model.value_desc];
+
+       if(value_desc && value_desc.get_value_node())
+       {
+               ValueNode::Handle value_node;
+               value_node=value_desc.get_value_node();
+
+               assert(value_node);if(!value_node)return;
+               
+               if(value_node && value_node!=(ValueNode::Handle)row[model.value_node])
+               {
+//                     Gtk::TreeModel::Children children = row.children();
+//                     while(!children.empty() && erase(children.begin()));
+                               
+                       set_row(row,value_desc,do_children);
+                       return;                         
+               }
+
+               LinkableValueNode::Handle linkable;
+               linkable=LinkableValueNode::Handle::cast_dynamic(value_node);
+
+               if( do_children && linkable && (int)row[model.link_count] != linkable->link_count())
+               {
+//                     Gtk::TreeModel::Children children = row.children();
+//                     while(!children.empty() && erase(children.begin()));
+                       
+                       set_row(row,value_desc);
+                       return;                         
+               }
+                       
+               //if(!value_node)
+               //      value_node=row[model.value_node];
+               
+               row[model.id]=value_node->get_id();
+
+               // Setup the row's label
+               if(value_node->get_id().empty())
+                       row[model.label] = Glib::ustring(row[model.name]);                                      
+               else if(Glib::ustring(row[model.name]).empty())
+                       row[model.label] = value_node->get_id();
+               else
+                       row[model.label] = Glib::ustring(row[model.name])+" ("+value_node->get_id()+')';                        
+       }
+       else
+       {
+               row[model.label] = Glib::ustring(row[model.name]);                                      
+               row[model.is_value_node] = false;
+               row[model.is_editable] = true;
+               Gtk::TreeModel::Children children = row.children();
+               while(!children.empty() && erase(children.begin()));
+       }
+       if(!do_children)
+               return; 
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+       if(!children.empty())
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeRow row=*iter;
+               rebuild_row(row);
+       }
+}
+
+CellRenderer_ValueBase*
+CanvasTreeStore::add_cell_renderer_value(Gtk::TreeView::Column* column)
+{
+       const CanvasTreeStore::Model model;
+       
+       CellRenderer_ValueBase* ret;
+       
+       ret=Gtk::manage( new CellRenderer_ValueBase() );
+
+       column->pack_start(*ret,true);
+       column->add_attribute(ret->property_value(), model.value);
+       column->add_attribute(ret->property_editable(), model.is_editable);
+       column->add_attribute(ret->property_canvas(), model.canvas);
+
+       return ret;
+}
+
+CellRenderer_TimeTrack*
+CanvasTreeStore::add_cell_renderer_value_node(Gtk::TreeView::Column* column)
+{
+       const CanvasTreeStore::Model model;
+       
+       CellRenderer_TimeTrack* ret;
+       
+       ret = Gtk::manage( new CellRenderer_TimeTrack() );
+       
+       column->pack_start(*ret,true);
+       //column->add_attribute(ret->property_visible(), model.is_value_node);
+       column->add_attribute(ret->property_value_desc(), model.value_desc);
+       column->add_attribute(ret->property_canvas(), model.canvas);
+       
+       
+       return ret;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/canvastreestore.h b/synfig-studio/trunk/src/gtkmm/canvastreestore.h
new file mode 100644 (file)
index 0000000..b011fbb
--- /dev/null
@@ -0,0 +1,194 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvastreestore.h
+**     \brief Template Header
+**
+**     $Id: canvastreestore.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_CANVASTREESTORE_H
+#define __SINFG_STUDIO_CANVASTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <sinfgapp/value_desc.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+       enum ColumnID
+       {
+               COLUMNID_ID,
+               COLUMNID_VALUE,
+               COLUMNID_TIME_TRACK,
+               COLUMNID_TYPE,
+               
+               COLUMNID_END                    //!< \internal
+       };
+#define        COLUMNID_NAME COLUMNID_ID
+
+class CanvasTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::ustring> id;
+
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle> canvas;
+               Gtk::TreeModelColumn<bool> is_canvas;
+
+               Gtk::TreeModelColumn<sinfg::ValueNode::Handle> value_node;
+               Gtk::TreeModelColumn<bool> is_value_node;
+               Gtk::TreeModelColumn<sinfg::ValueBase> value;
+               Gtk::TreeModelColumn<Glib::ustring> type;
+               Gtk::TreeModelColumn<int> link_id;
+               Gtk::TreeModelColumn<int> link_count;
+
+               Gtk::TreeModelColumn<bool> is_editable;
+
+               Gtk::TreeModelColumn<bool> is_shared;
+               Gtk::TreeModelColumn<bool> is_exported;
+       
+               Gtk::TreeModelColumn<sinfgapp::ValueDesc> value_desc;
+       
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+               Model()
+               {
+                       add(value);
+                       add(name);
+                       add(label);
+                       add(icon);
+                       add(type);
+                       add(id);
+                       add(canvas);
+                       add(value_node);
+                       add(is_canvas);
+                       add(is_value_node);
+
+                       add(is_shared);
+                       add(is_exported);
+                       add(is_editable);
+                       add(value_desc);
+                       add(link_count);
+                       add(link_id);
+                       
+                       add(tooltip);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       const Model model;
+
+       //std::multimap<etl::handle<ValueNode>, sigc::connection> connection_map;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+protected:
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       CanvasTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+       ~CanvasTreeStore();
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const sinfgapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+       virtual void rebuild_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+       virtual void refresh_row(Gtk::TreeModel::Row &row, bool do_children=true);
+
+       virtual void set_row(Gtk::TreeRow row,sinfgapp::ValueDesc value_desc, bool do_children=true);
+
+       bool find_first_value_desc(const sinfgapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+       bool find_next_value_desc(const sinfgapp::ValueDesc& value_desc, Gtk::TreeIter& iter);
+
+       bool find_first_value_node(const sinfg::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+       bool find_next_value_node(const sinfg::ValueNode::Handle& value_node, Gtk::TreeIter& iter);
+       
+       
+       static CellRenderer_ValueBase* add_cell_renderer_value(Gtk::TreeView::Column* column);
+
+       static CellRenderer_TimeTrack* add_cell_renderer_value_node(Gtk::TreeView::Column* column);
+
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       virtual void on_value_node_changed(sinfg::ValueNode::Handle value_node)=0;
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+public:
+       
+}; // END of class CanvasTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.cpp b/synfig-studio/trunk/src/gtkmm/canvasview.cpp
new file mode 100644 (file)
index 0000000..5d4c96b
--- /dev/null
@@ -0,0 +1,3552 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasview.cpp
+**     \brief Template File
+**
+**     $Id: canvasview.cpp,v 1.7 2005/01/16 19:55:57 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <sigc++/adaptors/hide.h>
+
+#include <ETL/clock>
+#include <sstream>
+
+#include <gtkmm/paned.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/treemodelsort.h>
+#include <gtkmm/buttonbox.h>
+
+#include <gtk/gtktreestore.h>
+#include <gtk/gtkversion.h>
+
+#include <sinfg/valuenode_reference.h>
+#include <sinfg/valuenode_subtract.h>          
+#include <sinfg/valuenode_linear.h>            
+#include <sinfg/valuenode_timedswap.h>         
+#include <sinfg/valuenode_scale.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_twotone.h>
+#include <sinfg/valuenode_stripes.h>
+#include <sinfg/layer.h>
+
+#include <sinfgapp/uimanager.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/selectionmanager.h>
+//#include <sinfgapp/action_setwaypoint.h>
+//#include <sinfgapp/action_deletewaypoint.h>
+
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+//#include <sigc++/hide.h>
+
+#include "canvasview.h"
+#include "instance.h"
+#include "app.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include "workarea.h"
+#include "dialog_color.h"
+#include "eventkey.h"
+
+#include "state_polygon.h"
+#include "state_bline.h"
+#include "state_normal.h"
+#include "state_eyedrop.h"
+#include "state_draw.h"
+
+#include "ducktransform_scale.h"
+#include "ducktransform_translate.h"
+#include "ducktransform_rotate.h"
+
+#include "event_mouse.h"
+#include "event_layerclick.h"
+
+#include "toolbox.h"
+
+#include "dialog_preview.h"
+#include "dialog_soundselect.h"
+
+#include "preview.h"
+#include "audiocontainer.h"
+#include "widget_timeslider.h"
+
+#include <sinfgapp/main.h>
+#include <sinfgapp/inputdevice.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+using namespace SigC;
+
+/* === M A C R O S ========================================================= */
+
+#define GRAB_HINT_DATA(y)      { \
+               String x; \
+               if(sinfgapp::Main::settings().get_value(String("pref.")+y+"_hints",x)) \
+               { \
+                       set_type_hint((Gdk::WindowTypeHint)atoi(x.c_str()));    \
+               } \
+       }
+
+#define DEFAULT_TIME_WINDOW_SIZE               (10.0)
+
+/*
+#ifdef DEBUGPOINT
+#undef DEBUGPOINT
+#endif
+#define DEBUGPOINT()
+*/
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips.set_tip(*button,tooltip);      \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       tooltips.set_tip(*button,tooltip);      \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+       button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+#define SLOT_EVENT(x)  sigc::hide_return(sigc::bind(sigc::mem_fun(*this,&studio::CanvasView::process_event_key),x))
+       
+/* === C L A S S E S ======================================================= */
+
+       
+class studio::UniversalScrubber
+{
+       CanvasView *canvas_view;
+
+       bool            scrubbing;
+       etl::clock      scrub_timer;
+       
+       sigc::connection end_scrub_connection;
+public:
+       UniversalScrubber(CanvasView *canvas_view):
+               canvas_view(canvas_view),
+               scrubbing(false)
+       {
+               canvas_view->canvas_interface()->signal_time_changed().connect(
+                       sigc::mem_fun(*this,&studio::UniversalScrubber::on_time_changed)
+               );
+       }
+       
+       ~UniversalScrubber()
+       {
+               end_scrub_connection.disconnect();
+       }
+       
+       void on_time_changed()
+       {
+               // Make sure we are changing the time quickly
+               // before we enable scrubbing
+               if(!scrubbing && scrub_timer()>1)
+               {
+                       scrub_timer.reset();
+                       return;
+               }
+               
+               // If we aren't scrubbing already, enable it
+               if(!scrubbing)
+               {
+                       scrubbing=true;                 
+                       audio_container()->start_scrubbing(canvas_view->get_time());
+               }
+               
+               // Reset the scrubber ender
+               end_scrub_connection.disconnect();
+               end_scrub_connection=Glib::signal_timeout().connect(
+                       sigc::bind_return(
+                               sigc::mem_fun(*this,&UniversalScrubber::end_of_scrubbing),
+                               false
+                       ),
+                       1000
+               );
+
+               // Scrub!
+               audio_container()->scrub(canvas_view->get_time());
+
+               scrub_timer.reset();
+       }
+       
+       void end_of_scrubbing()
+       {               
+               scrubbing=false;
+               audio_container()->stop_scrubbing();
+               scrub_timer.reset();
+       }
+       
+       handle<AudioContainer> audio_container()
+       {
+               assert(canvas_view->audio);
+               return canvas_view->audio;
+       }
+};
+
+       
+class studio::CanvasViewUIInterface : public sinfgapp::UIInterface
+{
+       CanvasView *view;
+
+public:
+
+       CanvasViewUIInterface(CanvasView *view):
+               view(view)
+       {
+       
+               view->statusbar->push("Idle");
+       }
+
+       ~CanvasViewUIInterface()
+       {
+               //view->statusbar->pop();
+               //view->progressbar->set_fraction(0);
+       }
+
+       virtual Response yes_no(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
+       {
+               view->present();
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       *view,          // Parent
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
+               dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+       virtual Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
+       {
+               view->present();
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       *view,          // Parent
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
+               dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
+               dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+       virtual Response ok_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_OK)
+       {
+               view->present();
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               Gtk::Dialog dialog(
+                       title,          // Title
+                       *view,          // Parent
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(message);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
+               dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
+               
+               dialog.set_default_response(dflt);
+               dialog.show();
+               return (Response)dialog.run();
+       }
+
+       virtual bool
+       task(const std::string &task)
+       {
+               if(!view->is_playing_)
+               {       
+                       view->statusbar->pop();
+                       view->statusbar->push(task);
+               }
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               if(view->cancel){return false;}
+               return true;
+       }
+
+       virtual bool
+       error(const std::string &err)
+       {
+               view->statusbar->push("ERROR");
+               
+               // If we are in the process of canceling,
+               // then just go ahead and return false --
+               // don't bother displaying a dialog
+               if(view->cancel)return false;
+               
+               Gtk::Dialog dialog(
+                       "Error",                // Title
+                       *view,          // Parent
+                       true,           // Modal
+                       true            // use_separator
+               );
+               Gtk::Label label(err);
+               label.show();
+               
+               dialog.get_vbox()->pack_start(label);
+               dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
+               dialog.show();
+               dialog.run();
+               view->statusbar->pop();
+               return true;
+       }
+
+       virtual bool
+       warning(const std::string &err)
+       {
+               view->statusbar->pop();
+               view->statusbar->push(err);
+               
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               if(view->cancel)return false;
+               return true;
+       }
+
+       virtual bool
+       amount_complete(int current, int total)
+       {
+               if(!view->is_playing_)
+               {       
+                       if(!view->working_depth)
+                       {
+                               if(current)
+                                       view->stopbutton->set_sensitive(true);
+                               else
+                                       view->stopbutton->set_sensitive(false);
+                       }
+                       float x((float)current/(float)total);
+                       if(x<0)x=0;
+                       else if(x>1)x=1;
+                       view->progressbar->set_fraction(x);
+               }
+               //while(studio::App::events_pending())studio::App::iteration(false);
+               if(view->cancel){/*view->cancel=false;*/return false;}
+               return true;
+       }
+       
+       void
+       not_implemented()
+       {
+               error("Feature not yet implemented");
+       }
+};
+
+class studio::CanvasViewSelectionManager : public sinfgapp::SelectionManager
+{
+       CanvasView *view;
+       CanvasView::LayerTreeModel layer_tree_model;
+       CanvasView::ChildrenTreeModel children_tree_model;
+public:
+
+       CanvasViewSelectionManager(CanvasView *view): view(view)
+{      
+       
+ }
+               
+
+private:
+       void _set_selected_layer(const sinfg::Layer::Handle &layer)
+       {
+               view->layer_tree->select_layer(layer);
+/*
+               // Don't change the selection while we are busy
+               // I cannot remember exactly why I put this here...
+               // It musta been for some reason, but I cannot recall.
+               //if(App::Busy::count)
+               //      return;
+               
+               if(view->layer_tree->get_selection()->get_selected())
+               {
+                       const Gtk::TreeRow row = *(view->layer_tree->get_selection()->get_selected());
+
+                       // Don't do anything if that layer is already selected
+                       if(layer == static_cast<sinfg::Layer::Handle>(row[layer_tree_model.layer]))
+                               return;
+               }
+               Gtk::TreeModel::Children::iterator iter;
+               if(view->layer_tree_store()->find_layer_row(layer,iter))
+               {
+                       Gtk::TreePath path(iter);
+                       for(int i=path.get_depth();i;i--)
+                       {
+                               int j;
+                               path=Gtk::TreePath(iter);
+                               for(j=i;j;j--)
+                                       path.up();
+                               view->layer_tree->get_tree_view().expand_row(path,false);
+                       }
+                       view->layer_tree->get_tree_view().scroll_to_row(Gtk::TreePath(iter));
+                       view->layer_tree->get_selection()->select(iter);
+               }
+*/
+       }
+public:
+       
+       //! Returns the number of layers selected.
+       virtual int get_selected_layer_count()const
+       {
+               return get_selected_layers().size();
+       }
+
+       //! Returns a list of the currently selected layers.
+       virtual LayerList get_selected_layers()const
+       {
+//             assert(view->layer_tree);
+               
+               if(!view->layer_tree) { DEBUGPOINT(); sinfg::error("canvas_view.layer_tree not defined!?"); return LayerList(); }
+               return view->layer_tree->get_selected_layers();
+       }
+       
+       //! Returns the first layer selected or an empty handle if none are selected.
+       virtual sinfg::Layer::Handle get_selected_layer()const
+       {
+//             assert(view->layer_tree);
+               
+               if(!view->layer_tree) { DEBUGPOINT(); sinfg::error("canvas_view.layer_tree not defined!?"); return 0; }
+               return view->layer_tree->get_selected_layer();
+       }
+       
+       //! Sets which layers should be selected
+       virtual void set_selected_layers(const LayerList &layer_list)
+       {
+//             assert(view->layer_tree);
+               
+               if(!view->layer_tree) { DEBUGPOINT(); sinfg::error("canvas_view.layer_tree not defined!?"); return; }
+               view->layer_tree->select_layers(layer_list);
+               //view->get_smach().process_event(EVENT_REFRESH_DUCKS);
+
+               //view->queue_rebuild_ducks();
+       }
+
+       //! Sets which layer should be selected.
+       virtual void set_selected_layer(const sinfg::Layer::Handle &layer)
+       {
+//             assert(view->layer_tree);
+               
+               if(!view->layer_tree) { DEBUGPOINT(); sinfg::error("canvas_view.layer_tree not defined!?"); return; }
+               view->layer_tree->select_layer(layer);
+               //view->queue_rebuild_ducks();
+       }
+
+       //! Clears the layer selection list
+       virtual void clear_selected_layers()
+       {
+               if(!view->layer_tree) return;
+               view->layer_tree->clear_selected_layers();
+       }
+
+
+
+       //! Returns the number of value_nodes selected.
+       virtual int get_selected_children_count()const
+       {
+               return get_selected_children().size();
+       }
+       
+       static inline void __child_grabber(const Gtk::TreeModel::iterator& iter, ChildrenList* ret)
+       {
+               const CanvasView::ChildrenTreeModel children_tree_model;
+               sinfgapp::ValueDesc value_desc((*iter)[children_tree_model.value_desc]);
+               if(value_desc)
+                       ret->push_back(value_desc);
+       }
+       
+       //! Returns a list of the currently selected value_nodes.
+       virtual ChildrenList get_selected_children()const
+       {
+               if(!view->children_tree) return ChildrenList();
+                       
+               Glib::RefPtr<Gtk::TreeSelection> selection=view->children_tree->get_selection();
+
+               if(!selection)
+                       return ChildrenList();
+       
+               ChildrenList ret;
+               
+               selection->selected_foreach_iter(
+                       sigc::bind(
+                               sigc::ptr_fun(
+                                       &studio::CanvasViewSelectionManager::__child_grabber
+                               ),
+                               &ret
+                       )
+               );
+               
+               /*
+               Gtk::TreeModel::Children::iterator iter(view->children_tree_store()->children().begin());
+               iter++;
+               Gtk::TreeModel::Children children = iter->children();
+               for(iter = children.begin(); iter != children.end(); ++iter)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if(selection->is_selected(row))
+                               ret.push_back((sinfgapp::ValueDesc)row[children_tree_model.value_desc]);
+               }
+               */
+               return ret;
+       }
+       
+       //! Returns the first value_node selected or an empty handle if none are selected.
+       virtual ChildrenList::value_type get_selected_child()const
+       {
+               if(!view->children_tree) return ChildrenList::value_type();
+
+               ChildrenList children(get_selected_children());
+
+               if(children.empty())
+                       return ChildrenList::value_type();
+
+               return children.front();
+       }
+       
+       //! Sets which value_nodes should be selected
+       virtual void set_selected_children(const ChildrenList &children_list)
+       {
+               return;
+       }
+
+       //! Sets which value_node should be selected. Empty handle if none.
+       virtual void set_selected_child(const ChildrenList::value_type &child)
+       {
+               return;
+       }
+
+       //! Clears the value_node selection list
+       virtual void clear_selected_children()
+       {
+               return;
+       }
+       
+       
+       
+       int get_selected_layer_parameter_count()const
+       {
+               return get_selected_layer_parameters().size();
+       }
+       
+       LayerParamList get_selected_layer_parameters()const
+       {
+               if(!view->layer_tree) return LayerParamList();
+
+               Glib::RefPtr<Gtk::TreeSelection> selection=view->layer_tree->get_selection();
+
+               if(!selection)
+                       return LayerParamList();
+       
+               LayerParamList ret;
+       
+               Gtk::TreeModel::Children children = const_cast<CanvasView*>(view)->layer_tree_store()->children();
+               Gtk::TreeModel::Children::iterator iter;
+               for(iter = children.begin(); iter != children.end(); ++iter)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       Gtk::TreeModel::Children::iterator iter;
+                       for(iter=row.children().begin();iter!=row.children().end();iter++)
+                       {
+                               Gtk::TreeModel::Row row = *iter;
+                               if(selection->is_selected(row))
+                                       ret.push_back(LayerParam(row[layer_tree_model.layer],(Glib::ustring)row[layer_tree_model.id]));
+                       }
+               }
+               return ret;
+       }
+       
+       LayerParam get_selected_layer_parameter() const
+       {
+               if(!view->layer_tree) return LayerParam();
+               return get_selected_layer_parameters().front();
+       }
+       
+       void set_selected_layer_parameters(const LayerParamList &layer_param_list)
+       {
+               return;
+       }
+       
+       void set_selected_layer_param(const LayerParam &layer_param)
+       {
+               return;
+       }
+       
+       void clear_selected_layer_parameters()
+       {
+               return;
+       }
+
+}; // END of class SelectionManager
+
+
+CanvasView::IsWorking::IsWorking(CanvasView &canvas_view_):
+       canvas_view_(canvas_view_)
+{
+       if(!canvas_view_.working_depth)
+               canvas_view_.stopbutton->set_sensitive(true);
+       canvas_view_.working_depth++;
+       canvas_view_.cancel=false;
+}
+
+CanvasView::IsWorking::~IsWorking()
+{
+       canvas_view_.working_depth--;
+       if(!canvas_view_.working_depth)
+               canvas_view_.stopbutton->set_sensitive(false);
+}
+
+CanvasView::IsWorking::operator bool()const
+{
+       if(canvas_view_.cancel)
+               return false;
+       return true;
+}
+
+/* === M E T H O D S ======================================================= */
+
+CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<sinfgapp::CanvasInterface> canvas_interface_):
+       smach_                                  (this),
+       instance_                               (instance),
+       canvas_interface_               (canvas_interface_),
+       //layer_tree_store_             (LayerTreeStore::create(canvas_interface_)),
+       //children_tree_store_  (ChildrenTreeStore::create(canvas_interface_)),
+       //keyframe_tree_store_  (KeyframeTreeStore::create(canvas_interface_)),
+       time_adjustment_                (0,0,25,0,0,0),
+       time_window_adjustment_ (0,0,25,0,0,0),
+       statusbar                               (manage(new class Gtk::Statusbar())),
+       
+       timeslider                              (new Widget_Timeslider),
+       
+       ui_interface_                   (new CanvasViewUIInterface(this)),
+       selection_manager_              (new CanvasViewSelectionManager(this)),
+       is_playing_                             (false),
+       
+       working_depth                   (0),
+       cancel                                  (false),
+       
+       canvas_properties               (*this,canvas_interface_),
+       canvas_options                  (this),
+       render_settings                 (*this,canvas_interface_),
+       waypoint_dialog                 (*this,canvas_interface_->get_canvas()),
+       keyframe_dialog                 (*this,canvas_interface_),
+       preview_dialog                  (new Dialog_Preview),
+       sound_dialog                    (new Dialog_SoundSelect(*this,canvas_interface_))
+{
+       layer_tree=0;
+       children_tree=0;
+       duck_refresh_flag=true;
+       
+       smach_.set_default_state(&state_normal);
+       
+       disp_audio = new Widget_Sound();
+       
+       //sinfg::info("Canvasview: Entered constructor");
+       // Minor hack
+       get_canvas()->set_time(0);
+       //layer_tree_store_->rebuild();
+               
+       // Set up the UI and Selection managers
+       canvas_interface()->set_ui_interface(get_ui_interface());
+       canvas_interface()->set_selection_manager(get_selection_manager());
+       rebuild_ducks_queued=false;
+       
+       //notebook=manage(new class Gtk::Notebook());
+       //Gtk::VPaned *vpaned = manage(new class Gtk::VPaned());
+       //vpaned->pack1(*create_work_area(), Gtk::EXPAND|Gtk::SHRINK);
+       //vpaned->pack2(*notebook, Gtk::SHRINK);
+       //vpaned->show_all();
+
+
+       //notebook->show();
+       
+       //notebook->append_page(*create_layer_tree(),"Layers");
+       //notebook->append_page(*create_children_tree(),"Children");
+       //notebook->append_page(*create_keyframe_tree(),"Keyframes");
+       
+       //sinfg::info("Canvasview: Before big chunk of allocation and tabling stuff");
+       //create all allocated stuff for this canvas
+       audio = new AudioContainer();
+       
+       Gtk::Table *layout_table= manage(new class Gtk::Table(1, 3, false));    
+       //layout_table->attach(*vpaned, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       layout_table->attach(*create_work_area(), 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       init_menus();   
+       //layout_table->attach(*App::ui_manager()->get_widget("/menu-main"), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       
+       
+       layout_table->attach(*create_time_bar(), 0, 1, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       layout_table->attach(*create_status_bar(), 0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       
+       update_title();
+
+       layout_table->show();
+       add(*layout_table);
+
+       //set_transient_for(*App::toolbox);
+
+       //sinfg::info("Canvasview: Before Signals");
+       /*
+ --    ** -- Signals -------------------------------------------------------------
+       */
+
+       canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::CanvasView::on_dirty_preview));
+       canvas_interface()->signal_mode_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_mode_changed));
+
+       canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_time_changed));
+
+       //canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::refresh_tables));
+       canvas_interface()->signal_id_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_id_changed));
+       canvas_interface()->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::refresh_rend_desc));
+       waypoint_dialog.signal_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_waypoint_changed));
+       waypoint_dialog.signal_delete().connect(sigc::mem_fun(*this,&studio::CanvasView::on_waypoint_delete));
+       
+       //MODIFIED TIME ADJUSTMENT STUFF....
+       time_window_adjustment().set_child_adjustment(&time_adjustment());
+       time_window_adjustment().signal_value_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::refresh_time_window)); 
+       time_adjustment().signal_value_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::time_was_changed));
+
+
+       work_area->signal_layer_selected().connect(sigc::mem_fun(*this,&studio::CanvasView::workarea_layer_selected));
+       work_area->signal_input_device_changed().connect(sigc::mem_fun(*this,&studio::CanvasView::on_input_device_changed));
+
+       canvas_interface()->signal_canvas_added().connect(
+               sigc::hide(
+                       sigc::mem_fun(*instance,&studio::Instance::refresh_canvas_tree)
+               )
+       );
+       canvas_interface()->signal_canvas_removed().connect(
+               sigc::hide(
+                       sigc::mem_fun(*instance,&studio::Instance::refresh_canvas_tree)
+               )
+       );
+
+       canvas_interface()->signal_layer_param_changed().connect(
+               sigc::hide(
+                       sigc::hide(
+                               SLOT_EVENT(EVENT_REFRESH_DUCKS)
+                       )
+               )
+       );
+       
+
+       //MUCH TIME STUFF TAKES PLACE IN HERE
+       refresh_rend_desc();
+       refresh_time_window();
+
+       /*! \todo We shouldn't need to do this at construction -- 
+       **      This should be preformed at the first time the window
+       **      becomes visible.
+       */
+       work_area->queue_render_preview();
+       
+       // If the canvas is really big, zoom out so that we can fit it all in the window
+       /*! \todo In other words, this is a zoom-to-fit, and should be 
+       ** in it's own function.
+       */
+       int w=get_canvas()->rend_desc().get_w()+70;
+       int h=get_canvas()->rend_desc().get_h()+70;
+       while(w>700 || h>600)
+       {
+               work_area->zoom_out();
+               w=round_to_int(get_canvas()->rend_desc().get_w()*work_area->get_zoom()+70);
+               h=round_to_int(get_canvas()->rend_desc().get_h()*work_area->get_zoom()+70);
+       } 
+       if(w>700)w=700;
+       if(h>600)h=600; 
+       set_default_size(w,h);
+       property_window_position().set_value(Gtk::WIN_POS_NONE);
+       
+       
+       
+       
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("STRING") );
+       listTargets.push_back( Gtk::TargetEntry("text/plain") );
+       listTargets.push_back( Gtk::TargetEntry("image") );
+
+       drag_dest_set(listTargets);
+       signal_drag_data_received().connect( sigc::mem_fun(*this, &studio::CanvasView::on_drop_drag_data_received) );
+
+
+       /*
+       Time length(get_canvas()->rend_desc().get_time_end()-get_canvas()->rend_desc().get_time_start());
+       if(length<10.0)
+       {
+               time_window_adjustment().set_page_increment(length);
+               time_window_adjustment().set_page_size(length);
+       }
+       else
+       {
+               time_window_adjustment().set_page_increment(10.0);
+               time_window_adjustment().set_page_size(10.0);
+       }
+       */
+       
+       //sinfg::info("Canvasview: Before Sound Hookup");
+       //load sound info from meta data
+       {
+               //sinfg::warning("Should load Audio: %s with %s offset",apath.c_str(),aoffset.c_str());
+               
+               on_audio_file_notify(); //redundant setting of the metadata, but oh well, it's no big deal :)
+               on_audio_offset_notify();
+               
+               //signal connection - since they are all associated with the canvas view
+               
+               //hook in signals for sound options box
+               sound_dialog->signal_file_changed().connect(sigc::mem_fun(*this,&CanvasView::on_audio_file_change));
+               sound_dialog->signal_offset_changed().connect(sigc::mem_fun(*this,&CanvasView::on_audio_offset_change));
+               
+               //attach to the preview when it's visible               
+               //preview_dialog->get_widget().signal_play().connect(sigc::mem_fun(*this,&CanvasView::play_audio));
+               //preview_dialog->get_widget().signal_stop().connect(sigc::mem_fun(*this,&CanvasView::stop_audio));
+               
+               //hook to metadata signals
+               get_canvas()->signal_meta_data_changed("audiofile").connect(sigc::mem_fun(*this,&CanvasView::on_audio_file_notify));
+               get_canvas()->signal_meta_data_changed("audiooffset").connect(sigc::mem_fun(*this,&CanvasView::on_audio_offset_notify));
+
+               //universal_scrubber=std::auto_ptr<UniversalScrubber>(new UniversalScrubber(this));
+       }
+       
+       //sinfg::info("Canvasview: Before Final time set up");
+       //MORE TIME STUFF
+       time_window_adjustment().set_value(get_canvas()->rend_desc().get_time_start());
+       time_window_adjustment().value_changed();
+
+       
+       GRAB_HINT_DATA("canvas_view");
+       /*
+       {
+       set_skip_taskbar_hint(true);
+       set_skip_pager_hint(true);
+       set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+       }
+       */
+       
+       refresh_rend_desc();    
+       hide_tables();
+
+       on_time_changed();      
+       //sinfg::info("Canvasview: Constructor Done");  
+}
+
+CanvasView::~CanvasView()
+{
+       signal_deleted()();
+
+       App::ui_manager()->remove_action_group(action_group);
+
+       // Shut down the smach
+       smach_.egress();
+       smach_.set_default_state(0);
+
+       // We want to ensure that the UI_Manager and
+       // the selection manager get destructed right now.
+       ui_interface_.reset();
+       selection_manager_.reset();
+
+       // Delete any external widgets
+       for(;!ext_widget_book_.empty();ext_widget_book_.erase(ext_widget_book_.begin()))
+       {
+               if(ext_widget_book_.begin()->second)
+                       delete ext_widget_book_.begin()->second;
+       }
+       
+       //delete preview
+       audio.reset();
+               
+       hide();
+       
+       sinfg::info("CanvasView:~CanvasView(): Destructor Finished");
+}
+
+
+
+Gtk::Widget *
+CanvasView::create_time_bar()
+{
+       Gtk::Image *icon;
+
+       Gtk::HScrollbar *time_window_scroll = manage(new class Gtk::HScrollbar(time_window_adjustment()));
+       //Gtk::HScrollbar *time_scroll = manage(new class Gtk::HScrollbar(time_adjustment()));
+       //TIME BAR TEMPORARY POSITION
+       //Widget_Timeslider *time_scroll = manage(new Widget_Timeslider);
+       timeslider->show();
+       timeslider->set_time_adjustment(&time_adjustment());
+       timeslider->set_bounds_adjustment(&time_window_adjustment());
+       //layout_table->attach(*timeslider, 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL);
+       
+       
+       tooltips.set_tip(*time_window_scroll,_("Moves the time window"));
+       tooltips.set_tip(*timeslider,_("Changes the current time"));
+       time_window_scroll->show();
+       timeslider->show();
+       time_window_scroll->set_flags(Gtk::CAN_FOCUS);
+       timeslider->set_flags(Gtk::CAN_FOCUS);
+
+       //time_scroll->signal_value_changed().connect(sigc::mem_fun(*work_area, &studio::WorkArea::render_preview_hook));
+       //time_scroll->set_update_policy(Gtk::UPDATE_DISCONTINUOUS);
+       
+       NORMAL_BUTTON(animatebutton,"gtk-yes","Animate");
+       animatebutton->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_animate_button_pressed));
+       animatebutton->show();
+
+       NORMAL_BUTTON(keyframebutton,"sinfg-keyframe_lock_all","All Keyframes Locked");
+       keyframebutton->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_keyframe_button_pressed));
+       keyframebutton->show();
+       
+       Gtk::Table *table= manage(new class Gtk::Table(2, 3, false));
+
+       //setup the audio display
+       disp_audio->set_size_request(-1,32); //disp_audio.show(); 
+       disp_audio->set_time_adjustment(&time_adjustment());
+       disp_audio->signal_start_scrubbing().connect(
+               sigc::mem_fun(*audio,&AudioContainer::start_scrubbing)
+       );
+       disp_audio->signal_scrub().connect(
+               sigc::mem_fun(*audio,&AudioContainer::scrub)
+       );
+       disp_audio->signal_stop_scrubbing().connect(
+               sigc::mem_fun(*audio,&AudioContainer::stop_scrubbing)
+       );
+       
+       table->attach(*manage(disp_audio), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK);
+       table->attach(*timeslider, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       table->attach(*time_window_scroll, 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+
+       table->attach(*animatebutton, 1, 2, 0, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       table->attach(*keyframebutton, 2, 3, 0, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       timebar=table;
+       table->show();
+       return table;
+}
+
+Gtk::Widget *
+CanvasView::create_work_area()
+{
+       work_area=std::auto_ptr<WorkArea>(new class studio::WorkArea(canvas_interface_));
+       work_area->set_instance(get_instance());
+       work_area->set_canvas(get_canvas());
+       work_area->set_canvas_view(this);
+       work_area->set_progress_callback(get_ui_interface().get());
+       work_area->signal_popup_menu().connect(sigc::mem_fun(*this, &studio::CanvasView::popup_main_menu));
+       work_area->show();
+       return work_area.get();
+}
+
+
+Gtk::Widget*
+CanvasView::create_status_bar()
+{
+       Gtk::Image *icon;
+       Gtk::IconSize iconsize=Gtk::IconSize::from_name("sinfg-small_icon");
+       cancel=false;
+
+       // Create the status bar at the bottom of the window
+       Gtk::Table *statusbartable= manage(new class Gtk::Table(7, 1, false));
+//     statusbar = manage(new class Gtk::Statusbar()); // This is already done at construction
+       progressbar =manage(new class Gtk::ProgressBar());
+       SMALL_BUTTON(stopbutton,"gtk-stop","Stop");
+       SMALL_BUTTON(refreshbutton,"gtk-refresh","Refresh");
+       //SMALL_BUTTON(treetogglebutton,"gtk-go-down","Toggle Layer Tree");
+//     NEW_SMALL_BUTTON(raisebutton,"gtk-go-up","Raise Layer");
+//     NEW_SMALL_BUTTON(lowerbutton,"gtk-go-down","Lower Layer");
+       //statusbartable->attach(*treetogglebutton, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+//     statusbartable->attach(*lowerbutton, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+//     statusbartable->attach(*raisebutton, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+
+       current_time_widget=manage(new Widget_Time);
+       current_time_widget->set_value(get_time());
+       current_time_widget->set_fps(get_canvas()->rend_desc().get_frame_rate());
+       current_time_widget->signal_value_changed().connect(
+               sigc::mem_fun(*this,&CanvasView::on_current_time_widget_changed)
+       );
+
+       statusbartable->attach(*current_time_widget, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       statusbartable->attach(*statusbar, 3, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       statusbartable->attach(*progressbar, 4, 5, 0, 1, Gtk::SHRINK, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       statusbartable->attach(*refreshbutton, 5, 6, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       statusbartable->attach(*stopbutton, 6, 7, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       statusbar->set_has_resize_grip(false);
+       statusbar->show();
+       stopbutton->show();
+       refreshbutton->show();
+       progressbar->show();
+       stopbutton->set_sensitive(false);
+
+       //refreshbutton->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_refresh_pressed));
+       //stopbutton->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::stop));
+       //treetogglebutton->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::toggle_tables));
+
+       refreshbutton->signal_clicked().connect(SLOT_EVENT(EVENT_REFRESH));
+       stopbutton->signal_clicked().connect(SLOT_EVENT(EVENT_STOP));
+
+       
+       statusbartable->show_all();
+       return statusbartable;
+}
+
+void
+CanvasView::on_current_time_widget_changed()
+{
+       set_time(current_time_widget->get_value());
+}
+
+Gtk::Widget*
+CanvasView::create_children_tree()
+{
+       // Create the layer tree
+       children_tree=manage(new class ChildrenTree());
+
+       // Set up the layer tree
+       //children_tree->set_model(children_tree_store());
+       if(children_tree)children_tree->set_time_adjustment(time_adjustment());
+       if(children_tree)children_tree->show();
+
+       // Connect Signals
+       if(children_tree)children_tree->signal_edited_value().connect(sigc::mem_fun(*this, &studio::CanvasView::on_edited_value));
+       if(children_tree)children_tree->signal_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_children_user_click));
+       if(children_tree)children_tree->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_waypoint_clicked));
+       if(children_tree)children_tree->get_selection()->signal_changed().connect(SLOT_EVENT(EVENT_REFRESH_DUCKS));
+
+       return children_tree;   
+}
+
+Gtk::Widget*
+CanvasView::create_keyframe_tree()
+{
+       keyframe_tree=manage(new KeyframeTree());
+
+       //keyframe_tree->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+       //keyframe_tree->show();
+       //keyframe_tree->set_model(keyframe_tree_store());
+       keyframe_tree->set_editable(true);
+       //keyframe_tree->signal_edited().connect(sigc::hide_return(sigc::mem_fun(*canvas_interface(), &sinfgapp::CanvasInterface::update_keyframe)));
+
+       keyframe_tree->signal_event().connect(sigc::mem_fun(*this, &studio::CanvasView::on_keyframe_tree_event));
+       
+       Gtk::ScrolledWindow *scroll_layer_tree = manage(new class Gtk::ScrolledWindow());
+       scroll_layer_tree->set_flags(Gtk::CAN_FOCUS);
+       scroll_layer_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scroll_layer_tree->add(*keyframe_tree);
+       scroll_layer_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       //scroll_layer_tree->show();
+
+       
+       Gtk::Table *layout_table= manage(new Gtk::Table(1, 2, false));  
+       layout_table->attach(*scroll_layer_tree, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       Gtk::Image *icon;
+       Gtk::IconSize iconsize(Gtk::IconSize::from_name("sinfg-small_icon"));
+
+       NEW_SMALL_BUTTON(button_add,"gtk-add","New Keyframe");
+       NEW_SMALL_BUTTON(button_duplicate,"sinfg-duplicate","Duplicate Keyframe");
+       NEW_SMALL_BUTTON(button_delete,"gtk-delete","Delete Keyframe");
+
+       Gtk::HBox *hbox(manage(new Gtk::HBox()));
+       layout_table->attach(*hbox, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       
+       hbox->pack_start(*button_add,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+       
+       /*
+       button_raise->set_relief(Gtk::RELIEF_HALF);
+       button_lower->set_relief(Gtk::RELIEF_HALF);
+       button_duplicate->set_relief(Gtk::RELIEF_HALF);
+       button_delete->set_relief(Gtk::RELIEF_HALF);
+       */
+       
+       button_add->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_keyframe_add_pressed));
+       button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_keyframe_duplicate_pressed));
+       button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_keyframe_remove_pressed));
+
+       //layout_table->show_all();
+
+       keyframe_tab_child=layout_table;
+       
+       
+       layout_table->hide();
+       
+       return layout_table;    
+}
+
+Gtk::Widget*
+CanvasView::create_layer_tree()
+{
+       // Create the layer tree
+       layer_tree=manage(new class LayerTree());
+
+       // Set up the layer tree
+       //layer_tree->set_model(layer_tree_store());
+       layer_tree->set_time_adjustment(time_adjustment());
+       layer_tree->show();
+
+       // Connect Signals
+       layer_tree->signal_layer_toggle().connect(sigc::mem_fun(*this, &studio::CanvasView::on_layer_toggle));
+       layer_tree->signal_edited_value().connect(sigc::mem_fun(*this, &studio::CanvasView::on_edited_value));
+       layer_tree->signal_layer_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_layer_user_click));
+       layer_tree->signal_param_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_children_user_click));
+       layer_tree->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_waypoint_clicked));
+       layer_tree->get_selection()->signal_changed().connect(SLOT_EVENT(EVENT_REFRESH_DUCKS));
+
+       layer_tree->hide();
+       return layer_tree;      
+}
+
+void
+CanvasView::init_menus()
+{
+/*
+       mainmenu.set_accel_group(get_accel_group());
+       mainmenu.set_accel_path("<Canvas-view>");
+
+       filemenu.set_accel_group(get_accel_group());
+       filemenu.set_accel_path("<Canvas-view>/File");
+
+       editmenu.set_accel_group(get_accel_group());
+       editmenu.set_accel_path("<Canvas-view>/Edit");
+
+       layermenu.set_accel_group(get_accel_group());
+       layermenu.set_accel_path("<Canvas-view>/Layer");
+*/
+       //cache the position of desired widgets
+       
+       /*Menus to worry about:
+       - filemenu
+       - editmenu
+       - layermenu
+       - duckmaskmenu
+       - mainmenu
+       - canvasmenu
+       - viewmenu
+       */
+       action_group = Gtk::ActionGroup::create();
+       
+       //action_group->add( Gtk::Action::create("MenuFile", "_File") );
+       action_group->add( Gtk::Action::create("save", Gtk::Stock::SAVE),
+               hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::save))
+       );
+       action_group->add( Gtk::Action::create("save-as", Gtk::Stock::SAVE_AS),
+               sigc::hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::dialog_save_as))
+       );
+       action_group->add( Gtk::Action::create("revert", Gtk::Stock::REVERT_TO_SAVED),
+               sigc::hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::safe_revert))
+       );
+       action_group->add( Gtk::Action::create("cvs-add", Gtk::StockID("sinfg-cvs_add")),
+               sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_add))
+       );
+       action_group->add( Gtk::Action::create("cvs-update", Gtk::StockID("sinfg-cvs_update")),
+               sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_update))
+       );
+       action_group->add( Gtk::Action::create("cvs-revert", Gtk::StockID("sinfg-cvs_revert")),
+               sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_revert))
+       );
+       action_group->add( Gtk::Action::create("cvs-commit", Gtk::StockID("sinfg-cvs_commit")),
+               sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_commit))
+       );
+       action_group->add( Gtk::Action::create("import", _("Import")),
+               sigc::hide_return(sigc::mem_fun(*this, &studio::CanvasView::image_import))
+       );
+       action_group->add( Gtk::Action::create("render", _("Render")),
+               sigc::mem_fun(render_settings,&studio::RenderSettings::present)
+       );
+       action_group->add( Gtk::Action::create("preview", _("Preview")),
+               sigc::mem_fun(*this,&CanvasView::on_preview_option)
+       );
+       action_group->add( Gtk::Action::create("sound", _("Sound File")),
+               sigc::mem_fun(*this,&CanvasView::on_audio_option)
+       );
+       action_group->add( Gtk::Action::create("options", _("Options")),
+               sigc::mem_fun(canvas_options,&studio::CanvasOptions::present)
+       );
+       action_group->add( Gtk::Action::create("close", Gtk::StockID("gtk-close")),
+               sigc::hide_return(sigc::mem_fun(*this,&studio::CanvasView::close))      
+       );
+
+       //action_group->add( Gtk::Action::create("undo", Gtk::StockID("gtk-undo")),
+       //      SLOT_EVENT(EVENT_UNDO)
+       //);
+
+       //action_group->add( Gtk::Action::create("redo", Gtk::StockID("gtk-redo")),
+       //      SLOT_EVENT(EVENT_REDO)
+       //);
+
+       action_group->add( Gtk::Action::create("select-all-ducks", _("Select All Ducks")),
+               sigc::mem_fun(*work_area,&studio::WorkArea::select_all_ducks)
+       );
+
+       action_group->add( Gtk::Action::create("unselect-all-layers", _("Unselect All Layers")),
+               sigc::mem_fun(*this,&CanvasView::on_unselect_layers)
+       );
+
+       action_group->add( Gtk::Action::create("stop", Gtk::StockID("gtk-stop")),
+               SLOT_EVENT(EVENT_STOP)
+       );
+       
+       action_group->add( Gtk::Action::create("refresh", Gtk::StockID("gtk-refresh")),
+               SLOT_EVENT(EVENT_REFRESH)
+       );
+
+       action_group->add( Gtk::Action::create("properties", Gtk::StockID("gtk-properties")),
+               sigc::mem_fun(canvas_properties,&studio::CanvasProperties::present)
+       );
+
+       // Preview Quality Menu
+       {
+               int i;
+               action_group->add( Gtk::RadioAction::create(quality_group,"quality-00", _("Use Parametric Renderer")),
+                       sigc::bind(
+                               sigc::mem_fun(*work_area, &studio::WorkArea::set_quality),
+                               0
+                       )
+               );
+               for(i=1;i<=10;i++)
+               {
+                       Glib::RefPtr<Gtk::RadioAction> action(Gtk::RadioAction::create(quality_group,strprintf("quality-%02d",i), strprintf("Set Quality to %d",i)));
+                       if(i==10)
+                               action->property_value()=10;
+                       action_group->add( action,
+                               sigc::bind(
+                                       sigc::mem_fun(*work_area, &studio::WorkArea::set_quality),
+                                       i
+                               )
+                       );
+               }
+       }
+
+       action_group->add( Gtk::Action::create("play", Gtk::StockID("sinfg-play")),
+               sigc::mem_fun(*this, &studio::CanvasView::play)
+       );
+       
+       action_group->add( Gtk::Action::create("dialog-flipbook", _("Flipbook Dialog")),
+               sigc::mem_fun(*preview_dialog, &studio::Dialog_Preview::present)
+       );
+
+       action_group->add( Gtk::Action::create("toggle-grid-show", _("Toggle Grid Show")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid)
+       );
+       action_group->add( Gtk::Action::create("toggle-grid-snap", _("Toggle Grid Snap")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid_snap)
+       );
+       action_group->add( Gtk::Action::create("toggle-guide-show", _("Toggle Guide Show")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_guide_snap)
+       );
+       action_group->add( Gtk::Action::create("toggle-low-res", _("Toggle Low-Res")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_low_resolution_flag)
+       );
+       action_group->add( Gtk::Action::create("toggle-onion-skin", _("Toggle Onion Skin")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_onion_skin)
+       );
+
+
+       action_group->add( Gtk::Action::create("canvas-zoom-fit", Gtk::StockID("gtk-zoom-fit")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_fit)
+       );
+       action_group->add( Gtk::Action::create("canvas-zoom-100", Gtk::StockID("gtk-zoom-100")),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_norm)
+       );
+
+
+       {
+               Glib::RefPtr<Gtk::Action> action;
+               
+               action=Gtk::Action::create("seek-next-frame", Gtk::Stock::GO_FORWARD,_("Next Frame"),_("Next Frame"));
+               action_group->add(action,sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_frame),1));
+               action=Gtk::Action::create("seek-prev-frame", Gtk::Stock::GO_BACK,_("Prev Frame"),_("Prev Frame"));
+               action_group->add( action, sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_frame),-1));
+
+               action=Gtk::Action::create("seek-next-second", Gtk::Stock::GO_FORWARD,_("Seek Foward"),_("Seek Foward"));
+               action_group->add(action,sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_time),Time(1)));
+               action=Gtk::Action::create("seek-prev-second", Gtk::Stock::GO_BACK,_("Seek Backward"),_("Seek Backward"));
+               action_group->add( action, sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_time),Time(-1)));
+
+               // Broken...!?
+               /*
+               action=Gtk::Action::create("seek-end", Gtk::Stock::GOTO_LAST,_("Seek to End"),_("Seek to End"));
+               action_group->add(action,sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_time),Time::end()));
+               */
+               action=Gtk::Action::create("seek-begin", Gtk::Stock::GOTO_FIRST,_("Seek to Begin"),_("Seek to Begin"));
+               action_group->add( action, sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek_time),Time::begin()));
+
+               action=Gtk::Action::create("jump-next-keyframe", Gtk::Stock::GO_FORWARD,_("Jump to Next Keyframe"),_("Jump to Next Keyframe"));
+               action_group->add( action,sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_next_keyframe));
+
+               action=Gtk::Action::create("jump-prev-keyframe", Gtk::Stock::GO_BACK,_("Jump to Prev Keyframe"),_("Jump to Prev Keyframe"));
+               action_group->add( action,sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_prev_keyframe));
+
+               action=Gtk::Action::create("canvas-zoom-in", Gtk::Stock::ZOOM_IN);
+               action_group->add( action,sigc::mem_fun(*work_area, &studio::WorkArea::zoom_in));
+               
+               action=Gtk::Action::create("canvas-zoom-out", Gtk::Stock::ZOOM_OUT);
+               action_group->add( action, sigc::mem_fun(*work_area, &studio::WorkArea::zoom_out) );
+               
+               action=Gtk::Action::create("time-zoom-in", Gtk::Stock::ZOOM_IN, _("Zoom In on Timeline"));
+               action_group->add( action, sigc::mem_fun(*this, &studio::CanvasView::time_zoom_in) );
+               
+               action=Gtk::Action::create("time-zoom-out", Gtk::Stock::ZOOM_OUT, _("Zoom Out on Timeline"));
+               action_group->add( action, sigc::mem_fun(*this, &studio::CanvasView::time_zoom_out) );
+               
+       }
+
+
+#define DUCK_MASK(lower,upper) \
+       duck_mask_##lower=Gtk::ToggleAction::create("mask-" #lower "-ducks", _("Mask "#lower" ducks")); \
+       duck_mask_##lower->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_##upper)); \
+       action_group->add( duck_mask_##lower, \
+               sigc::bind( \
+                       sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask), \
+                       Duck::TYPE_##upper \
+               ) \
+       ) 
+       DUCK_MASK(position,POSITION);
+       DUCK_MASK(tangent,TANGENT);
+       DUCK_MASK(vertex,VERTEX);
+       DUCK_MASK(radius,RADIUS);
+       DUCK_MASK(width,WIDTH);
+       DUCK_MASK(angle,ANGLE);
+#undef DUCK_MASK
+
+       add_accel_group(App::ui_manager()->get_accel_group());
+
+/*     // Here is where we add the actions that may have conflicting
+       // keyboard accelerators.
+       {
+               Glib::RefPtr<Gtk::ActionGroup> accel_action_group(Gtk::ActionGroup::create("canvas_view"));
+               Glib::RefPtr<Gtk::Action> action;
+               
+               action=Gtk::Action::create("seek-next-frame", Gtk::StockID("gtk-forward"),_("Next Frame"),_("Next Frame"));
+               accel_action_group->add(action,sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek),1));
+
+               action=Gtk::Action::create("seek-prev-frame", Gtk::StockID("gtk-forward"),_("Prev Frame"),_("Prev Frame"));
+               accel_action_group->add( action, sigc::bind(sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::seek),-1));
+
+               action=Gtk::Action::create("jump-next-keyframe", Gtk::StockID("gtk-forward"),_("Jump to Next Keyframe"),_("Jump to Next Keyframe"));
+               accel_action_group->add( action,sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_next_keyframe));
+
+               action=Gtk::Action::create("jump-prev-keyframe", Gtk::StockID("gtk-back"),_("Jump to Prev Keyframe"),_("Jump to Prev Keyframe"));
+               accel_action_group->add( action,sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_prev_keyframe));
+
+               action=Gtk::Action::create("canvas-zoom-in", Gtk::StockID("gtk-zoom-in"));
+               accel_action_group->add( action,sigc::mem_fun(*work_area, &studio::WorkArea::zoom_in));
+               
+               action=Gtk::Action::create("canvas-zoom-out", Gtk::StockID("gtk-zoom-out"));
+               accel_action_group->add( action, sigc::mem_fun(*work_area, &studio::WorkArea::zoom_out) );
+               
+               action=Gtk::Action::create("time-zoom-in", Gtk::StockID("gtk-zoom-in"), _("Zoom In on Timeline"));
+               accel_action_group->add( action, sigc::mem_fun(*this, &studio::CanvasView::time_zoom_in) );
+               
+               action=Gtk::Action::create("time-zoom-out", Gtk::StockID("gtk-zoom-out"), _("Zoom Out on Timeline"));
+               accel_action_group->add( action, sigc::mem_fun(*this, &studio::CanvasView::time_zoom_out) );
+               
+               Glib::RefPtr<Gtk::UIManager> accel_ui_manager(Gtk::UIManager::create());
+
+               Glib::ustring ui_info =
+               "
+               <ui>
+                       <accelerator action='seek-next-frame' />
+                       <accelerator action='seek-prev-frame' />
+                       <accelerator action='jump-next-keyframe' />
+                       <accelerator action='jump-prev-keyframe' />
+                       <accelerator action='canvas-zoom-in' />
+                       <accelerator action='canvas-zoom-out' />
+                       <accelerator action='time-zoom-in' />
+                       <accelerator action='time-zoom-out' />
+               </ui>
+               ";
+
+               accel_ui_manager->add_ui_from_string(ui_info);
+               add_accel_group(accel_ui_manager->get_accel_group());
+       
+               accel_ui_manager->insert_action_group(accel_action_group);
+               set_ref_obj("accel_ui_manager",accel_ui_manager);
+               set_ref_obj("accel_action_group",accel_action_group);
+       }
+*/
+
+
+
+#if 0  
+       
+       //Test some key stuff
+       
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-save"),
+               hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::save))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-save-as"),sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_save_as))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-revert-to-saved"),hide_return(sigc::mem_fun(*get_instance().get(), &studio::Instance::safe_revert))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-cvs_add"),sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_add))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-cvs_update"),sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_update))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-cvs_commit"),sigc::hide_return(sigc::mem_fun(*get_instance(), &studio::Instance::dialog_cvs_commit))));
+
+       filemenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       filemenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Import..."),Gtk::AccelKey('I',Gdk::CONTROL_MASK),sigc::hide_return(sigc::mem_fun(*this, &studio::CanvasView::image_import))));
+       filemenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       filemenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Render"),Gtk::AccelKey("F9"),
+               sigc::mem_fun(render_settings,&studio::RenderSettings::present)
+       ));
+       filemenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Preview"),Gtk::AccelKey("F11"),
+               sigc::mem_fun(*this,&CanvasView::on_preview_option)
+       ));     
+       filemenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Sound File"),
+               sigc::mem_fun(*this,&CanvasView::on_audio_option)
+       ));     
+       
+       filemenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       filemenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Options"),Gtk::AccelKey("F12"),
+               sigc::mem_fun(canvas_options,&studio::CanvasOptions::present)
+       ));
+       filemenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       filemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-close"),sigc::hide_return(sigc::mem_fun(*this,&studio::CanvasView::close))));
+
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-undo"),Gtk::AccelKey('Z',Gdk::CONTROL_MASK),SLOT_EVENT(EVENT_UNDO)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-redo"),Gtk::AccelKey('R',Gdk::CONTROL_MASK),SLOT_EVENT(EVENT_REDO)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-cut"),NOT_IMPLEMENTED_SLOT));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-copy"),NOT_IMPLEMENTED_SLOT));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-paste"),NOT_IMPLEMENTED_SLOT));
+       editmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       editmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Select All Ducks"),Gtk::AccelKey('E',Gdk::CONTROL_MASK),sigc::mem_fun(*work_area,&studio::WorkArea::select_all_ducks)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Unselect All Layers"),Gtk::AccelKey('D',Gdk::CONTROL_MASK),sigc::mem_fun(*this,&CanvasView::on_unselect_layers)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       //editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-stop"),Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0)),sigc::hide_return(sigc::mem_fun(*this, &studio::CanvasView::stop))));
+       //editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-refresh"),Gtk::AccelKey('k',Gdk::CONTROL_MASK),sigc::hide_return(sigc::mem_fun(*this, &studio::CanvasView::on_refresh_pressed))));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-stop"),Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0)),SLOT_EVENT(EVENT_STOP)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-refresh"),Gtk::AccelKey('k',Gdk::CONTROL_MASK),SLOT_EVENT(EVENT_REFRESH)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-rotoscope_bline"),
+               sigc::mem_fun(*this, &studio::CanvasView::do_rotoscope_bline)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-rotoscope_polygon"),
+               sigc::mem_fun(*this, &studio::CanvasView::do_rotoscope_poly)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-eyedrop"),
+               sigc::mem_fun(*this, &studio::CanvasView::do_eyedrop)));
+       editmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       editmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-properties"),Gtk::AccelKey("F8"),
+               sigc::mem_fun(canvas_properties,&studio::CanvasProperties::present)
+       ));
+
+       build_new_layer_menu(newlayermenu);
+       layermenu.items().push_back(Gtk::Menu_Helpers::MenuElem("New",newlayermenu));
+
+
+       {
+               sinfgapp::Action::ParamList param_list;
+               param_list.add("canvas",Canvas::Handle(get_canvas()));
+               param_list.add("canvas_interface",canvas_interface());
+               add_actions_to_menu(&canvasmenu, param_list,sinfgapp::Action::CATEGORY_CANVAS);
+       }
+
+       
+       //canvasmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Keyframe Dialog",sigc::mem_fun(keyframe_dialog,&studio::Dialog_Keyframe::present)));
+
+       // Duck Mask Menu
+       if(1)
+               {
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::TearoffMenuElem());
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Position Ducks"),Gtk::AccelKey('1',Gdk::MOD1_MASK)));
+               duck_mask_position=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_position->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_POSITION));
+               duck_mask_position->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_POSITION
+                       )
+               );
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Vertex Ducks"),Gtk::AccelKey('2',Gdk::MOD1_MASK)));
+               duck_mask_vertex=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_vertex->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_VERTEX));
+               duck_mask_vertex->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_VERTEX
+                       )
+               );
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Tangent Ducks"),Gtk::AccelKey('3',Gdk::MOD1_MASK)));
+               duck_mask_tangent=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_tangent->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_TANGENT));
+               duck_mask_tangent->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_TANGENT
+                       )
+               );
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Radius Ducks"),Gtk::AccelKey('4',Gdk::MOD1_MASK)));
+               duck_mask_radius=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_radius->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_RADIUS));
+               duck_mask_radius->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_RADIUS
+                       )
+               );
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Width Ducks"),Gtk::AccelKey('5',Gdk::MOD1_MASK)));
+               duck_mask_width=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_width->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_WIDTH));
+               duck_mask_width->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_WIDTH
+                       )
+               );
+
+               duckmaskmenu.items().push_back(Gtk::Menu_Helpers::CheckMenuElem(_("Angle Ducks"),Gtk::AccelKey('6',Gdk::MOD1_MASK)));
+               duck_mask_angle=static_cast<Gtk::CheckMenuItem*>(&duckmaskmenu.items().back());
+               duck_mask_angle->set_active((bool)(work_area->get_type_mask()&Duck::TYPE_ANGLE));
+               duck_mask_angle->signal_toggled().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this, &studio::CanvasView::toggle_duck_mask),
+                               Duck::TYPE_ANGLE
+                       )
+               );
+
+               viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Mask Ducks"),duckmaskmenu));
+       }
+       
+       // Preview Quality Menu
+       if(1)
+       {
+               qualitymenu.items().push_back(Gtk::Menu_Helpers::TearoffMenuElem());
+               int i;
+               qualitymenu.items().push_back(Gtk::Menu_Helpers::MenuElem(strprintf(_("Use Parametric Renderer"),0),
+                       sigc::bind(
+                               sigc::mem_fun(*work_area, &studio::WorkArea::set_quality),
+                               0
+                       )
+               ));
+               for(i=1;i<=10;i++)
+               {
+                       qualitymenu.items().push_back(Gtk::Menu_Helpers::MenuElem(strprintf(_("Set Quality to %d"),i),Gtk::AccelKey('0'+(i%10),Gdk::CONTROL_MASK),
+                               sigc::bind(
+                                       sigc::mem_fun(*work_area, &studio::WorkArea::set_quality),
+                                       i
+                               )
+                       ));
+               }
+               viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Preview Quality"),qualitymenu));
+       }
+       
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-play"),
+               sigc::mem_fun(*this, &studio::CanvasView::play)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("Flipbook Dialog"),
+               sigc::mem_fun(*preview_dialog, &studio::Dialog_Preview::present)));
+
+       viewmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Toggle Grid Show"),Gtk::AccelKey('g',Gdk::CONTROL_MASK),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Toggle Grid Snap"),Gtk::AccelKey('l',Gdk::CONTROL_MASK),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_grid_snap)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Toggle Guide Snap"),Gtk::AccelKey('k',Gdk::CONTROL_MASK),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_guide_snap)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Toggle Low-Res"),Gtk::AccelKey('`',Gdk::CONTROL_MASK),
+               sigc::mem_fun(*work_area, &studio::WorkArea::toggle_low_resolution_flag)));
+       
+       viewmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-in"),Gtk::AccelKey('=',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_in)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-out"),Gtk::AccelKey('-',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_out)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-fit"),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_fit)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-100"),Gtk::AccelKey('`',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*work_area, &studio::WorkArea::zoom_norm)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-in"),Gtk::AccelKey('+',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*this, &studio::CanvasView::time_zoom_in)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-zoom-out"),Gtk::AccelKey('_',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*this, &studio::CanvasView::time_zoom_out)));
+
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Jump to Next Keyframe"),Gtk::AccelKey(']',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_next_keyframe)));
+       viewmenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Jump to Prev Keyframe"),Gtk::AccelKey('[',static_cast<Gdk::ModifierType>(0)),
+               sigc::mem_fun(*canvas_interface().get(), &sinfgapp::CanvasInterface::jump_to_prev_keyframe)));
+
+       mainmenu.items().push_back(Gtk::Menu_Helpers::TearoffMenuElem());
+       mainmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("_File",filemenu));
+       mainmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("_Edit",editmenu));
+       mainmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("_View",viewmenu));
+       mainmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("_Canvas",canvasmenu));
+       mainmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("_Layer",layermenu));
+
+       mainmenu.accelerate(*this);
+       
+       {
+               
+               trackmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("New Waypoint",NOT_IMPLEMENTED_SLOT));
+               trackmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Delete Waypoint",NOT_IMPLEMENTED_SLOT));
+               trackmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Export",NOT_IMPLEMENTED_SLOT));
+               trackmenu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+               trackmenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Properties",NOT_IMPLEMENTED_SLOT));
+       }
+       mainmenu.show();
+       filemenu.show();
+       editmenu.show();
+       canvasmenu.show();
+       layermenu.show();
+
+       keyframemenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-properties"),
+               sigc::mem_fun(*this,&studio::CanvasView::show_keyframe_dialog)
+       ));
+
+
+       get_accel_group()->unlock();
+
+       //Set the accelerator paths for all the menus
+       filemenu.set_accel_path("<synfig>/File");
+       editmenu.set_accel_path("<synfig>/Edit");
+       layermenu.set_accel_path("<synfig>/Layer");
+       //mainmenu.set_accel_path("<sinfg-main>");
+       canvasmenu.set_accel_path("<synfig>/Canvas");
+       viewmenu.set_accel_path("<synfig>/View");
+       duckmaskmenu.set_accel_path("<synfig>/DuckMask");
+#endif 
+}
+
+void
+CanvasView::on_unselect_layers()
+{
+       layer_tree->clear_selected_layers();
+}
+
+void
+CanvasView::show_keyframe_dialog()
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection(keyframe_tree->get_selection());
+       if(selection->get_selected())
+       {
+               Gtk::TreeRow row(*selection->get_selected());
+               
+               Keyframe keyframe(row[keyframe_tree->model.keyframe]);
+               
+               keyframe_dialog.set_keyframe(keyframe);
+               keyframe_dialog.present();
+       }
+}
+
+void
+CanvasView::add_layer(sinfg::String x)
+{
+       Canvas::Handle canvas;
+       
+       sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+       
+       int target_depth(0);
+       
+       if(layer_list.empty())
+       {
+               canvas=get_canvas();
+       }
+       else
+       {
+               canvas=(*layer_list.begin())->get_canvas();
+               target_depth=canvas->get_depth(*layer_list.begin());
+       }
+
+       
+       Layer::Handle layer(canvas_interface()->add_layer_to(x,canvas,target_depth));
+       if(layer)
+       {
+               get_selection_manager()->clear_selected_layers();
+               get_selection_manager()->set_selected_layer(layer);             
+       }
+}
+
+void
+CanvasView::popup_layer_menu(sinfg::Layer::Handle layer)
+{
+       //Gtk::Menu* menu(manage(new Gtk::Menu));
+       Gtk::Menu* menu(&parammenu);
+       menu->items().clear();
+       
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",canvas_interface()->get_time());
+       param_list.add("canvas",Canvas::Handle(layer->get_canvas()));
+       param_list.add("canvas_interface",canvas_interface());
+       param_list.add("layer",layer);
+       
+       //Gtk::Menu *newlayers(manage(new Gtk::Menu()));
+       //build_new_layer_menu(*newlayers);
+       
+       //parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("New Layer"),*newlayers));
+
+       if(layer->get_name()=="PasteCanvas")
+       {
+               menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Select All Children"),
+                       sigc::bind(
+                               sigc::mem_fun(
+                                       *layer_tree,
+                                       &studio::LayerTree::select_all_children_layers
+                               ),
+                               layer
+                       )
+               ));
+       }
+       
+       add_actions_to_menu(menu, param_list,sinfgapp::Action::CATEGORY_LAYER);
+       
+       menu->popup(3,gtk_get_current_event_time());
+}
+
+void
+CanvasView::register_layer_type(sinfg::Layer::Book::value_type &lyr,std::map<sinfg::String,Gtk::Menu*>* category_map)
+{
+/*     if(lyr.second.category==_("Do Not Use"))
+               return;
+       
+       if(category_map->count(lyr.second.category)==0)
+               (*category_map)[lyr.second.category]=manage(new Gtk::Menu());
+
+       (*category_map)[lyr.second.category]->items().push_back(Gtk::Menu_Helpers::MenuElem(lyr.second.local_name,
+               sigc::hide_return(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::CanvasView::add_layer),
+                               lyr.first
+                       )
+               )
+       ));
+*/
+}
+
+void
+CanvasView::build_new_layer_menu(Gtk::Menu &menu)
+{
+/*
+       std::map<sinfg::String,Gtk::Menu*> category_map;
+
+       std::for_each(
+               sinfg::Layer::book().begin(),
+               sinfg::Layer::book().end(),
+               sigc::bind(
+                       sigc::mem_fun(
+                               *this,
+                               &studio::CanvasView::register_layer_type
+                       ),
+                       &category_map
+               )
+       );
+
+       menu.items().clear();
+       menu.items().push_back(Gtk::Menu_Helpers::TearoffMenuElem());
+
+       std::map<sinfg::String,Gtk::Menu*>::iterator iter;
+       for(iter=category_map.begin();iter!=category_map.end();++iter)
+               menu.items().push_back(Gtk::Menu_Helpers::MenuElem(iter->first,*iter->second)); 
+
+       menu.show();
+*/
+}
+
+void
+CanvasView::popup_main_menu()
+{
+       //mainmenu.popup(0,gtk_get_current_event_time());
+       Gtk::Menu* menu = dynamic_cast<Gtk::Menu*>(App::ui_manager()->get_widget("/menu-main"));
+       if(menu)
+       {
+               //menu->set_accel_group(App::ui_manager()->get_accel_group());
+               //menu->accelerate(*this);
+               menu->popup(0,gtk_get_current_event_time());
+       }
+}
+
+void
+CanvasView::on_refresh_pressed()
+{
+       rebuild_tables();
+       rebuild_ducks();
+       work_area->queue_render_preview();
+}
+
+void
+CanvasView::workarea_layer_selected(sinfg::Layer::Handle layer)
+{
+       get_selection_manager()->clear_selected_layers();
+       if(layer)
+               get_selection_manager()->set_selected_layer(layer);
+}
+
+
+void
+CanvasView::refresh_rend_desc()
+{
+       current_time_widget->set_fps(get_canvas()->rend_desc().get_frame_rate());
+
+       
+       //????
+       //sinfg::info("Canvasview: Refreshing render desc info");
+       if(!get_time().is_equal(time_adjustment().get_value()))
+       {
+               time_adjustment().set_value(get_time());
+               time_adjustment().value_changed();
+       }
+
+       Time length(get_canvas()->rend_desc().get_time_end()-get_canvas()->rend_desc().get_time_start());
+       if(length<DEFAULT_TIME_WINDOW_SIZE)
+       {
+               time_window_adjustment().set_page_increment(length);
+               time_window_adjustment().set_page_size(length);
+       }
+       else
+       {
+               time_window_adjustment().set_page_increment(DEFAULT_TIME_WINDOW_SIZE);
+               time_window_adjustment().set_page_size(DEFAULT_TIME_WINDOW_SIZE);
+       }
+
+       //set the FPS of the timeslider
+       timeslider->set_global_fps(get_canvas()->rend_desc().get_frame_rate());
+       
+       //set the beginning and ending time of the time slider
+       Time begin_time=get_canvas()->rend_desc().get_time_start();
+       Time end_time=get_canvas()->rend_desc().get_time_end();
+
+       // Setup the time_window adjustment
+       time_window_adjustment().set_lower(begin_time);
+       time_window_adjustment().set_upper(end_time);
+       time_window_adjustment().set_step_increment(sinfg::Time(1.0/get_canvas()->rend_desc().get_frame_rate()));
+
+       //Time length(get_canvas()->rend_desc().get_time_end()-get_canvas()->rend_desc().get_time_start());
+       if(length < time_window_adjustment().get_page_size())
+       {
+               time_window_adjustment().set_page_increment(length);
+               time_window_adjustment().set_page_size(length);
+       }
+       
+       /*sinfg::info("w: %p - [%.3f,%.3f] (%.3f,%.3f) child: %p\n",
+                               &time_window_adjustment_, time_window_adjustment_.get_lower(),
+                               time_window_adjustment_.get_upper(),time_window_adjustment_.get_value(),
+                               time_window_adjustment_.get_page_size(),time_window_adjustment_.get_child_adjustment()
+       );*/
+       
+       time_window_adjustment().changed(); //only non-value stuff was changed
+
+       // Setup the time adjustment
+       
+       //NOTE THESE TWO SHOULD BE CHANGED BY THE changed() CALL ABOVE
+       //time_adjustment().set_lower(time_window_adjustment().get_value());
+       //time_adjustment().set_upper(time_window_adjustment().get_value()+time_window_adjustment().get_page_size());
+       
+//     time_adjustment().set_lower(get_canvas()->rend_desc().get_time_start());
+//     time_adjustment().set_upper(get_canvas()->rend_desc().get_time_end());
+       time_adjustment().set_step_increment(sinfg::Time(1.0/get_canvas()->rend_desc().get_frame_rate()));
+       time_adjustment().set_page_increment(sinfg::Time(1.0));
+       time_adjustment().set_page_size(0);
+       
+       time_adjustment().changed();
+       
+       /*sinfg::info("w: %p - [%.3f,%.3f] (%.3f,%.3f) child: %p\n",
+                               &time_window_adjustment_, time_window_adjustment_.get_lower(),
+                               time_window_adjustment_.get_upper(),time_window_adjustment_.get_value(),
+                               time_window_adjustment_.get_page_size(),time_window_adjustment_.get_child_adjustment()
+       );      */
+       
+       if(begin_time==end_time)
+       {
+               hide_timebar();
+       }
+       else
+       {
+               show_timebar();
+       }
+
+       //clamp time to big bounds...
+       if(time_adjustment().get_value() < begin_time)
+       {
+               time_adjustment().set_value(begin_time);
+               time_adjustment().value_changed();
+       }
+       
+       if(time_adjustment().get_value() > end_time)
+       {
+               time_adjustment().set_value(end_time);
+               time_adjustment().value_changed();
+       }
+       
+       /*sinfg::info("Time stats: \n"
+                               "w: %p - [%.3f,%.3f] (%.3f,%.3f) child: %p\n"
+                               "t: %p - [%.3f,%.3f] %.3f",
+                               &time_window_adjustment_, time_window_adjustment_.get_lower(),
+                               time_window_adjustment_.get_upper(),time_window_adjustment_.get_value(),
+                               time_window_adjustment_.get_page_size(),time_window_adjustment_.get_child_adjustment(),
+                               &time_adjustment_,time_adjustment_.get_lower(),time_adjustment_.get_upper(),
+                               time_adjustment_.get_value()
+       );*/
+
+       work_area->queue_render_preview();
+}
+
+
+bool
+CanvasView::close()
+{
+       hide();
+       // I think this is bad..., removing
+       //      get_instance()->canvas_view_list().erase(std::find(get_instance()->canvas_view_list().begin(),get_instance()->canvas_view_list().end(),this));
+       return false;
+}
+
+handle<CanvasView>
+CanvasView::create(loose_handle<Instance> instance,handle<Canvas> canvas)
+{
+       etl::handle<studio::CanvasView> view(new CanvasView(instance,instance->sinfgapp::Instance::find_canvas_interface(canvas)));
+       instance->canvas_view_list().push_front(view);
+       instance->signal_canvas_view_created()(view.get());
+       return view;
+}
+
+void
+CanvasView::update_title()
+{
+       string title;
+
+       title+=etl::basename(get_instance()->get_file_name())
+               +" : ";
+       if(get_canvas()->get_name().empty())
+               title+='"'+get_canvas()->get_id()+'"';
+       else
+               title+='"'+get_canvas()->get_name()+'"';
+
+       if(get_instance()->sinfgapp::Instance::get_action_count())
+               title+=_(" (Unsaved)");
+
+       if(get_instance()->sinfgapp::Instance::in_repository())
+       {
+               title+=" (CVS";
+               if(get_instance()->sinfgapp::Instance::is_modified())
+                       title+=_("-MODIFIED");
+               if(get_instance()->sinfgapp::Instance::is_updated())
+                       title+=_("-UPDATED");
+               title+=')';
+       }
+
+       if(get_canvas()->is_root())
+               title+=_(" (Root)");
+
+       set_title(title);
+}
+
+
+void
+CanvasView::on_hide()
+{
+       smach_.egress();
+       Gtk::Window::on_hide();
+}
+
+void
+CanvasView::present()
+{
+       grab_focus();//on_focus_in_event(0);
+       Gtk::Window::present();
+}
+
+bool
+CanvasView::on_focus_in_event(GdkEventFocus*x)
+{
+       if(studio::App::get_selected_canvas_view()!=this)
+       {
+               if(studio::App::get_selected_canvas_view())
+               {
+                       studio::App::get_selected_canvas_view()->get_smach().process_event(EVENT_YIELD_TOOL_OPTIONS);
+                       App::ui_manager()->remove_action_group(App::get_selected_canvas_view()->action_group);
+               }
+
+               get_smach().process_event(EVENT_REFRESH_TOOL_OPTIONS);
+
+               studio::App::set_selected_canvas_view(this);
+       
+               App::ui_manager()->insert_action_group(action_group);
+       }
+       
+       // HACK ... Questionable...?
+       if(x)
+               return Gtk::Window::on_focus_in_event(x);
+       
+       return true;
+}
+
+bool
+CanvasView::on_focus_out_event(GdkEventFocus*x)
+{
+       //App::ui_manager()->remove_action_group(action_group);
+       //App::ui_manager()->ensure_update();
+       return Gtk::Window::on_focus_out_event(x);
+}
+
+void
+CanvasView::refresh_tables()
+{
+//     if(layer_tree_store_)layer_tree_store_->refresh();
+//     if(children_tree_store_)children_tree_store_->refresh();
+}
+
+void
+CanvasView::rebuild_tables()
+{
+//     layer_tree_store_->rebuild();
+//     children_tree_store_->rebuild();
+}
+
+void
+CanvasView::build_tables()
+{
+//     layer_tree_store_->rebuild();
+//     children_tree_store_->rebuild();
+}
+
+void
+CanvasView::on_layer_toggle(sinfg::Layer::Handle layer)
+{
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_activate"));
+       assert(action);
+       
+       if(!action)
+               return;
+       
+       action->set_param("canvas",Canvas::Handle(layer->get_canvas()));
+       if(!action->set_param("canvas_interface",canvas_interface()))
+//     if(!action->set_param("canvas_interface",get_instance()->find_canvas_interface(layer->get_canvas())))
+               sinfg::error("LayerActivate didn't like CanvasInterface...?");
+       action->set_param("time",get_time());
+       action->set_param("layer",layer);
+       action->set_param("new_status",!layer->active());
+
+       assert(action->is_ready());
+       
+       canvas_interface()->get_instance()->perform_action(action);
+}
+
+
+void
+CanvasView::popup_param_menu(sinfgapp::ValueDesc value_desc, float location)
+{
+       parammenu.items().clear();
+       get_instance()->make_param_menu(&parammenu,get_canvas(),value_desc,location);
+       
+       parammenu.popup(3,gtk_get_current_event_time());
+}
+
+void
+CanvasView::add_actions_to_menu(Gtk::Menu *menu, const sinfgapp::Action::ParamList &param_list,sinfgapp::Action::Category category)const
+{
+       get_instance()->add_actions_to_menu(menu, param_list, category);
+}
+
+bool
+CanvasView::on_layer_user_click(int button, Gtk::TreeRow row, LayerTree::ColumnID column_id)
+{      
+       switch(button)
+       {
+       case 3:
+               {
+
+                       Gtk::MenuItem* menu = dynamic_cast<Gtk::MenuItem*>(App::ui_manager()->get_widget("/menu-main/menu-layer"));
+                       if(menu && menu->get_submenu())
+                       {
+                               //menu->set_accel_group(App::ui_manager()->get_accel_group());
+                               //menu->accelerate(*this);
+                               menu->get_submenu()->popup(button,gtk_get_current_event_time());
+                       }
+
+                       
+                       #if 0
+                       bool multiple_selected=true;
+                       
+                       if(layer_tree->get_selection()->count_selected_rows()<=1)
+                               multiple_selected=false;
+
+                       // If the clicked row is not selected, then unselect
+                       // everything that isn't selected and select this row
+                       if(multiple_selected && !layer_tree->get_selection()->is_selected(row))
+                       {
+                               layer_tree->get_selection()->unselect_all();
+                               layer_tree->get_selection()->select(row);
+                               multiple_selected=false;
+                       }
+                       
+                       if(column_id==COLUMNID_TIME_TRACK)
+                               return false;
+                       
+                       //sinfgapp::ValueDesc value_desc(row[layer_param_tree_model.value_desc]);
+                       //ValueNode::Handle value_node(row[layer_param_tree_model.value_node]);
+                       //ValueNode::Handle parent_value_node;
+                       //ValueBase value=row[layer_param_tree_model.value];
+                       
+                       //if(row.parent())
+                       //{
+                       //      parent_value_node=(*row.parent())[layer_tree_model.value_node];
+                       //}
+
+                       {
+                               Layer::Handle layer(row[layer_tree_model.layer]);
+                               sinfgapp::Action::ParamList param_list;
+                               param_list.add("time",canvas_interface()->get_time());
+                               param_list.add("canvas",Canvas::Handle(row[layer_tree_model.canvas]));
+                               param_list.add("canvas_interface",canvas_interface());
+                               if(!multiple_selected)
+                                       param_list.add("layer",layer);
+                               else
+                               {
+                                       sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+                                       sinfgapp::SelectionManager::LayerList::iterator iter;
+                               
+                                       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                                               param_list.add("layer",Layer::Handle(*iter));
+                               }
+                               
+                               parammenu.items().clear();
+
+                               Gtk::Menu *newlayers(manage(new Gtk::Menu()));
+                               build_new_layer_menu(*newlayers);
+                               
+                               parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem("New Layer",*newlayers));
+                               if(!multiple_selected && layer->get_name()=="PasteCanvas")
+                               {
+                                       parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Select All Children"),
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *layer_tree,
+                                                               &studio::LayerTree::select_all_children_layers
+                                                       ),
+                                                       layer
+                                               )
+                                       ));
+                               }
+                               
+                               add_actions_to_menu(&parammenu, param_list,sinfgapp::Action::CATEGORY_LAYER);
+                               parammenu.popup(button,gtk_get_current_event_time());
+                               return true;
+                       }
+/*
+                       else if(column_id==LayerTree::COLUMNID_TIME_TRACK && value_node && handle<sinfg::ValueNode_Animated>::cast_dynamic(value_node))
+                       {                                       
+                               // Right-click on time track with animated
+//                             trackmenu.popup(0,0);
+                               return true;
+                       }
+                       else
+                       {
+                               if(!multiple_selected)
+                               {
+                                       popup_param_menu(value_desc);
+                                       return true;
+                               }
+                               else
+                               {
+#warning update me!
+#if 0
+                                       parammenu.items().clear();
+                                       parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Connect",
+                                               hide_return(sigc::mem_fun(*canvas_interface().get(),&sinfgapp::CanvasInterface::connect_selected_layer_params))
+                                       ));
+                                       parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem("Disconnect",
+                                               hide_return(sigc::mem_fun(*canvas_interface().get(),&sinfgapp::CanvasInterface::disconnect_selected_layer_params))
+                                       ));
+                                       parammenu.popup(0,0);
+#endif
+                               }
+                               return true;
+                       }
+               */
+#endif
+}
+               return true;
+               break;
+               
+       default:
+               return false;
+               break;          
+       }
+}
+
+
+
+bool
+CanvasView::on_children_user_click(int button, Gtk::TreeRow row, ChildrenTree::ColumnID column_id)
+{      
+       switch(button)
+       {
+       case 3:
+               {
+                       if(column_id==COLUMNID_TIME_TRACK)
+                               return false;
+                       if(!(bool)row[children_tree_model.is_canvas])
+                       {
+                               sinfgapp::ValueDesc value_desc=row[children_tree_model.value_desc];
+                               assert(value_desc);
+                               popup_param_menu(value_desc);
+                               return true;
+                       }
+               }
+               return true;
+               break;
+               
+       default:
+               return false;
+               break;          
+       }
+}
+
+bool
+CanvasView::on_keyframe_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               switch(event->button.button)
+               {
+                       case 3: 
+                       {
+                               //keyframemenu.popup(event->button.button,gtk_get_current_event_time());
+                               return true;
+                       }
+                       break;
+               }
+               break;
+       case GDK_MOTION_NOTIFY:
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+
+void
+CanvasView::refresh_time_window()
+{
+       //THESE SHOULD AUTOMATICALLY BE TAKEN CARE OF
+       //time_adjustment().set_lower(time_window_adjustment().get_value());
+       //time_adjustment().set_upper(time_window_adjustment().get_value()+time_window_adjustment().get_page_size());
+       
+       time_adjustment().set_page_increment(1.0); // One second
+       time_adjustment().set_page_size(0);
+       
+       if(get_canvas())
+               time_adjustment().set_step_increment(1.0/get_canvas()->rend_desc().get_frame_rate());
+       time_adjustment().changed();
+       
+       //NOTE THIS SHOULD HOOK INTO THE CORRECT SIGNALS...
+       if(children_tree)
+               children_tree->queue_draw();
+}
+
+void
+CanvasView::on_time_changed()
+{
+       Time time(get_time());
+               
+       current_time_widget->set_value(time);
+       try {
+               get_canvas()->keyframe_list().find(time);
+               current_time_widget->modify_text(Gtk::STATE_NORMAL,Gdk::Color("#FF0000"));
+       }catch(...){
+               current_time_widget->modify_text(Gtk::STATE_NORMAL,Gdk::Color("#000000"));              
+       }
+       
+       if(get_time() != time_adjustment().get_value())
+       {
+               
+               //Recenters the window, causing it to jump (possibly undesirably... but whatever)
+               if(time < time_window_adjustment().get_value() ||
+                       time > time_window_adjustment().get_value()+time_window_adjustment().get_page_size())
+               {
+                       time_window_adjustment().set_value(
+                               time-time_window_adjustment().get_page_size()/2
+                       );
+               }
+               time_adjustment().set_value(time);
+               time_adjustment().value_changed();
+               
+               // Shouldn't these trees just hook into
+               // the time changed signal...?
+               //YES THEY SHOULD...
+               if(layer_tree)layer_tree->queue_draw();
+               if(children_tree)children_tree->queue_draw();
+       }
+}
+
+void
+CanvasView::time_zoom_in()
+{
+       time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()*0.75);
+       time_window_adjustment().changed();
+       
+       refresh_time_window();
+}
+
+void
+CanvasView::time_zoom_out()
+{
+       time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()/0.75);
+       time_window_adjustment().changed();
+       
+       refresh_time_window();
+}
+
+void
+CanvasView::time_was_changed()
+{
+       sinfg::Time time((sinfg::Time)(double)time_adjustment().get_value());
+       set_time(time);
+}
+
+void
+CanvasView::on_edited_value(sinfgapp::ValueDesc value_desc,sinfg::ValueBase new_value)
+{
+       canvas_interface()->change_value(value_desc,new_value);
+}
+
+/*
+void
+CanvasView::on_children_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(children_tree->get_model()->get_iter(path));
+
+       assert((bool)row[children_tree_model.is_value_node]);
+
+       sinfgapp::ValueDesc value_desc=row[children_tree_model.value_desc];
+       assert(value_desc);
+
+       on_edited_value(value_desc,value);
+}
+*/
+
+void
+CanvasView::on_id_changed()
+{
+       update_title();
+}
+
+
+void
+CanvasView::on_mode_changed(sinfgapp::CanvasInterface::Mode mode)
+{
+       // If the aninimate flag was set in mode...
+       if(mode&sinfgapp::MODE_ANIMATE)
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("gtk-no"),Gtk::ICON_SIZE_BUTTON));
+               animatebutton->remove();        
+               animatebutton->add(*icon);      
+               tooltips.set_tip(*animatebutton,_("In Animate Editing Mode"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+       else
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("gtk-yes"),Gtk::ICON_SIZE_BUTTON));
+               animatebutton->remove();        
+               animatebutton->add(*icon);      
+               tooltips.set_tip(*animatebutton,_("Not in Animate Editing Mode"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+
+       if((mode&sinfgapp::MODE_ANIMATE_FUTURE) && (mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("sinfg-keyframe_lock_all"),Gtk::ICON_SIZE_BUTTON));
+               keyframebutton->remove();       
+               keyframebutton->add(*icon);     
+               tooltips.set_tip(*keyframebutton,_("All Keyframes Locked"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+       else if((mode&sinfgapp::MODE_ANIMATE_FUTURE) && !(mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("sinfg-keyframe_lock_future"),Gtk::ICON_SIZE_BUTTON));
+               keyframebutton->remove();       
+               keyframebutton->add(*icon);     
+               tooltips.set_tip(*keyframebutton,_("Future Keyframes Locked"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+       else if(!(mode&sinfgapp::MODE_ANIMATE_FUTURE) && (mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("sinfg-keyframe_lock_past"),Gtk::ICON_SIZE_BUTTON));
+               keyframebutton->remove();       
+               keyframebutton->add(*icon);     
+               tooltips.set_tip(*keyframebutton,_("Past Keyframes Locked"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+       else if(!(mode&sinfgapp::MODE_ANIMATE_FUTURE) && !(mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               Gtk::Image *icon;
+               icon=manage(new Gtk::Image(Gtk::StockID("sinfg-keyframe_lock_none"),Gtk::ICON_SIZE_BUTTON));
+               keyframebutton->remove();       
+               keyframebutton->add(*icon);     
+               tooltips.set_tip(*keyframebutton,_("No Keyframes Locked"));
+               icon->set_padding(0,0);
+               icon->show();
+       }
+       
+       work_area->queue_draw();
+}
+
+void
+CanvasView::on_animate_button_pressed()
+{
+       if(get_mode()&sinfgapp::MODE_ANIMATE)
+               set_mode(get_mode()-sinfgapp::MODE_ANIMATE);
+       else
+               set_mode(get_mode()|sinfgapp::MODE_ANIMATE);
+}
+
+void
+CanvasView::on_keyframe_button_pressed()
+{
+       sinfgapp::CanvasInterface::Mode mode(get_mode());
+       
+       if((mode&sinfgapp::MODE_ANIMATE_FUTURE) && (mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               set_mode(get_mode()-sinfgapp::MODE_ANIMATE_FUTURE);
+       }
+       else if(!(mode&sinfgapp::MODE_ANIMATE_FUTURE) && (mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               set_mode(get_mode()-sinfgapp::MODE_ANIMATE_PAST|sinfgapp::MODE_ANIMATE_FUTURE);
+       }
+       else if((mode&sinfgapp::MODE_ANIMATE_FUTURE) && !(mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               set_mode(get_mode()-sinfgapp::MODE_ANIMATE_FUTURE);
+       }
+       else if(!(mode&sinfgapp::MODE_ANIMATE_FUTURE) && !(mode&sinfgapp::MODE_ANIMATE_PAST))
+       {
+               set_mode(get_mode()|sinfgapp::MODE_ANIMATE_FUTURE|sinfgapp::MODE_ANIMATE_PAST);
+       }
+}
+
+bool
+CanvasView::duck_change_param(const Point &value,sinfg::Layer::Handle layer, sinfg::String param_name)
+{
+       return canvas_interface()->change_value(sinfgapp::ValueDesc(layer,param_name),value);
+}
+
+bool
+CanvasView::on_duck_changed(const sinfg::Point &value,const sinfgapp::ValueDesc& value_desc)
+{
+       switch(value_desc.get_value_type())
+       {
+       case ValueBase::TYPE_REAL:
+               return canvas_interface()->change_value(value_desc,value.mag());
+               break;
+       case ValueBase::TYPE_ANGLE:
+               return canvas_interface()->change_value(value_desc,Angle::tan(value[1],value[0]));
+               break;
+       default:
+               return canvas_interface()->change_value(value_desc,value);
+               break;
+       }
+
+       return true;
+}
+
+void
+CanvasView::selected_layer_color_set(Color color)
+{
+       sinfgapp::SelectionManager::LayerList selected_list(get_selection_manager()->get_selected_layers());
+       sinfgapp::SelectionManager::LayerList::iterator iter;
+
+       // Create the action group
+       //sinfgapp::PassiveGrouper group(canvas_interface()->get_instance(),_("Set Colors"));
+
+       Layer::Handle layer;
+       for(iter=selected_list.begin();iter!=selected_list.end();++iter)
+       {
+               if(*iter==layer)
+                       continue;
+               layer=*iter;
+               on_edited_value(sinfgapp::ValueDesc(layer,"color"),color);
+       }
+}
+
+void
+CanvasView::rebuild_ducks_layer_(sinfg::TransformStack& transform_stack, Canvas::Handle canvas, std::set<sinfg::Layer::Handle>& selected_list)
+{
+       int transforms(0);
+       String layer_name;
+               
+#define QUEUE_REBUILD_DUCKS            sigc::mem_fun(*this,&CanvasView::queue_rebuild_ducks)   
+
+       if(!canvas)
+       {
+               sinfg::warning("CanvasView::rebuild_ducks_layer_(): Layer doesn't have canvas set");
+               return;
+       }
+       for(Canvas::iterator iter(canvas->begin());iter!=canvas->end();++iter)
+       {
+               Layer::Handle layer(*iter);
+
+               if(selected_list.count(layer))
+               {
+                       if(!curr_transform_stack_set)
+                       {
+                               curr_transform_stack_set=true;
+                               curr_transform_stack=transform_stack;
+                       }
+
+                       // This layer is currently selected.
+                       duck_changed_connections.push_back(layer->signal_changed().connect(QUEUE_REBUILD_DUCKS));
+                       
+                       // do the bounding box thing
+                       bbox|=transform_stack.perform(layer->get_bounding_rect());
+                       
+                       // Grab the layer's list pf parameters
+                       Layer::ParamList paramlist(layer->get_param_list());
+               
+                       // Grab the layer vocabulary
+                       Layer::Vocab vocab=layer->get_param_vocab();
+                       Layer::Vocab::iterator iter;
+                               
+                       for(iter=vocab.begin();iter!=vocab.end();iter++)
+                       {
+                               if(!iter->get_hidden() && !iter->get_invisible_duck())
+                               {
+                                       sinfgapp::ValueDesc value_desc(layer,iter->get_name());
+                                       work_area->add_to_ducks(value_desc,this,transform_stack,&*iter);
+                                       if(value_desc.is_value_node())
+                                               duck_changed_connections.push_back(value_desc.get_value_node()->signal_changed().connect(QUEUE_REBUILD_DUCKS));
+                               }
+                               if(iter->get_name()=="color")
+                               {
+                                       /*
+                                       if(!App::dialog_color->busy())
+                                       {
+                                               App::dialog_color->reset();
+                                               App::dialog_color->set_color(layer->get_param("color").get(Color()));
+                                               App::dialog_color->signal_edited().connect(
+                                                       sigc::mem_fun(
+                                                               *this,
+                                                               &studio::CanvasView::selected_layer_color_set
+                                                       )
+                                               );              
+                                       }
+                                       */
+                               }
+                       }
+               }
+               
+               layer_name=layer->get_name();
+               
+               if(layer->active())
+               {
+                       Transform::Handle trans(layer->get_transform());
+                       if(trans)
+                       {
+                               transform_stack.push(trans);
+                               transforms++;
+                       }
+
+/*                     // Add transforms onto the stack
+                       if(layer_name=="Translate")
+                       {
+                               transform_stack.push(sinfg::Transform_Translate(layer->get_param("origin").get(Vector())));
+                               transforms++;
+                       }else
+                       if(layer_name=="Zoom")
+                       {
+                               Vector scale;
+                               scale[0]=scale[1]=exp(layer->get_param("amount").get(Real()));
+                               transform_stack.push(sinfg::Transform_Scale(scale,layer->get_param("center").get(Vector())));
+                               transforms++;
+                       }else
+                       if(layer_name=="stretch")
+                       {
+                               Vector scale(layer->get_param("amount").get(Vector()));
+                               transform_stack.push(sinfg::Transform_Scale(scale,layer->get_param("center").get(Vector())));
+                               transforms++;
+                       }else
+                       if(layer_name=="Rotate")
+                       {
+                               transform_stack.push(sinfg::Transform_Rotate(layer->get_param("amount").get(Angle()),layer->get_param("origin").get(Vector())));
+                               transforms++;
+                       }
+*/
+               }
+               
+               // If this is a paste canvas layer, then we need to
+               // descend into it
+               if(layer_name=="PasteCanvas")
+               {
+                       Vector scale;
+                       scale[0]=scale[1]=exp(layer->get_param("zoom").get(Real()));
+                       Vector origin(layer->get_param("origin").get(Vector()));
+                       
+                       Canvas::Handle child_canvas(layer->get_param("canvas").get(Canvas::Handle()));
+                       
+                       if(!scale.is_equal_to(Vector(1,1)))
+                               transform_stack.push(new Transform_Scale(scale,origin));
+                       if(!scale.is_equal_to(Vector(0,0)))
+                               transform_stack.push(new Transform_Translate(origin));
+                       
+                       rebuild_ducks_layer_(transform_stack,child_canvas,selected_list);
+                       
+                       if(!scale.is_equal_to(Vector(0,0)))
+                               transform_stack.pop();
+                       if(!scale.is_equal_to(Vector(1,1)))
+                               transform_stack.pop();
+               }
+       }
+       // Remove all of the transforms we have added
+       while(transforms--) { transform_stack.pop(); }
+
+#undef QUEUE_REBUILD_DUCKS
+}
+
+void
+CanvasView::queue_rebuild_ducks()
+{
+#if 0
+       if(rebuild_ducks_queued)
+               return;
+#else  
+       if(rebuild_ducks_queued)
+               queue_rebuild_ducks_connection.disconnect();
+#endif
+       
+       queue_rebuild_ducks_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&CanvasView::rebuild_ducks),
+                       false
+               ),
+               50
+       );
+       
+       rebuild_ducks_queued=true;
+}
+
+void
+CanvasView::rebuild_ducks()
+{      
+       /*static int i=0;
+       i++;
+       if(i>30)
+               sinfg::info("%d",i/(i-i));
+       */
+       
+       rebuild_ducks_queued=false;
+       //queue_rebuild_ducks_connection.disconnect();
+       
+       if(work_area->is_dragging())
+       {
+               queue_rebuild_ducks();
+               return;
+       }
+       
+       if(!duck_refresh_flag)
+       {
+               duck_refresh_needed=true;
+               return;
+       }
+       
+       bbox=Rect::zero();
+       
+       work_area->clear_ducks();
+       work_area->set_time(get_time());
+       get_canvas()->set_time(get_time());
+       curr_transform_stack.clear();
+       //curr_transform_stack.push(new Transform_Translate(Point(0,0)));
+       curr_transform_stack_set=false;
+
+       for(;!duck_changed_connections.empty();duck_changed_connections.pop_back())duck_changed_connections.back().disconnect();
+       
+       //get_canvas()->set_time(get_time());
+       bool not_empty(false);
+       
+       // First do the layers...       
+       do{
+               sinfgapp::SelectionManager::LayerList selected_list(get_selection_manager()->get_selected_layers());
+               std::set<sinfg::Layer::Handle> layer_set(selected_list.begin(),selected_list.end());
+               
+               if(!layer_set.empty())
+                       not_empty=true;
+               
+               sinfg::TransformStack transform_stack;
+               
+               rebuild_ducks_layer_(transform_stack, get_canvas(), layer_set);
+
+       }while(0);
+
+       // Now do the children
+       do{
+               sinfgapp::SelectionManager::ChildrenList selected_list(get_selection_manager()->get_selected_children());
+               sinfgapp::SelectionManager::ChildrenList::iterator iter;
+               sinfg::TransformStack transform_stack;
+       
+               if(selected_list.empty())
+               {
+                       break;
+               }
+               else
+               {
+                       not_empty=true;
+                       for(iter=selected_list.begin();iter!=selected_list.end();++iter)
+                       {
+                               work_area->add_to_ducks(*iter,this,transform_stack);
+                       }
+               }
+       }while(0);
+       work_area->refresh_selected_ducks();
+       work_area->queue_draw_preview();
+}
+
+void
+CanvasView::on_dirty_preview()
+{
+       if(!is_playing_)
+       {
+               IsWorking is_working(*this);
+
+               work_area->queue_render_preview();
+       }
+}
+
+void
+CanvasView::play()
+{
+       assert(get_canvas());
+       
+       // If we are already busy, don't play!
+       if(working_depth)return;
+       
+       // Set us up as working
+       IsWorking is_working(*this);
+       
+       etl::clock timer;
+       Time
+               time=work_area->get_time(),
+               endtime=get_canvas()->rend_desc().get_time_end();
+
+       // If we are already at the end of time, start over
+       if(time==endtime)
+               time=get_canvas()->rend_desc().get_time_start();
+       
+       is_playing_=true;               
+
+       work_area->clear_ducks();
+       
+       for(timer.reset(); time + timer() < endtime;)
+       {
+               //Clamp the time window so we can see the time value as it races across the horizon
+               bool timewindreset = false;
+               
+               while( time + timer() > Time(time_window_adjustment().get_sub_upper()) )
+               {
+                       time_window_adjustment().set_value(
+                                       min(
+                                               time_window_adjustment().get_value()+time_window_adjustment().get_page_size()/2,
+                                               time_window_adjustment().get_upper()-time_window_adjustment().get_page_size() )
+                               );
+                       timewindreset = true;
+               }
+               
+               while( time + timer() < Time(time_window_adjustment().get_sub_lower()) )
+               {
+                       time_window_adjustment().set_value(
+                               max(
+                                       time_window_adjustment().get_value()-time_window_adjustment().get_page_size()/2,
+                                       time_window_adjustment().get_lower())
+                       );
+                       
+                       timewindreset = true;
+               }
+               
+               //we need to tell people that the value changed
+               if(timewindreset) time_window_adjustment().value_changed();
+               
+               //update actual time to next step
+               time_adjustment().set_value(time+timer());
+               time_adjustment().value_changed();
+               
+               if(!work_area->sync_render_preview())
+                       break;
+               
+               studio::App::iteration(false);
+               
+               if(get_cancel_status())
+                       return;
+       }
+       is_playing_=false;              
+
+       time_adjustment().set_value(endtime);
+       time_adjustment().value_changed();
+}
+
+void
+CanvasView::show_tables()
+{
+/*
+       Smach::event_result x(process_event_key(EVENT_TABLES_SHOW));
+       if(x==Smach::RESULT_OK || x==Smach::RESULT_ACCEPT)
+       {
+               Gtk::IconSize iconsize=Gtk::IconSize::from_name("sinfg-small_icon");
+               treetogglebutton->remove();
+               treetogglebutton->add(*manage(new Gtk::Image(Gtk::StockID("gtk-go-down"),iconsize)));   
+               treetogglebutton->show_all();
+               notebook->show();
+       }
+*/
+}
+
+void
+CanvasView::hide_tables()
+{
+/*
+       Smach::event_result x(process_event_key(EVENT_TABLES_HIDE));
+       if(x==Smach::RESULT_OK || x==Smach::RESULT_ACCEPT)
+       {
+               Gtk::IconSize iconsize=Gtk::IconSize::from_name("sinfg-small_icon");
+               treetogglebutton->remove();
+               treetogglebutton->add(*manage(new Gtk::Image(Gtk::StockID("gtk-go-up"),iconsize)));     
+               treetogglebutton->show_all();
+               notebook->hide();
+       }
+*/
+}
+
+bool
+CanvasView::tables_are_visible()
+{
+//     return notebook->is_visible();
+       return false;
+}
+
+void
+CanvasView::toggle_tables()
+{
+//     if(tables_are_visible())
+//             hide_tables();
+//     else
+//             show_tables();
+}
+
+void
+CanvasView::do_rotoscope_bline()
+{
+       smach_.enter(&state_bline);
+}
+
+void
+CanvasView::do_rotoscope()
+{
+       smach_.enter(&state_draw);
+}
+
+void
+CanvasView::do_rotoscope_poly()
+{
+       smach_.enter(&state_polygon);
+}
+
+void
+CanvasView::do_eyedrop()
+{
+       smach_.enter(&state_eyedrop);
+}
+
+void
+CanvasView::show_timebar()
+{
+       timebar->show();
+       current_time_widget->show();
+       
+       //keyframe_tab_child->show();
+       if(layer_tree)
+               layer_tree->set_show_timetrack(true);
+       if(children_tree)
+               children_tree->set_show_timetrack(true);
+}
+
+void
+CanvasView::hide_timebar()
+{
+       timebar->hide();
+       current_time_widget->hide();
+       //keyframe_tab_child->hide();
+       if(layer_tree)
+               layer_tree->set_show_timetrack(false);
+       if(children_tree)
+               children_tree->set_show_timetrack(false);
+}
+
+
+
+void
+CanvasView::on_waypoint_clicked(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint,int button)
+{
+       waypoint_dialog.set_value_desc(value_desc);
+       waypoint_dialog.set_waypoint(waypoint);
+
+       switch(button)
+       {
+       case -1:
+               waypoint_dialog.show();
+               break;
+       case 2:
+               {
+                       Gtk::Menu* waypoint_menu(manage(new Gtk::Menu()));
+
+                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-jump-to"),
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               *canvas_interface(),
+                                               &sinfgapp::CanvasInterface::set_time
+                                       ),
+                                       waypoint.get_time()
+                               )
+                       ));
+
+                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("Edit Waypoint"),
+                               sigc::mem_fun(
+                                       waypoint_dialog,
+                                       &Gtk::Widget::show
+                               )
+                       ));
+                       
+                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-duplicate"),
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_interface(),
+                                                       &sinfgapp::CanvasInterface::waypoint_duplicate
+                                               ),
+                                               waypoint
+                                       ),
+                                       value_desc
+                               )
+                       ));
+                       waypoint_menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-delete"),
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_interface(),
+                                                       &sinfgapp::CanvasInterface::waypoint_remove
+                                               ),
+                                               waypoint
+                                       ),
+                                       value_desc
+                               )
+                       ));
+                       waypoint_menu->popup(button+1,gtk_get_current_event_time());
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+void
+CanvasView::on_waypoint_changed()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("canvas",get_canvas());
+       param_list.add("canvas_interface",canvas_interface());
+       param_list.add("value_node",waypoint_dialog.get_value_desc().get_value_node());
+       param_list.add("waypoint",waypoint_dialog.get_waypoint());
+//     param_list.add("time",canvas_interface()->get_time());
+
+       get_instance()->process_action("waypoint_set_smart", param_list);
+}
+
+void
+CanvasView::on_waypoint_delete()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("canvas",get_canvas());
+       param_list.add("canvas_interface",canvas_interface());
+       param_list.add("value_node",waypoint_dialog.get_value_desc().get_value_node());
+       param_list.add("waypoint",waypoint_dialog.get_waypoint());
+//     param_list.add("time",canvas_interface()->get_time());
+
+       get_instance()->process_action("waypoint_remove", param_list);
+}
+
+void
+CanvasView::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data_, guint info, guint time)
+{
+       // We will make this true once we have a solid drop
+       bool success(false);
+       //sinfg::info("Droped data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("Droped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       
+       if ((selection_data_.get_length() >= 0) && (selection_data_.get_format() == 8))
+       {
+               if(sinfg::String(selection_data_.get_data_type())=="STRING")do
+               {
+                       sinfg::String selection_data((gchar *)(selection_data_.get_data()));
+
+                       Layer::Handle layer(sinfg::Layer::create("Text"));
+                       if(!layer)
+                               break;
+                       if(!layer->set_param("text",ValueBase(selection_data)))
+                               break;
+
+                       sinfgapp::Action::Handle        action(sinfgapp::Action::create("layer_add"));
+               
+                       assert(action);
+                       if(!action)
+                               break;
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("new",layer);
+
+                       if(!get_instance()->perform_action(action))
+                               break;
+                       
+                       // Ok, we have successfuly imported at least one item.
+                       success=true;
+               } while(0); // END of "STRING"
+               
+               if(sinfg::String(selection_data_.get_data_type())=="text/plain")
+               {
+                       sinfg::String selection_data((gchar *)(selection_data_.get_data()));
+       
+                       // For some reason, GTK hands us a list of URL's seperated
+                       // by not only Carrage-Returns, but also Line-Feeds.
+                       // Line-Feeds will mess us up. Remove all the line-feeds.
+                       while(selection_data.find_first_of('\r')!=sinfg::String::npos)
+                               selection_data.erase(selection_data.begin()+selection_data.find_first_of('\r'));
+       
+                       std::stringstream stream(selection_data);
+       
+                       //sinfgapp::PassiveGrouper group(canvas_interface()->get_instance(),_("Insert Image"));
+                       while(stream)
+                       {
+                               sinfg::String filename,URI;
+                               getline(stream,filename);
+                               
+                               // If we don't have a filename, move on.
+                               if(filename.empty())
+                                       continue;
+                               
+                               // Make sure this URL is of the "file://" type.
+                               URI=String(filename.begin(),filename.begin()+sizeof("file://")-1);
+                               if(URI!="file://")
+                               {
+                                       sinfg::warning("Unknown URI (%s) in \"%s\"",URI.c_str(),filename.c_str());
+                                       continue;
+                               }
+                               
+                               // Strip the "file://" part from the filename
+                               filename=sinfg::String(filename.begin()+sizeof("file://")-1,filename.end());
+
+                               String ext;
+                               try{ext=(String(filename.begin()+filename.find_last_of('.')+1,filename.end()));}catch(...){continue;}
+       
+                               // If this is a SIF file, then we need to do things slightly differently
+                               if(ext=="sketch")
+                               {
+                                       if(work_area->load_sketch(filename))
+                                       {
+                                               success=true;
+                                               work_area->queue_draw();
+                                       }
+                               }
+                               else
+                               {
+                                       if(canvas_interface()->import(filename))
+                                               success=true;
+                               }
+
+                               continue;
+                       }
+               } // END of "text/plain"
+       }
+       else
+               ui_interface_->error("Drop failed: bad selection data");
+
+       // Finish the drag
+       context->drag_finish(success, false, time);
+}
+
+void
+CanvasView::on_keyframe_add_pressed()
+{
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_add"));
+
+       if(!action)
+       {
+               ui_interface_->error("I am unable to find the appropriate action");
+               return;
+       }               
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",canvas_interface());
+       action->set_param("keyframe",Keyframe(get_time()));
+
+       canvas_interface()->get_instance()->perform_action(action);
+}
+
+void
+CanvasView::on_keyframe_duplicate_pressed()
+{
+       const KeyframeTreeStore::Model model;
+       const Gtk::TreeRow row(*keyframe_tree->get_selection()->get_selected());
+       Keyframe keyframe;
+       if(!row)
+       {
+               ui_interface_->error("I am unable to duplicate the keyframe");
+               return;
+       }               
+       keyframe=row[model.keyframe];
+
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_duplicate"));
+
+       if(!action)
+       {
+               ui_interface_->error("I am unable to find the appropriate action");
+               return;
+       }               
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",canvas_interface());
+       action->set_param("keyframe",keyframe);
+       action->set_param("time",get_time());
+
+       canvas_interface()->get_instance()->perform_action(action);
+}
+
+void
+CanvasView::on_keyframe_remove_pressed()
+{
+       const KeyframeTreeStore::Model model;
+       const Gtk::TreeRow row(*keyframe_tree->get_selection()->get_selected());
+       Keyframe keyframe;
+       if(!row)
+       {
+               ui_interface_->error("I am unable to remove the keyframe");
+               return;
+       }               
+       keyframe=row[model.keyframe];
+
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_remove"));
+
+       if(!action)
+       {
+               ui_interface_->error("I am unable to find the appropriate action");
+               return;
+       }               
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",canvas_interface());
+       action->set_param("keyframe",keyframe);
+
+       canvas_interface()->get_instance()->perform_action(action);
+}
+
+
+void
+CanvasView::toggle_duck_mask(Duckmatic::Type type)
+{
+       bool is_currently_on(work_area->get_type_mask()&type);
+
+       switch(type)
+       {
+       case Duck::TYPE_POSITION:
+               if(duck_mask_position)
+                       duck_mask_position->set_active(!is_currently_on);
+               break;
+       
+       case Duck::TYPE_VERTEX:
+               if(duck_mask_vertex)
+                       duck_mask_vertex->set_active(!is_currently_on);
+               break;
+       
+       case Duck::TYPE_TANGENT:
+               if(duck_mask_tangent)
+                       duck_mask_tangent->set_active(!is_currently_on);
+               break;
+       
+       case Duck::TYPE_RADIUS:
+               if(duck_mask_radius)
+                       duck_mask_radius->set_active(!is_currently_on);
+               break;
+       
+       case Duck::TYPE_WIDTH:
+               if(duck_mask_width)
+                       duck_mask_width->set_active(!is_currently_on);
+               break;
+
+       case Duck::TYPE_ANGLE:
+               if(duck_mask_angle)
+                       duck_mask_angle->set_active(!is_currently_on);
+               break;
+
+       default:
+               sinfg::warning("CanvasView::toggle_duck_mask():Unknown duck type!");
+               break;
+       }
+
+       if(is_currently_on)
+               work_area->set_type_mask(work_area->get_type_mask()-type);
+       else
+               work_area->set_type_mask(work_area->get_type_mask()|type);
+       
+       work_area->queue_draw();
+}
+
+
+void
+CanvasView::image_import()
+{
+       String filename(dirname(get_canvas()->get_file_name()));
+       if(App::dialog_open_file(_("Import Image"), filename))
+               canvas_interface()->import(filename);
+}
+
+Smach::event_result
+CanvasView::process_event_key(EventKey x)
+{
+       return smach_.process_event(x);
+}
+
+void
+CanvasView::on_input_device_changed(GdkDevice* device)
+{
+       if(!device)
+       {
+               get_smach().egress();
+       }
+       assert(device);
+       
+       sinfgapp::InputDevice::Handle input_device;
+       input_device=sinfgapp::Main::select_input_device(device->name);
+       App::toolbox->change_state(input_device->get_state());
+       process_event_key(EVENT_INPUT_DEVICE_CHANGED);
+}
+
+void
+CanvasView::on_preview_option()
+{
+       Dialog_PreviewOptions *po = dynamic_cast<Dialog_PreviewOptions *>(get_ext_widget("prevoptions"));
+       
+       Canvas::Handle  canv = get_canvas();
+       
+       if(canv)
+       {
+               RendDesc &r = canv->rend_desc();
+               if(r.get_frame_rate())
+               {
+                       float rate = 1/r.get_frame_rate();
+                       float beg = r.get_time_start() + r.get_frame_start()*rate;
+                       float end = r.get_time_start() + r.get_frame_end()*rate;
+
+                       if(!po)
+                       {
+                               po = new Dialog_PreviewOptions;
+                               po->set_zoom(work_area->get_zoom()/2);
+                               po->set_fps(r.get_frame_rate()/2);
+                               po->set_begintime(beg);
+                               po->set_begin_override(false);
+                               po->set_endtime(end);
+                               po->set_end_override(false);
+                               
+                               set_ext_widget("prevoptions",po);
+                       }
+                       /*po->set_zoom(work_area->get_zoom()/2);
+                       po->set_fps(r.get_frame_rate()/2);
+                       po->set_begintime(beg);
+                       po->set_begin_override(false);
+                       po->set_endtime(end);
+                       po->set_end_override(false);*/
+                       
+                       po->set_global_fps(r.get_frame_rate());
+                       po->signal_finish().connect(sigc::mem_fun(*this,&CanvasView::on_preview_create));
+                       po->present();
+               }
+       }
+}
+
+void
+CanvasView::on_preview_create(const PreviewInfo &info)
+{      
+       //set all the options
+       etl::handle<Preview>    prev = new Preview;
+       
+       prev->set_canvasview(this);
+       prev->set_zoom(info.zoom);
+       prev->set_fps(info.fps);
+       prev->set_overbegin(info.overbegin);
+       prev->set_begintime(info.begintime);
+       prev->set_overend(info.overend);
+       prev->set_endtime(info.endtime);
+       prev->set_quality(work_area->get_quality());
+
+       //render it out...
+       prev->render();
+       
+       Dialog_Preview *pd = preview_dialog.get();
+       assert(pd);
+       
+       pd->set_preview(prev.get());
+       pd->present();
+}
+
+void
+CanvasView::on_audio_option()
+{
+       sinfg::warning("Launching Audio Options");
+       sound_dialog->set_global_fps(get_canvas()->rend_desc().get_frame_rate());
+       sound_dialog->present();
+}
+
+void
+CanvasView::on_audio_file_change(const std::string &f)
+{      
+       //save in meta data - always even when not valid...
+       canvas_interface()->set_meta_data("audiofile",f);
+}
+
+void
+CanvasView::on_audio_offset_change(const Time &t)
+{
+       canvas_interface()->set_meta_data("audiooffset",t.get_string());
+}
+
+void
+CanvasView::on_audio_file_notify()
+{
+       std::string file(get_canvas()->get_meta_data("audiofile"));
+       if(!file.c_str()) return;
+       
+       if(!audio->load(file,dirname(get_canvas()->get_file_name())+string("/")))
+       {
+               if(file != "") sinfg::warning("Could not load the file: %s", file.c_str());
+               get_canvas()->erase_meta_data("audiofile");
+               disp_audio->hide();
+               disp_audio->set_profile(etl::handle<AudioProfile>());
+       }else
+       {
+               //save in canvasview            
+               sinfg::warning("Getting the profile of the music stuff");
+               
+               //profile specific stuff for the preview widget
+               //similar for other attachments
+               Dialog_Preview *pd = preview_dialog.get();
+               pd->get_widget().set_audio(audio);
+               
+               handle<AudioProfile>    prof = audio->get_profile();
+               
+               if(!prof)
+               {
+                       sinfg::warning("Agh, I couldn't build the profile captain!");                   
+               }
+               pd->get_widget().set_audioprofile(prof);
+               
+               disp_audio->set_profile(audio->get_profile());
+               disp_audio->show();
+               
+               sinfg::warning("successfully set the profiles and stuff");
+       }
+       disp_audio->queue_draw();
+}
+
+void
+CanvasView::on_audio_offset_notify()
+{
+       Time t(get_canvas()->get_meta_data("audiooffset"),get_canvas()->rend_desc().get_frame_rate());
+       audio->set_offset(t);
+       sound_dialog->set_offset(t);
+       disp_audio->queue_draw();
+       
+       sinfg::info("CanvasView::on_audio_offset_notify(): offset time set to %s",t.get_string(get_canvas()->rend_desc().get_frame_rate()).c_str());
+}
+
+void
+CanvasView::play_audio(float t)
+{
+       if(audio.get())
+       {
+               sinfg::info("Playing audio at %f s",t);
+               audio->play(t);
+       }               
+}
+
+void
+CanvasView::stop_audio()
+{
+       if(audio.get())
+       {
+               audio->stop();
+       }
+}
+
+bool
+CanvasView::on_audio_scrub()
+{
+       disp_audio->draw();
+       return true;
+}
+
+
+
+Glib::RefPtr<Glib::ObjectBase>
+CanvasView::get_ref_obj(const sinfg::String& x)
+{
+       return ref_obj_book_[x];
+}
+
+Glib::RefPtr<const Glib::ObjectBase>
+CanvasView::get_ref_obj(const sinfg::String& x)const
+{
+       return ref_obj_book_.find(x)->second;
+}
+
+void
+CanvasView::set_ref_obj(const sinfg::String& x, Glib::RefPtr<Glib::ObjectBase> y)
+{
+       ref_obj_book_[x]=y;
+}
+
+Glib::RefPtr<Gtk::TreeModel>
+CanvasView::get_tree_model(const sinfg::String& x)
+{
+       return Glib::RefPtr<Gtk::TreeModel>::cast_dynamic(ref_obj_book_["_tree_model_"+x]);
+}
+
+Glib::RefPtr<const Gtk::TreeModel>
+CanvasView::get_tree_model(const sinfg::String& x)const
+{
+       return Glib::RefPtr<Gtk::TreeModel>::cast_dynamic(ref_obj_book_.find("_tree_model_"+x)->second);
+}
+
+void
+CanvasView::set_tree_model(const sinfg::String& x, Glib::RefPtr<Gtk::TreeModel> y)
+{
+       ref_obj_book_["_tree_model_"+x]=Glib::RefPtr<Glib::ObjectBase>::cast_static(y);
+}
+
+Gtk::Widget*
+CanvasView::get_ext_widget(const sinfg::String& x)
+{
+       return ext_widget_book_[x];
+}
+
+void
+CanvasView::set_ext_widget(const sinfg::String& x, Gtk::Widget* y)
+{
+       ext_widget_book_[x]=y;
+       if(x=="layers_cmp")
+       {
+               layer_tree=dynamic_cast<LayerTree*>(y);
+
+               layer_tree->get_selection()->signal_changed().connect(SLOT_EVENT(EVENT_LAYER_SELECTION_CHANGED));
+               layer_tree->get_selection()->signal_changed().connect(SLOT_EVENT(EVENT_REFRESH_DUCKS));
+               layer_tree->signal_layer_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_layer_user_click));
+               layer_tree->signal_param_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_children_user_click));
+               layer_tree->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_waypoint_clicked));
+       }
+       if(x=="children")
+       {
+               children_tree=dynamic_cast<ChildrenTree*>(y);
+               if(children_tree)children_tree->signal_user_click().connect(sigc::mem_fun(*this, &studio::CanvasView::on_children_user_click));
+               if(children_tree)children_tree->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::CanvasView::on_waypoint_clicked));
+               if(children_tree)children_tree->get_selection()->signal_changed().connect(SLOT_EVENT(EVENT_REFRESH_DUCKS));
+       }
+       if(x=="keyframes")
+               keyframe_tree=dynamic_cast<KeyframeTree*>(y);
+}
+
+static bool _close_instance(etl::handle<Instance> instance)
+{
+       etl::handle<Instance> argh(instance);
+       instance->safe_close();
+       sinfg::info("closed");
+       return false;
+}
+
+bool
+CanvasView::on_delete_event(GdkEventAny* event)
+{
+       if(get_instance()->get_visible_canvases()==1)
+       {
+               // Schedule a close to occur in a few moments
+               Glib::signal_timeout().connect(
+                       sigc::bind(
+                               sigc::ptr_fun(_close_instance),
+                               (etl::handle<Instance>)get_instance()
+                       )
+                       ,250
+               );
+       }
+       if(event)
+               return Gtk::Window::on_delete_event(event);
+       
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.h b/synfig-studio/trunk/src/gtkmm/canvasview.h
new file mode 100644 (file)
index 0000000..887e622
--- /dev/null
@@ -0,0 +1,697 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasview.h
+**     \brief Template Header
+**
+**     $Id: canvasview.h,v 1.2 2005/01/13 18:37:30 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_GTKMM_CANVASVIEW_H
+#define __SINFG_STUDIO_GTKMM_CANVASVIEW_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/window.h>
+#include <gtkmm/image.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/statusbar.h>
+#include <gtkmm/progressbar.h>
+#include <gtkmm/button.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/notebook.h>
+#include <gdkmm/device.h>
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/selectionmanager.h>
+
+#include <sinfg/canvas.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+#include "instance.h"
+#include "canvasproperties.h"
+#include "canvasoptions.h"
+#include "render.h"
+#include "cellrenderer_timetrack.h"
+#include "app.h"
+
+#include "layertreestore.h"
+#include "layertree.h"
+#include "childrentreestore.h"
+#include "childrentree.h"
+#include "keyframetreestore.h"
+#include "keyframetree.h"
+
+#include "dialog_waypoint.h"
+#include "dialog_keyframe.h"
+
+#include "duckmatic.h"
+#include <gtkmm/scale.h>
+
+#include <gtkmm/uimanager.h>
+
+#include "smach.h"
+
+#include <memory>
+#include <set>
+#include <map>
+#include <gtkmm/toggleaction.h>
+#include <gtkmm/radioaction.h>
+#include <sinfg/rect.h>
+
+#include "adjust_window.h"
+
+#include <sinfg/transform.h>
+
+/* === M A C R O S ========================================================= */
+
+#ifndef DEBUGPOINT_CLASS
+#if    _DEBUG
+#define DEBUGPOINT_CLASS(x)            struct debugpointclass_ ## x { debugpointclass_ ## x () { DEBUGPOINT(); } ~debugpointclass_ ## x () { DEBUGPOINT(); } } badfthguae_ ## x ;
+#else
+#define DEBUGPOINT_CLASS(x)    
+#endif
+#endif
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CanvasViewUIInterface;
+class CanvasViewSelectionManager;
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+class UniversalScrubber;
+class WorkArea;
+
+class Duckmatic;
+
+class Preview;
+struct PreviewInfo;
+class AudioContainer;
+       
+class Widget_Sound;
+class Widget_Timeslider;
+class Widget_Time;
+       
+class Dialog_SoundSelect;
+class Dialog_Preview;
+
+class sinfg::TransformStack;
+class Dock_Layers;
+class Dock_Children;
+class Dock_Keyframes;
+       
+class CanvasView : public Gtk::Window, public etl::shared_object
+{
+       friend class UniversalScrubber;
+       friend class Dock_Layers;
+       friend class Dock_Children;
+       friend class Dock_Keyframes;
+               
+       friend class CanvasViewUIInterface;
+       friend class CanvasViewSelectionManager;
+
+       friend class Duckmatic;
+               
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+       
+public:
+
+       typedef etl::handle<CanvasView> Handle;
+       
+       typedef etl::handle<const CanvasView> ConstHandle;
+       
+       typedef etl::loose_handle<CanvasView> LooseHandle;
+
+       typedef LayerTreeStore::Model LayerTreeModel;
+
+       typedef ChildrenTreeStore::Model ChildrenTreeModel;
+
+       //! Create an instance of this class whenever doing a longer task.
+       /*! Make sure that you check the bool value of this class occasionaly
+       **      to make sure the action has not been canceled. */
+       class IsWorking
+       {
+               CanvasView &canvas_view_;
+
+       public:
+               IsWorking(CanvasView &canvas_view_);
+               ~IsWorking();
+               operator bool()const;
+       };
+       friend class IsWorking;
+
+       typedef sinfgapp::CanvasInterface::Mode Mode;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+public:
+       std::auto_ptr<WorkArea> work_area;
+
+       WorkArea* get_work_area() { return work_area.get(); }
+private:
+
+       sinfg::TransformStack curr_transform_stack;
+       bool curr_transform_stack_set;
+
+       sinfg::Rect bbox;
+
+       DEBUGPOINT_CLASS(1);
+
+       //! State Machine
+       Smach smach_;
+
+       DEBUGPOINT_CLASS(2);
+
+       etl::loose_handle<Instance> instance_;
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       DEBUGPOINT_CLASS(3);
+
+       //! Sound and information to play it
+       etl::handle<AudioContainer>             audio;
+       studio::Widget_Sound                    *disp_audio; //should this be put into thing too?
+
+       SigC::Connection                                playcon;
+       SigC::Connection                                stopcon;
+       
+       std::auto_ptr<UniversalScrubber> universal_scrubber;
+       
+       //! Tooltip controler
+       Gtk::Tooltips tooltips;
+
+       DEBUGPOINT_CLASS(4);
+
+       //! TreeModel for the layers
+       LayerTreeModel layer_tree_model;
+
+       //! TreeModel for the the children
+       ChildrenTreeModel children_tree_model;
+
+       //Glib::RefPtr<LayerTreeStore> layer_tree_store_;
+
+       //Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
+
+       //Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
+
+       DEBUGPOINT_CLASS(5);
+       
+       //std::map<sinfg::String,Glib::RefPtr<Gtk::TreeModel> > tree_model_book_;
+       std::map<sinfg::String,Glib::RefPtr<Glib::ObjectBase> > ref_obj_book_;
+       std::map<sinfg::String,Gtk::Widget*> ext_widget_book_;
+
+
+       //! The time adjustment's scope is defined by the time_window adjustment
+       Gtk::Adjustment time_adjustment_;
+       
+       //! The time_window adjustment governs the position of the time window on the whole time line
+       //Gtk::Adjustment time_window_adjustment_;
+       studio::Adjust_Window time_window_adjustment_;
+       
+                       
+       LayerTree *layer_tree;
+       
+       ChildrenTree *children_tree;
+
+       KeyframeTree *keyframe_tree;
+
+       Gtk::Widget *keyframe_tab_child;
+
+       Gtk::ProgressBar *progressbar;
+       Gtk::Statusbar *statusbar;
+       
+       Gtk::TreeRow children_canvas_row;
+       Gtk::TreeRow children_valuenode_row;
+       
+       Gtk::Button *stopbutton;
+       Gtk::Button *refreshbutton;
+       Gtk::Button *treetogglebutton;
+       Gtk::Notebook *notebook;
+       Gtk::Widget *timebar;
+
+       Widget_Time *current_time_widget;
+       void on_current_time_widget_changed();
+       
+       std::auto_ptr<Widget_Timeslider>                timeslider;
+
+       std::list<sigc::connection> duck_changed_connections;
+
+
+
+       Gtk::Button *animatebutton;
+       Gtk::Button *keyframebutton;
+       
+/*     DEBUGPOINT_CLASS(8);
+
+       Gtk::Menu duckmaskmenu;
+       DEBUGPOINT_CLASS(77);
+       Gtk::Menu qualitymenu;
+       DEBUGPOINT_CLASS(6);
+
+       Gtk::Menu filemenu;
+       DEBUGPOINT_CLASS(777);
+       Gtk::Menu editmenu;
+       DEBUGPOINT_CLASS(71);
+       Gtk::Menu canvasmenu;
+       DEBUGPOINT_CLASS(73);
+public:
+       Gtk::Menu layermenu;
+private:
+       DEBUGPOINT_CLASS(74);
+       Gtk::Menu newlayermenu;
+       DEBUGPOINT_CLASS(76);
+       Gtk::Menu viewmenu;
+
+       DEBUGPOINT_CLASS(99);
+       Gtk::Menu keyframemenu;
+
+       Gtk::Menu parammenu;
+       DEBUGPOINT_CLASS(9);
+       Gtk::Menu trackmenu;
+       DEBUGPOINT_CLASS(7);
+
+       Gtk::CheckMenuItem* duck_mask_position;
+       Gtk::CheckMenuItem* duck_mask_vertex;
+       Gtk::CheckMenuItem* duck_mask_tangent;
+       Gtk::CheckMenuItem* duck_mask_radius;
+       Gtk::CheckMenuItem* duck_mask_width;
+       Gtk::CheckMenuItem* duck_mask_angle;
+*/
+       Gtk::Menu parammenu;
+
+
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_position;
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_vertex;
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_tangent;
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_radius;
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_width;
+       Glib::RefPtr<Gtk::ToggleAction> duck_mask_angle;
+
+       Gtk::RadioButtonGroup quality_group;
+       
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+
+
+       etl::handle<sinfgapp::UIInterface> ui_interface_;
+       etl::handle<sinfgapp::SelectionManager> selection_manager_;
+       
+       bool is_playing_;
+
+       sigc::signal<void> signal_deleted_;
+
+       bool rebuild_ducks_queued;
+       sigc::connection queue_rebuild_ducks_connection;
+
+       /*
+ -- ** -- P U B L I C   D A T A -----------------------------------------------
+       */
+
+public:
+       void queue_rebuild_ducks();
+       sigc::signal<void>& signal_deleted() { return signal_deleted_; }
+
+       Gtk::Menu mainmenu;
+
+       bool duck_refresh_flag;
+       bool duck_refresh_needed;
+
+       //! This is for the IsWorking class.
+       int working_depth;
+
+       bool cancel;
+
+
+       /*
+ -- ** -- D I A L O G S -------------------------------------------------------
+       */
+
+public:
+
+       CanvasProperties canvas_properties;
+       CanvasOptions canvas_options;
+       RenderSettings render_settings;
+       Dialog_Waypoint waypoint_dialog;
+       Dialog_Keyframe keyframe_dialog;
+
+       std::auto_ptr<Dialog_Preview>                   preview_dialog;
+       //std::auto_ptr<Dialog_PreviewOptions>  previewoption_dialog;
+       std::auto_ptr<Dialog_SoundSelect>               sound_dialog;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       // Constructor is private to force the use of the "create()" constructor
+       CanvasView(etl::loose_handle<Instance> instance,etl::handle<sinfgapp::CanvasInterface> canvas_interface);
+
+       //! Constructor Helper
+       Gtk::Widget* create_layer_tree();
+
+       //! Constructor Helper
+       Gtk::Widget* create_children_tree();
+
+       //! Constructor Helper
+       Gtk::Widget* create_keyframe_tree();
+
+       //! Constructor Helper
+       Gtk::Widget* create_status_bar();
+
+       //! Constructor Helper - Initializes all of the menus
+       void init_menus();
+
+       bool duck_change_param(const sinfg::Point &value,sinfg::Layer::Handle layer, sinfg::String param_name);
+
+       void refresh_time_window();
+
+       void time_was_changed();
+
+       void refresh_rend_desc();       
+       
+       void toggle_duck_mask(Duckmatic::Type type);
+
+       Gtk::Widget *create_work_area();
+
+       Gtk::Widget *create_time_bar();
+
+
+
+       void popup_param_menu_bezier(float location, sinfgapp::ValueDesc value_desc)
+       { popup_param_menu(value_desc,location); }
+       
+       void popup_param_menu(sinfgapp::ValueDesc value_desc, float location=0);
+
+
+       void workarea_layer_selected(sinfg::Layer::Handle layer);
+
+       void selected_layer_color_set(sinfg::Color color);
+               
+
+
+       void register_layer_type(sinfg::Layer::Book::value_type &lyr,std::map<sinfg::String,Gtk::Menu*>*);
+
+       //! Rebuilds the "new layer" menu
+       void build_new_layer_menu(Gtk::Menu &menu);
+
+       void rebuild_ducks_layer_(sinfg::TransformStack& transform_stack, sinfg::Canvas::Handle canvas, std::set<sinfg::Layer::Handle>& selected_list);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       const sinfg::TransformStack& get_curr_transform_stack()const { return curr_transform_stack; }
+
+       const sinfg::Rect& get_bbox()const { return bbox; }
+
+       Glib::RefPtr<Glib::ObjectBase> get_ref_obj(const sinfg::String& x);
+       Glib::RefPtr<const Glib::ObjectBase> get_ref_obj(const sinfg::String& x)const;
+       void set_ref_obj(const sinfg::String& x, Glib::RefPtr<Glib::ObjectBase> y);
+
+       Glib::RefPtr<Gtk::TreeModel> get_tree_model(const sinfg::String& x);
+       Glib::RefPtr<const Gtk::TreeModel> get_tree_model(const sinfg::String& x)const;
+       void set_tree_model(const sinfg::String& x, Glib::RefPtr<Gtk::TreeModel> y);
+
+       Gtk::Widget* get_ext_widget(const sinfg::String& x);
+       void set_ext_widget(const sinfg::String& x, Gtk::Widget* y);
+       
+       //std::map<sinfg::String,Gtk::Widget*>& tree_view_book() { return tree_view_book_; }
+       //std::map<sinfg::String,Gtk::Widget*>& ext_widget_book() { return tree_view_book_; }
+
+       void popup_main_menu();
+
+       Smach& get_smach() { return smach_; }
+
+       const Smach& get_smach()const { return smach_; }
+       
+       Smach::event_result process_event_key(EventKey x);
+       
+       void popup_layer_menu(sinfg::Layer::Handle layer);
+
+       virtual ~CanvasView();
+
+       void set_mode(Mode x) { canvas_interface()->set_mode(x); }
+       
+       Mode get_mode()const { return canvas_interface()->get_mode(); }
+                               
+       Gtk::Adjustment &time_adjustment() { return time_adjustment_; }
+       
+       const Gtk::Adjustment &time_adjustment()const { return time_adjustment_; }
+
+       studio::Adjust_Window &time_window_adjustment() { return time_window_adjustment_; }
+       
+       const studio::Adjust_Window &time_window_adjustment()const { return time_window_adjustment_; }
+
+       etl::handle<sinfgapp::UIInterface> get_ui_interface() { return ui_interface_;}
+
+       etl::handle<sinfgapp::SelectionManager> get_selection_manager() { return selection_manager_; }
+
+       Glib::RefPtr<Gtk::TreeModel> layer_tree_store() { return get_tree_model("layers"); }
+       
+       Glib::RefPtr<const Gtk::TreeModel> layer_tree_store()const { return get_tree_model("layers"); }
+
+       Glib::RefPtr<Gtk::TreeModel> children_tree_store() { return get_tree_model("children"); }
+       
+       Glib::RefPtr<const Gtk::TreeModel> children_tree_store()const { return get_tree_model("children"); }
+
+       Glib::RefPtr<Gtk::TreeModel> keyframe_tree_store() { return get_tree_model("keyframes"); }
+       
+       Glib::RefPtr<const Gtk::TreeModel> keyframe_tree_store()const { return get_tree_model("keyframes"); }
+
+       void set_time(sinfg::Time t) { canvas_interface_->set_time(t); }
+       
+       sinfg::Time get_time() { return canvas_interface_->get_time(); }
+
+       etl::handle<sinfg::Canvas> get_canvas()const { return canvas_interface_->get_canvas(); }
+
+       etl::handle<Instance> get_instance()const { return instance_; }
+
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+
+       etl::handle<const sinfgapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+
+       void add_actions_to_menu(Gtk::Menu *menu,   const sinfgapp::Action::ParamList &param_list, sinfgapp::Action::Category category=sinfgapp::Action::CATEGORY_ALL)const;
+
+       //! Updates the title of the window
+       void update_title();
+
+       //! Closes this canvas view
+       bool close();
+
+       //!     Stops the currently executing action
+       /*! \see get_cancel_status(), reset_cancel_status(), IsWorking */
+       void stop() { cancel=true; }
+
+       //! Returns the cancel status
+       /*! \see stop(), reset_cancel_status(), IsWorking */
+       bool get_cancel_status()const { return cancel; }
+
+       //! Resets the cancel status
+       /*! \see stop(), get_cancel_status(), IsWorking */
+       void reset_cancel_status() { cancel=false; }
+
+       void new_child_canvas();
+
+       //! Rebuilds layer_tree_store_ from the Canvas. Maintains selected items.
+       void rebuild_tables();
+
+       //! Builds layer_tree_store_ from the Canvas. Does not maintain selected items.
+       void build_tables();
+
+       //! Refreshes the data for the tables
+       void refresh_tables();
+
+       //void rebuild_layer_table();
+       //void build_layer_table();
+       //void refresh_layer_table();
+
+//     void rebuild_canvas_table();
+//     void build_canvas_table();
+//     void refresh_canvas_table();
+
+//     void rebuild_valuenode_table();
+//     void build_valuenode_table();
+//     void refresh_valuenode_table();
+
+       //! \writeme
+       void rebuild_ducks();
+       
+       //bool add_to_ducks(sinfgapp::ValueDesc value_desc, sinfg::ParamDesc *param_desc=NULL);
+               
+       //! Starts "playing" the animation in real-time
+       void play();
+
+       //! Shows the tables (Layer/Children)
+       void show_tables();
+       
+       //! Hides the tables (Layer/Children)
+       void hide_tables();
+       
+       //! Toggles the tables
+       void toggle_tables();
+
+       //! Gets the table status
+       bool tables_are_visible();
+       
+       //! Shows the time bar
+       void show_timebar();
+
+       //! Hides the time bar
+       void hide_timebar();
+
+       void do_rotoscope_bline();
+
+       void do_rotoscope();
+
+       void do_rotoscope_poly();
+
+       void do_eyedrop();
+
+       void time_zoom_in();
+       void time_zoom_out();
+       
+       void add_layer(sinfg::String x);
+       
+       void show_keyframe_dialog();
+       
+       void play_audio(float t);
+       void stop_audio();
+       
+       void image_import();
+
+       void on_waypoint_clicked(sinfgapp::ValueDesc,sinfg::Waypoint, int button);
+       
+       void preview_option() {on_preview_option();}
+       
+       void present();
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+       
+       void on_unselect_layers();
+
+       void on_input_device_changed(GdkDevice*);
+
+       virtual void on_hide();
+
+       virtual bool on_focus_in_event(GdkEventFocus*);
+       virtual bool on_focus_out_event(GdkEventFocus*);
+       
+       //bool on_children_tree_event(GdkEvent *event);
+
+       bool on_keyframe_tree_event(GdkEvent *event);
+
+       //void on_children_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value);
+
+       void on_dirty_preview();
+
+       bool on_children_user_click(int, Gtk::TreeRow, ChildrenTree::ColumnID);
+
+       bool on_layer_user_click(int, Gtk::TreeRow, LayerTree::ColumnID);
+
+//     void on_layer_toggle(const Glib::ustring& path_string, Gtk::TreeModelColumn<bool> column);
+       
+       void on_mode_changed(sinfgapp::CanvasInterface::Mode mode);
+
+//     void on_layer_waypoint_clicked(const Glib::ustring &, sinfg::ValueNode_Animated::WaypointList::iterator);
+       
+       //void on_children_waypoint_clicked(const Glib::ustring &, sinfg::ValueNode_Animated::WaypointList::iterator);
+
+       void on_waypoint_changed();
+       
+       void on_waypoint_delete();
+
+       void on_refresh_pressed();
+
+       void on_id_changed();
+       
+       void on_time_changed();
+
+       /*
+       void on_layer_raise_pressed();
+       void on_layer_lower_pressed();
+       void on_layer_duplicate_pressed();
+       void on_layer_delete_pressed();
+       */
+       
+       void on_keyframe_add_pressed();
+
+       void on_keyframe_duplicate_pressed();
+
+       void on_keyframe_remove_pressed();
+
+       void on_animate_button_pressed();
+
+       void on_keyframe_button_pressed();
+       
+       void on_preview_option();
+       void on_preview_create(const PreviewInfo &);
+       
+       void on_audio_option();
+       void on_audio_file_change(const std::string &f);
+       void on_audio_offset_change(const sinfg::Time &t);
+       
+       void on_audio_file_notify();
+       void on_audio_offset_notify();
+       
+       bool on_duck_changed(const sinfg::Point &value,const sinfgapp::ValueDesc& value_desc);
+
+       void on_layer_toggle(sinfg::Layer::Handle);
+
+       void on_edited_value(sinfgapp::ValueDesc,sinfg::ValueBase);
+
+       //void on_waypoint_clicked(sinfgapp::ValueDesc,sinfg::ValueNode_Animated::WaypointList::iterator, int button);
+
+       void on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);
+       
+       //void on_audio_play();
+       bool on_audio_scrub();
+
+protected:
+       bool on_delete_event(GdkEventAny* event);
+       
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+       
+       static etl::handle<studio::CanvasView> create(etl::loose_handle<Instance> instance,etl::handle<sinfg::Canvas> canvas);
+}; // END of class CanvasView
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.cpp
new file mode 100644 (file)
index 0000000..07d81f1
--- /dev/null
@@ -0,0 +1,96 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_gradient.cpp
+**     \brief Template File
+**
+**     $Id: cellrenderer_gradient.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include "cellrenderer_gradient.h"
+#include "widget_gradient.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CellRenderer_Gradient::CellRenderer_Gradient():
+       Glib::ObjectBase        (typeid(CellRenderer_Gradient)),
+       Gtk::CellRendererText   (),
+       property_gradient_(*this,"gradient",sinfg::Gradient())
+{
+       //CellRendererText::signal_edited().connect(sigc::mem_fun(*this,&studio::CellRenderer_Gradient::string_edited_));
+}
+
+CellRenderer_Gradient::~CellRenderer_Gradient()
+{
+}
+
+
+void
+CellRenderer_Gradient::render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags)
+{
+       if(!window)
+               return;
+       render_gradient_to_window(window,ca,property_gradient_.get_value());
+}
+
+
+Gtk::CellEditable*
+CellRenderer_Gradient::start_editing_vfunc(
+       GdkEvent* event,
+       Gtk::Widget& widget,
+       const Glib::ustring& path,
+       const Gdk::Rectangle& background_area,
+       const Gdk::Rectangle& cell_area,
+       Gtk::CellRendererState flags)
+{
+       return 0;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.h b/synfig-studio/trunk/src/gtkmm/cellrenderer_gradient.h
new file mode 100644 (file)
index 0000000..99ecfce
--- /dev/null
@@ -0,0 +1,87 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_gradient.h
+**     \brief Template Header
+**
+**     $Id: cellrenderer_gradient.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_CELLRENDERER_GRADIENT_H
+#define __SINFG_STUDIO_CELLRENDERER_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/entry.h>
+#include <gtkmm/cellrenderertext.h>
+
+#include <sigc++/signal.h>
+#include <sigc++/slot.h>
+
+#include <sinfg/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Entry; class Button; };
+
+namespace studio {
+
+class CellRenderer_Gradient : public Gtk::CellRendererText
+{
+       sigc::signal<void, const Glib::ustring&> signal_secondary_click_;
+       sigc::signal<void, const Glib::ustring&, sinfg::Gradient> signal_edited_;
+
+       Glib::Property<sinfg::Gradient> property_gradient_;
+
+public:
+       sigc::signal<void, const Glib::ustring&, sinfg::Gradient> &signal_edited()
+       {return signal_edited_; }
+
+       Glib::PropertyProxy<sinfg::Gradient> property_gradient() { return property_gradient_.get_proxy();}
+       
+       CellRenderer_Gradient();
+       ~CellRenderer_Gradient();
+
+protected:
+       
+       virtual void
+       render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags);
+
+       virtual Gtk::CellEditable* start_editing_vfunc(GdkEvent* event,
+                                                 Gtk::Widget& widget,
+                                                 const Glib::ustring& path,
+                                                 const Gdk::Rectangle& background_area,
+                                                 const Gdk::Rectangle& cell_area,
+                                                 Gtk::CellRendererState flags);
+
+}; // END of class CellRenderer_Gradient
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_time.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_time.cpp
new file mode 100644 (file)
index 0000000..e7fe1fa
--- /dev/null
@@ -0,0 +1,132 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_time.cpp
+**     \brief Template File
+**
+**     $Id: cellrenderer_time.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include "cellrenderer_time.h"
+#include "app.h"
+#include "widget_time.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CellRenderer_Time::CellRenderer_Time():
+       Glib::ObjectBase        (typeid(CellRenderer_Time)),
+       Gtk::CellRendererText   (),
+       property_time_(*this,"time",sinfg::Time(0)),
+       property_fps_(*this,"fps", float(0))
+{
+       CellRendererText::signal_edited().connect(sigc::mem_fun(*this,&studio::CellRenderer_Time::string_edited_));
+}
+
+CellRenderer_Time::~CellRenderer_Time()
+{
+       sinfg::info("CellRenderer_Time::~CellRenderer_Time(): deleted");
+}
+
+void
+CellRenderer_Time::string_edited_(const Glib::ustring&path,const Glib::ustring&str)
+{
+       signal_edited_(path,Time((String)str,(Real)Time(property_fps_)));
+}
+
+void
+CellRenderer_Time::render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags)
+{
+       if(!window)
+               return;
+       //int   height = ca.get_height();
+
+       Gtk::StateType state = Gtk::STATE_INSENSITIVE;
+       if(property_editable())
+               state = Gtk::STATE_NORMAL;
+       if((flags & Gtk::CELL_RENDERER_SELECTED) != 0)
+               state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE;
+
+       const Time time(property_time_);
+       const float fps((Real)Time(property_fps_));
+       
+       property_text()=(Glib::ustring)time.get_string(fps,App::get_time_format());
+
+       CellRendererText::render_vfunc(window,widget,background_area,ca,expose_area,flags);
+}
+
+
+Gtk::CellEditable*
+CellRenderer_Time::start_editing_vfunc(
+       GdkEvent* event,
+       Gtk::Widget& widget,
+       const Glib::ustring& path,
+       const Gdk::Rectangle& background_area,
+       const Gdk::Rectangle& cell_area,
+       Gtk::CellRendererState flags)
+{
+       // If we aren't editable, then there is nothing to do
+       if(!property_editable())
+               return 0;
+
+       const Time time(property_time_);
+       const float fps((Real)Time(property_fps_));
+       
+       property_text()=(Glib::ustring)time.get_string(fps,App::get_time_format()|Time::FORMAT_FULL);
+#if 0
+       Widget_Time* widget_time(manage(new Widget_Time));
+       widget_time->set_fps(fps);
+       widget_time->set_value(time);
+       widget_time->signal_editing_done().connect(sigc::mem_fun(*this, &CellRenderer_Time::on_value_editing_done));
+       return widget_time;
+#else
+       return CellRendererText::start_editing_vfunc(event,widget,path,background_area,cell_area,flags);
+#endif
+}
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_time.h b/synfig-studio/trunk/src/gtkmm/cellrenderer_time.h
new file mode 100644 (file)
index 0000000..c024723
--- /dev/null
@@ -0,0 +1,93 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_time.h
+**     \brief Template Header
+**
+**     $Id: cellrenderer_time.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_CELLRENDERER_TIME_H
+#define __SINFG_STUDIO_CELLRENDERER_TIME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/entry.h>
+#include <gtkmm/cellrenderertext.h>
+
+#include <sigc++/signal.h>
+#include <sigc++/slot.h>
+
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Entry; class Button; };
+
+namespace studio {
+
+class CellRenderer_Time : public Gtk::CellRendererText
+{
+       sigc::signal<void, const Glib::ustring&> signal_secondary_click_;
+       sigc::signal<void, const Glib::ustring&, sinfg::Time> signal_edited_;
+
+       Glib::Property<sinfg::Time> property_time_;
+       Glib::Property<sinfg::Time> property_fps_;
+
+       void string_edited_(const Glib::ustring&,const Glib::ustring&);
+
+       void on_value_editing_done();
+
+public:
+       sigc::signal<void, const Glib::ustring&, sinfg::Time> &signal_edited()
+       {return signal_edited_; }
+
+       Glib::PropertyProxy<sinfg::Time> property_time() { return property_time_.get_proxy();}
+       Glib::PropertyProxy<sinfg::Time> property_fps() { return property_fps_.get_proxy();}
+       
+       CellRenderer_Time();
+       ~CellRenderer_Time();
+
+protected:
+       
+       virtual void
+       render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags);
+
+       virtual Gtk::CellEditable* start_editing_vfunc(GdkEvent* event,
+                                                 Gtk::Widget& widget,
+                                                 const Glib::ustring& path,
+                                                 const Gdk::Rectangle& background_area,
+                                                 const Gdk::Rectangle& cell_area,
+                                                 Gtk::CellRendererState flags);
+
+}; // END of class CellRenderer_Time
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp
new file mode 100644 (file)
index 0000000..b3c9a66
--- /dev/null
@@ -0,0 +1,993 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_timetrack.cpp
+**     \brief Template Header
+**
+**     $Id: cellrenderer_timetrack.cpp,v 1.4 2005/01/13 20:23:01 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include "cellrenderer_timetrack.h"
+#include <gtk/gtk.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/combo.h>
+#include <ETL/stringf>
+#include "widget_value.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <gtkmm/optionmenu.h>
+#include "widget_time.h"
+#include "widget_timeslider.h"
+
+#include <sinfgapp/canvasinterface.h>
+#include "instance.h"
+
+#include <sinfg/timepointcollect.h>
+
+#endif
+
+using namespace sinfg;
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+static char stipple_xpm[] = { 2, 0 };
+
+//mode for modifier keys
+enum MODMODE
+{
+       NONE = 0,
+       SELECT_MASK = Gdk::CONTROL_MASK,
+       COPY_MASK = Gdk::SHIFT_MASK,
+       DELETE_MASK = Gdk::MOD1_MASK
+};
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CellRenderer_TimeTrack::CellRenderer_TimeTrack():
+       Glib::ObjectBase        (typeid(CellRenderer_TimeTrack)),
+       Gtk::CellRenderer       (),
+       adjustment_                     (10,10,20,0,0,0),
+       
+       property_valuedesc_     (*this,"value_desc",sinfgapp::ValueDesc()),
+       property_canvas_        (*this,"canvas",sinfg::Canvas::Handle()),
+       property_adjustment_(*this,"adjustment",&adjustment_),
+       property_enable_timing_info_(*this,"enable-timing-info", false)
+{
+               dragging=false;
+       selection=false;
+}
+
+CellRenderer_TimeTrack::~CellRenderer_TimeTrack()
+{
+       sinfg::info("CellRenderer_TimeTrack::~CellRenderer_TimeTrack(): deleted");
+}
+
+void
+CellRenderer_TimeTrack::set_adjustment(Gtk::Adjustment &x)
+{
+       property_adjustment_=&x;
+//     x.signal_value_changed().connect(sigc::mem_fun(*this,&Gtk::Widget::queue_draw));
+}
+
+sinfg::Canvas::Handle
+CellRenderer_TimeTrack::get_canvas()const
+{
+       return const_cast<CellRenderer_TimeTrack*>(this)->property_canvas().get_value();
+}
+
+Gtk::Adjustment *
+CellRenderer_TimeTrack::get_adjustment()
+{
+       return (Gtk::Adjustment*)property_adjustment_;
+}
+
+const Gtk::Adjustment *
+CellRenderer_TimeTrack::get_adjustment()const
+{
+       return (const Gtk::Adjustment*)property_adjustment_;
+}
+
+bool
+CellRenderer_TimeTrack::is_selected(const Waypoint& waypoint)const
+{
+       return selected==waypoint;
+}
+
+//kind of a hack... pointer is ugly
+const sinfg::Node::time_set *get_times_from_vdesc(const sinfgapp::ValueDesc &v)
+{
+       if(v.get_value_type() == sinfg::ValueBase::TYPE_CANVAS)
+       {
+               sinfg::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle());
+       
+               if(canvasparam)
+               {
+                       return &canvasparam->get_times();
+               }
+       }
+       
+       ValueNode *base_value = v.get_value_node().get();
+       
+       ValueNode_DynamicList *parent_value_node = 
+                       v.parent_is_value_node() ?
+                               dynamic_cast<ValueNode_DynamicList *>(v.get_parent_value_node().get()) :
+                               0;
+       
+       //we want a dynamic list entry to override the normal...
+       if(parent_value_node)
+       {
+               return &parent_value_node->list[v.get_index()].get_times();
+       }else if(base_value) //don't render stuff if it's just animated...
+       {
+               return &base_value->get_times();
+       }
+       return 0;
+}
+
+bool get_closest_time(const sinfg::Node::time_set &tset, const Time &t, const Time &range, Time &out)
+{
+       Node::time_set::const_iterator  i,j,end = tset.end();
+       
+       //TODO add in RangeGet so it's not so damn hard to click on points
+       
+       i = tset.upper_bound(t); //where t is the lower bound, t < [first,i)
+       j = i; --j;
+       
+       double dist = Time::end();
+       double closest = 0;
+       
+       if(i != end)
+       {
+               closest = i->get_time();
+               dist = abs(i->get_time() - t);
+       }
+       
+       if(j != end && (abs(j->get_time() - t) < dist) )
+       {
+               closest = j->get_time();
+               dist = abs(j->get_time() - t);
+       }
+       
+       if( dist <= range/2 )
+       {
+               out = closest;
+               return true;
+       }
+       
+       return false;
+}
+
+void
+CellRenderer_TimeTrack::render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& area_,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags)
+{
+       if(!window)
+               return;
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
+       Glib::RefPtr<Gdk::GC> inactive_gc(Gdk::GC::create(window));
+       Gtk::Adjustment *adjustment=get_adjustment();
+       Gtk::StateType state = Gtk::STATE_ACTIVE;
+       Gtk::ShadowType shadow;
+
+       Gdk::Color
+               curr_time_color("#0000ff"),
+               inactive_color("#000000"),
+               keyframe_color("#a07f7f");
+       Gdk::Color activepoint_color[2];
+
+       activepoint_color[0]=Gdk::Color("#ff0000");
+       activepoint_color[1]=Gdk::Color("#00ff00");
+
+       inactive_gc->set_rgb_fg_color(inactive_color);
+       inactive_gc->set_stipple(Gdk::Bitmap::create(stipple_xpm,2,2));
+       inactive_gc->set_fill(Gdk::STIPPLED);
+       
+       sinfg::Canvas::Handle canvas(property_canvas().get_value());
+       
+       sinfgapp::ValueDesc value_desc = property_value_desc().get_value();
+       sinfg::ValueNode *base_value = value_desc.get_value_node().get();
+       sinfg::ValueNode_Animated *value_node=dynamic_cast<sinfg::ValueNode_Animated*>(base_value);
+
+       sinfg::ValueNode_DynamicList *parent_value_node(0);
+       if(property_value_desc().get_value().parent_is_value_node())
+               parent_value_node=dynamic_cast<sinfg::ValueNode_DynamicList*>(property_value_desc().get_value().get_parent_value_node().get());
+
+       // If the canvas is defined, then load up the keyframes
+       if(canvas)
+       {
+               const sinfg::KeyframeList& keyframe_list(canvas->keyframe_list());
+               sinfg::KeyframeList::const_iterator iter;
+               
+               for(iter=keyframe_list.begin();iter!=keyframe_list.end();++iter)
+               {
+                       if(!iter->get_time().is_valid())
+                               continue;
+                       
+                       const int x((int)((float)area_.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->get_time()-adjustment->get_lower())));
+                       if(iter->get_time()>=adjustment->get_lower() && iter->get_time()<adjustment->get_upper())
+                       {
+                               gc->set_rgb_fg_color(keyframe_color);
+                               window->draw_rectangle(gc, true, area_.get_x()+x, area_.get_y(), 1, area_.get_height()+1);
+                       }                       
+               }
+       }
+       
+       //render all the time points that exist
+       {
+               const sinfg::Node::time_set *tset = get_times_from_vdesc(value_desc);
+               
+               if(tset)
+               {
+                       sinfg::Node::time_set::const_iterator   i = tset->begin(), end = tset->end();
+                       
+                       float   lower = adjustment->get_lower(),
+                                       upper = adjustment->get_upper();
+                       
+                       Glib::RefPtr<Gdk::GC>   gc = Gdk::GC::create(widget.get_window());
+                       
+                       Gdk::Rectangle area(area_);
+                       gc->set_clip_rectangle(area);
+                       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       
+                       bool valselected = sel_value.get_value_node() == base_value && !sel_times.empty();
+                       
+                       float cfps = get_canvas()->rend_desc().get_frame_rate();
+                       
+                       vector<Time>    drawredafter;
+                       
+                       Time diff = actual_time - actual_dragtime;//selected_time-drag_time;
+                       for(; i != end; ++i)
+                       {
+                               //find the coordinate in the drawable space...
+                               Time t = i->get_time();
+                               
+                               if(!t.is_valid())
+                                       continue;
+                               
+                               //if it found it... (might want to change comparison, and optimize 
+                               //                                       sel_times.find to not produce an overall nlogn solution)
+                               
+                               bool selected=false;
+                               //not dragging... just draw as per normal
+                               //if move dragging draw offset
+                               //if copy dragging draw both...
+                                                               
+                               if(valselected && sel_times.find(t) != sel_times.end())
+                               {
+                                       if(dragging) //skip if we're dragging because we'll render it later
+                                       {
+                                               if(mode & COPY_MASK) // draw both blue and red moved
+                                               {
+                                                       drawredafter.push_back((t + diff).round(cfps));
+                                                       gc->set_rgb_fg_color(Gdk::Color("#00EEEE"));
+                                               }else if(mode & DELETE_MASK) //it's just red...
+                                               {
+                                                       gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
+                                                       selected=true;
+                                               }else //move - draw the red on top of the others...
+                                               {
+                                                       drawredafter.push_back((t + diff).round(cfps));
+                                                       continue;
+                                               }
+                                       }else
+                                       {
+                                               gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
+                                               selected=true;
+                                       }
+                               }else
+                               {
+                                       gc->set_rgb_fg_color(Gdk::Color("#00EEEE"));
+                               }
+                               
+                               //sinfg::info("Displaying time: %.3f s",(float)t);
+                               const int x = (int)((t-lower)*area.get_width()/(upper-lower));
+                               
+                               //should draw me a grey filled circle...
+                               Gdk::Rectangle area2(
+                                       area.get_x() - area.get_height()/2 + x + 1,
+                                       area.get_y() + 1,
+                                       area.get_height()-2,
+                                       area.get_height()-2
+                               );
+                               render_time_point_to_window(window,area2,*i,selected);
+                               
+                               /*window->draw_arc(gc,true,
+                               area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
+                               area.get_height()/2, area.get_height()*3/4,
+                               0, 64*360);
+                               
+                               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                               window->draw_arc(gc,false,
+                               area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
+                               area.get_height()/2, area.get_height()*3/4,
+                               0, 64*360);
+                               */
+                       }
+                       
+                       {
+                               vector<Time>::iterator i = drawredafter.begin(), end = drawredafter.end();
+                               for(; i != end; ++i)
+                               {
+                                       //find the coordinate in the drawable space...
+                                       Time t = *i;
+                                       
+                                       if(!t.is_valid())
+                                               continue;
+                                                                                                               
+                                       //sinfg::info("Displaying time: %.3f s",(float)t);
+                                       const int x = (int)((t-lower)*area.get_width()/(upper-lower));
+                                       
+                                       //should draw me a grey filled circle...
+                                       
+                                       Gdk::Rectangle area2(
+                                               area.get_x() - area.get_height()/2 + x + 1,
+                                               area.get_y() + 1,
+                                               area.get_height()-2,
+                                               area.get_height()-2
+                                       );
+                                       render_time_point_to_window(window,area2,*i,true);
+/*                                     gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
+                                       window->draw_arc(gc,true,
+                                       area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
+                                       area.get_height()/2, area.get_height()*3/4,
+                                       0, 64*360);
+                                       
+                                       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                                       window->draw_arc(gc,false,
+                                       area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
+                                       area.get_height()/2, area.get_height()*3/4,
+                                       0, 64*360);
+*/
+                               }               
+                       }
+               }
+       }
+
+       /* THIS IS NOW HANDLED ENTIRELY BY THE TIMEPOINT SYSTEM
+       // This this is an animated value node, then render the waypoints
+       if(value_node)
+       {                               
+               //now render the actual waypoints
+               sinfg::ValueNode_Animated::WaypointList::iterator iter;
+               for(
+                       iter=value_node->waypoint_list().begin();
+                       iter!=value_node->waypoint_list().end();
+                       iter++
+               )
+               {
+                       if(!iter->get_time().is_valid())
+                               continue;
+                       int x;
+                       bool selected=false;
+                       if(is_selected(*iter))
+                       {
+                               Time t(iter->get_time());
+
+
+                               if(dragging)
+                                       t=(t+selected_time-drag_time).round(get_canvas()->rend_desc().get_frame_rate());
+
+                               x=(int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(t-adjustment->get_lower()));
+                               shadow=Gtk::SHADOW_IN;
+                               selected=true;
+                       }
+                       else
+                       {
+                               x=(int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->get_time()-adjustment->get_lower()));
+                               shadow=Gtk::SHADOW_OUT;
+                               selected=false;
+                       }
+                       
+                       
+                       widget.get_style()->paint_diamond(
+                               Glib::RefPtr<Gdk::Window>::cast_static(window),
+                               state,
+                               shadow,
+                               area,
+                               widget,
+                               "solid",
+                               area.get_x()+x-area.get_height()/4,
+                               area.get_y()+area.get_height()/4,
+                               area.get_height()/2,
+                               area.get_height()/2
+                       );
+               }
+       }
+       */
+               Gdk::Rectangle area(area_);
+       // If the parent of this value node is a dynamic list, then
+       // render the on and off times
+       if(parent_value_node)
+       {
+               const int index(property_value_desc().get_value().get_index());
+               const sinfg::ValueNode_DynamicList::ListEntry& list_entry(parent_value_node->list[index]);
+               const sinfg::ValueNode_DynamicList::ListEntry::ActivepointList& activepoint_list(list_entry.timing_info);
+               sinfg::ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator iter,next;
+
+               bool is_off(false);
+               if(!activepoint_list.empty())
+                       is_off=!activepoint_list.front().state;
+               
+               int xstart(0);
+               
+               int x=0,prevx=0;
+               for(next=activepoint_list.begin(),iter=next++;iter!=activepoint_list.end();iter=next++)
+               {
+                       x=((int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->time-adjustment->get_lower())));
+                       if(x<0)x=0;
+                       if(x>area.get_width())x=area.get_width();
+                       
+                       bool status_at_time=0;
+                       if(next!=activepoint_list.end())
+                       {
+                               status_at_time=!list_entry.status_at_time((iter->time+next->time)/2.0); 
+                       }
+                       else
+                               status_at_time=!list_entry.status_at_time(Time::end()); 
+                       
+                       if(!is_off && status_at_time)
+                       {
+                               xstart=x;
+                               is_off=true;
+                       }
+                       else
+                       if(is_off && !status_at_time)
+                       {
+                               window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), x-xstart, area.get_height());
+                               is_off=false;
+                       }
+                       
+                       /*
+                       if(!is_off && iter!=activepoint_list.end() && next->state==false && iter->state==false)
+                       {
+                               xstart=x;
+                               is_off=true;
+                       }
+                       else if(is_off && next!=activepoint_list.end() && iter->state==false && next->state==true)
+                       {
+                               window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), x-xstart, area.get_height());
+                               is_off=false;
+                       }
+                       else if(is_off && iter!=activepoint_list.end() && iter->state==true)
+                       {
+                               window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), prevx-xstart, area.get_height());
+                               is_off=false;
+                       }
+                       */
+                       
+                       
+                       
+                       if(iter->time>=adjustment->get_lower() && iter->time<adjustment->get_upper())
+                       {
+                               int w(1);
+                               if(selected==*iter)
+                                       w=3;
+                               gc->set_rgb_fg_color(activepoint_color[iter->state]);
+                               window->draw_rectangle(gc, true, area.get_x()+x-w/2, area.get_y(), w, area.get_height());
+                       }
+                       prevx=x;
+               }
+               if(is_off)
+               {
+                       window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), area.get_width()-xstart, area.get_height());
+               }
+       }               
+               
+       // Render a line that defines the current tick in time
+       {
+               gc->set_rgb_fg_color(curr_time_color);
+
+               const int x((int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(adjustment->get_value()-adjustment->get_lower())));
+
+               if(adjustment->get_value()>=adjustment->get_lower() && adjustment->get_value()<adjustment->get_upper())
+                       window->draw_rectangle(gc, true, area.get_x()+x, area.get_y(), 1, area.get_height());
+       }
+}
+
+sinfg::ValueNode_Animated::WaypointList::iterator
+CellRenderer_TimeTrack::find_waypoint(const sinfg::Time& t,const sinfg::Time& scope)
+{
+       sinfg::ValueNode_Animated *value_node=dynamic_cast<sinfg::ValueNode_Animated*>(property_value_desc().get_value().get_value_node().get());
+
+    Time nearest(Time::end());
+
+       sinfg::ValueNode_Animated::WaypointList::iterator iter,ret;
+
+       if(value_node)
+       {
+               for(
+                       iter=value_node->waypoint_list().begin();
+                       iter!=value_node->waypoint_list().end();
+                       iter++
+                       )
+               {
+                       Time val=abs(iter->get_time()-selected_time);
+                       if(val<nearest)
+                       {
+                               nearest=val;
+                               ret=iter;
+                       }
+               }
+
+               if(nearest!=Time::end() && nearest<scope)
+               {
+                       return ret;
+               }
+       }
+       throw int();
+}
+
+bool
+CellRenderer_TimeTrack::activate_vfunc(
+       GdkEvent* event,
+       Gtk::Widget& widget,
+       const Glib::ustring& treepath,
+       const Gdk::Rectangle& background_area,
+       const Gdk::Rectangle& cell_area,
+       Gtk::CellRendererState flags)
+{
+       path=treepath;
+       sinfg::ValueNode_Animated::WaypointList::iterator iter;
+    Time nearest=1000000000;
+       Gtk::Adjustment *adjustment=get_adjustment();
+
+       sinfg::ValueNode_Animated *value_node=dynamic_cast<sinfg::ValueNode_Animated*>(property_value_desc().get_value().get_value_node().get());
+
+       sinfg::Canvas::Handle canvas(get_canvas());
+
+       sinfg::ValueNode_DynamicList *parent_value_node(0);
+       if(property_value_desc().get_value().parent_is_value_node())
+               parent_value_node=dynamic_cast<sinfg::ValueNode_DynamicList*>(property_value_desc().get_value().get_parent_value_node().get());
+
+       Time deltatime = 0;
+       Time curr_time;
+       switch(event->type)
+       {
+       case GDK_MOTION_NOTIFY:
+               curr_time=((float)event->motion.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
+               
+               mode = NONE;                    
+               {       
+                       Gdk::ModifierType mod;
+                       Gdk::Event(event).get_state(mod);
+                       mode = mod;
+               }
+               break;
+       case GDK_BUTTON_PRESS:
+       case GDK_BUTTON_RELEASE:
+       default:
+               curr_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
+               {       
+                       Gdk::ModifierType mod;
+                       Gdk::Event(event).get_state(mod);
+                       mode = mod;
+               }
+               break;          
+       }
+       actual_time = curr_time;        
+       if(canvas)
+               curr_time=curr_time.round(canvas->rend_desc().get_frame_rate());
+       selected_time=curr_time;
+
+    Time pixel_width((adjustment->get_upper()-adjustment->get_lower())/cell_area.get_width());
+       
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               //selected_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
+
+               //Deal with time point selection, but only if they aren't involved in the insanity...
+               if(/*!value_node && */event->button.button == 1)
+               {
+                       Time stime;
+                       
+                       /*!     UI specification:
+                       
+                               When nothing is selected, clicking on a point in either normal mode order
+                                       addative mode will select the time point closest to the click. 
+                                       Subtractive click will do nothing
+                       
+                               When things are already selected, clicking on a selected point does
+                                       nothing (in both normal and add mode).  Add mode clicking on an unselected
+                                       point adds it to the set.  Normal clicking on an unselected point will
+                                       select only that one time point.  Subtractive clicking on any point
+                                       will remove it from the the set if it is included.
+                       */
+                                               
+                       sinfgapp::ValueDesc valdesc = property_value_desc().get_value();
+                       const Node::time_set *tset = get_times_from_vdesc(valdesc);
+                       
+                       bool clickfound = tset && get_closest_time(*tset,actual_time,pixel_width*cell_area.get_height(),stime);
+                       bool selectmode = mode & SELECT_MASK;
+                                               
+                       //NOTE LATER ON WE SHOULD MAKE IT SO MULTIPLE VALUENODES CAN BE SELECTED AT ONCE
+                       //we want to jump to the value desc if we're not currently on it
+                       //      but only if we want to add the point
+                       if(clickfound && !(sel_value == valdesc))
+                       {
+                               sel_value = valdesc;
+                               sel_times.clear();
+                       }
+                       
+                       //now that we've made sure we're selecting the correct value, deal with the already selected points
+                       set<Time>::iterator foundi = clickfound ? sel_times.find(stime) : sel_times.end();
+                       bool found = foundi != sel_times.end();
+                       
+                       //remove all other points from our list... (only select the one we need)
+                       if(!selectmode && !found)
+                       {
+                               sel_times.clear();
+                       }
+                       
+                       if(found && selectmode) //remove a single already selected point
+                       {
+                               sel_times.erase(foundi);
+                       }else if(clickfound) //otherwise look at adding it
+                       {
+                               //for replace the list was cleared earlier, and for add it wasn't so it works
+                               sel_times.insert(stime);                                
+                       }
+               }
+               
+               selection=false;
+               try
+               {
+                       iter=find_waypoint(selected_time,pixel_width*cell_area.get_height()/2);
+                       selected_waypoint=iter;
+                       selected=*iter;
+                       
+                       selection=true;
+               }
+               catch(int)
+               {
+                       selection=false;
+                       selected=sinfg::UniqueID::nil();
+               }
+               
+               if((!sel_times.empty() || selection) && event->button.button==1)
+               {
+                       dragging=true;
+                       drag_time=selected_time;
+                       actual_dragtime=actual_time;
+               }
+               //selected_time=iter->time;
+
+               /*
+               // Activepoint Selection
+               if(parent_value_node)
+               {
+                       const int index(property_value_desc().get_value().get_index());
+                       const sinfg::ValueNode_DynamicList::ListEntry::ActivepointList& activepoint_list(parent_value_node->list[index].timing_info);
+                       sinfg::ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator iter;
+       
+                       for(iter=activepoint_list.begin();iter!=activepoint_list.end();++iter)
+                       {
+                               Time val=abs(iter->time-selected_time);
+                               if(val<nearest)
+                               {
+                                       nearest=val;
+                                       selected=*iter;
+                                       selection=true;
+                               }
+                       }
+                       // Perhaps I sould signal if we selected this activepoint?
+               }*/
+               
+                       if(event->button.button==3)
+                       {
+                               Time stime;
+                               sinfgapp::ValueDesc valdesc = property_value_desc().get_value();
+                               const Node::time_set *tset = get_times_from_vdesc(valdesc);
+                               
+                               bool clickfound = tset && get_closest_time(*tset,actual_time,pixel_width*cell_area.get_height(),stime);
+                               
+                               etl::handle<sinfg::Node> node;
+                               if(valdesc.get_value(stime).get_type()==ValueBase::TYPE_CANVAS)
+                               {
+                                       node=Canvas::Handle(valdesc.get_value(stime).get(Canvas::Handle()));
+                               }
+                               else //if(valdesc.is_value_node())
+                               {
+                                       node=valdesc.get_value_node();
+                               }
+                               
+                               if(clickfound && node)
+                               {
+                                       show_timepoint_menu(node, stime, actual_time<stime?SIDE_LEFT:SIDE_RIGHT);
+                               }
+                       }
+
+               break;
+       case GDK_MOTION_NOTIFY:
+               //DEBUGPOINT();
+               //if(selection && dragging)
+               //      selected_time=((float)event->motion.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
+               return true;
+               
+               break;
+       case GDK_BUTTON_RELEASE:
+               {
+                       DEBUGPOINT();
+       
+                       //selected_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
+                       dragging=false;
+       
+                       /*if(event->button.button==3 && selection)
+                       {
+                               signal_waypoint_clicked_(path,*selected_waypoint,event->button.button-1);
+                               return true;
+                       }
+                       */
+                       
+                       //Time point stuff...
+                       if(event->button.button == 1)
+                       {
+                               bool delmode = (mode & DELETE_MASK) && !(mode & COPY_MASK);
+                               deltatime = actual_time - actual_dragtime;
+                               if(sel_times.size() != 0 && (delmode || !deltatime.is_equal(Time(0))))
+                               {
+                                       sinfgapp::Action::ParamList param_list;
+                                       param_list.add("canvas",canvas_interface()->get_canvas());
+                                       param_list.add("canvas_interface",canvas_interface());
+                                       
+                                       if(sel_value.get_value_type() == sinfg::ValueBase::TYPE_CANVAS)
+                                       {
+                                               param_list.add("addcanvas",sel_value.get_value().get(Canvas::Handle()));
+                                       }else
+                                       {
+                                               param_list.add("addvaluedesc",sel_value);
+                                       }
+                                       
+                                       set<Time>       newset;
+                                       std::set<sinfg::Time>::iterator i = sel_times.begin(), end = sel_times.end();
+                                       for(; i != end; ++i)
+                                       {
+                                               param_list.add("addtime",*i);
+                                               
+                                               newset.insert((*i + deltatime).round(get_canvas()->rend_desc().get_frame_rate()));
+                                       }
+                                                               
+                                       if(!delmode)
+                                               param_list.add("deltatime",deltatime);
+                               //      param_list.add("time",canvas_interface()->get_time());
+                                       
+                                       if(mode & COPY_MASK) //copy
+                                       {
+                                               etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
+                                                       ->process_action("timepoint_copy", param_list);
+                                       }else if(delmode) //DELETE
+                                       {
+                                               etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
+                                                       ->process_action("timepoint_delete", param_list);                                       
+                                       }else //MOVE
+                                       {
+                                               etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
+                                                       ->process_action("timepoint_move", param_list);                                 
+                                       }
+                                       
+                                       //now replace all the selected with the new selected
+                                       sel_times = newset;                     
+                               }
+                       }
+                       
+                       
+                       
+                       /*if(value_node && selection)
+                       {
+                               if(selected_time==drag_time && event->button.button!=3)
+                                       signal_waypoint_clicked_(path,*selected_waypoint,event->button.button-1);
+                               else
+                               if(event->button.button==1)
+                               {
+                                       sinfg::Waypoint waypoint(*selected_waypoint);
+                                       Time newtime((waypoint.get_time()+(selected_time-drag_time)).round(canvas->rend_desc().get_frame_rate()));
+                                       if(waypoint.get_time()!=newtime)
+                                       {
+                                               waypoint.set_time(newtime);
+                                               signal_waypoint_changed_(waypoint,value_node);
+                                       }
+                               }
+                       }*/
+                       
+                       //if(selection)
+                       //      selected_time=iter->time;
+                       //selected_time=iter->get_time();
+                       return true;
+               }
+       default:
+               //std::cerr<<"unknown event type "<<event->type<<std::endl;
+               return false;
+               break;
+       }       
+
+
+
+       return false;
+}
+
+
+
+Glib::PropertyProxy<sinfgapp::ValueDesc>
+CellRenderer_TimeTrack::property_value_desc()
+{
+       return Glib::PropertyProxy<sinfgapp::ValueDesc>(this,"value_desc");
+}
+
+Glib::PropertyProxy<sinfg::Canvas::Handle>
+CellRenderer_TimeTrack::property_canvas()
+{
+       return Glib::PropertyProxy<sinfg::Canvas::Handle>(this,"canvas");
+}
+
+Glib::PropertyProxy<Gtk::Adjustment* >
+CellRenderer_TimeTrack::property_adjustment()
+{
+       return Glib::PropertyProxy<Gtk::Adjustment* >(this,"adjustment");
+}
+
+void
+CellRenderer_TimeTrack::set_canvas_interface(etl::loose_handle<sinfgapp::CanvasInterface>      h)
+{
+       canvas_interface_ = h;
+}
+
+static void
+set_waypoint_model(std::set<sinfg::Waypoint, std::less<UniqueID> > waypoints, Waypoint::Model model, etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface)
+{
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(canvas_interface->get_instance().get(),_("Change Waypoint Group"));
+
+       std::set<sinfg::Waypoint, std::less<UniqueID> >::const_iterator iter;
+       for(iter=waypoints.begin();iter!=waypoints.end();++iter)
+       {
+               Waypoint waypoint(*iter);
+               waypoint.apply_model(model);
+               
+               sinfgapp::Action::Handle action(sinfgapp::Action::create("waypoint_set"));
+               
+               assert(action);
+               
+               action->set_param("canvas",canvas_interface->get_canvas());
+               action->set_param("canvas_interface",canvas_interface);
+
+               action->set_param("waypoint",waypoint);
+               action->set_param("value_node",waypoint.get_parent_value_node());
+
+               if(!canvas_interface->get_instance()->perform_action(action))
+               {
+                       group.cancel();
+                       return;
+               }
+       }
+}
+
+void
+CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle<sinfg::Node>& node, const sinfg::Time& time, Side side)
+{
+       std::set<sinfg::Waypoint, std::less<UniqueID> > waypoint_set;
+       int n;
+       n=sinfg::waypoint_collect(waypoint_set,time,node);
+
+       Gtk::Menu* menu(manage(new Gtk::Menu()));
+
+       // Create the interpolation method menu
+       if(!waypoint_set.empty())
+       {
+               Gtk::Menu* interp_menu(manage(new Gtk::Menu()));
+               Waypoint::Model model;
+               
+               if(side==SIDE_LEFT)model.set_before(INTERPOLATION_TCB);
+               else model.set_after(INTERPOLATION_TCB);
+               interp_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("TCB"),
+                       sigc::bind(
+                               sigc::ptr_fun(set_waypoint_model),
+                               waypoint_set,
+                               model,
+                               canvas_interface()
+                       )
+               ));
+
+               if(side==SIDE_LEFT)model.set_before(INTERPOLATION_LINEAR);
+               else model.set_after(INTERPOLATION_LINEAR);
+               interp_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Linear"),
+                       sigc::bind(
+                               sigc::ptr_fun(set_waypoint_model),
+                               waypoint_set,
+                               model,
+                               canvas_interface()
+                       )
+               ));
+
+               if(side==SIDE_LEFT)model.set_before(INTERPOLATION_HALT);
+               else model.set_after(INTERPOLATION_HALT);
+               interp_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Ease"),
+                       sigc::bind(
+                               sigc::ptr_fun(set_waypoint_model),
+                               waypoint_set,
+                               model,
+                               canvas_interface()
+                       )
+               ));
+
+               if(side==SIDE_LEFT)model.set_before(INTERPOLATION_CONSTANT);
+               else model.set_after(INTERPOLATION_CONSTANT);
+               interp_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Constant"),
+                       sigc::bind(
+                               sigc::ptr_fun(set_waypoint_model),
+                               waypoint_set,
+                               model,
+                               canvas_interface()
+                       )
+               ));
+               
+               
+               menu->items().push_back(
+                       Gtk::Menu_Helpers::MenuElem(
+                               side==SIDE_LEFT?_("Change \"In\" Interp."):_("Change \"Out\" Interp."),
+                               *interp_menu
+                       )
+               );
+       }
+
+       menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-jump-to"),
+               sigc::bind(
+                       sigc::mem_fun(
+                               *canvas_interface(),
+                               &sinfgapp::CanvasInterface::set_time
+                       ),
+                       time
+               )
+       ));
+
+       if(!waypoint_set.empty())
+       {
+               if(waypoint_set.size()==1)
+               {
+                       delete menu;
+                       menu=0;
+                       signal_waypoint_clicked_(" ",*waypoint_set.begin(),2);
+                       return;
+               }
+               else
+                       sinfg::info("Too many waypoints under me");
+       }
+       else
+               sinfg::info("ZERO waypoints under me");
+
+       if(menu)menu->popup(3,gtk_get_current_event_time());
+}
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.h b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.h
new file mode 100644 (file)
index 0000000..37c0a07
--- /dev/null
@@ -0,0 +1,214 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_timetrack.h
+**     \brief Template Header
+**
+**     $Id: cellrenderer_timetrack.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_CELLRENDERER_TIMETRACK_H
+#define __SINFG_GTKMM_CELLRENDERER_TIMETRACK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/ruler.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/statusbar.h>
+#include <gtkmm/button.h>
+#include <gtkmm/progressbar.h>
+#include <atkmm/stateset.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/scrollbar.h>
+#include <gtkmm/cellrenderer.h>
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/menu.h>
+
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class Widget_ValueBase;
+
+enum Side
+{
+       SIDE_LEFT,
+       SIDE_RIGHT
+};
+
+/*! \class CellRenderer_TimeTrack
+**     \brief A cell renderer that displays the waypoints for Animated ValueNodes.
+*/
+class CellRenderer_TimeTrack :
+       public Gtk::CellRenderer
+{
+
+       /*
+ --    ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+       //! Time adjustment window
+       Gtk::Adjustment adjustment_;
+       
+       //! Signal for when the user clicks on a waypoint
+       sigc::signal<void, const Glib::ustring&,sinfg::Waypoint, int> signal_waypoint_clicked_;
+
+       sigc::signal<void, sinfg::Waypoint, sinfg::ValueNode::Handle> signal_waypoint_changed_;
+
+       //! Iterator for selected waypoint. (Should this be an UniqueID instead?)
+       sinfg::ValueNode_Animated::WaypointList::iterator selected_waypoint;
+       
+       sinfg::UniqueID selected;
+
+       //! selected information for time... (will work for way points etc...)
+       //TODO: make multiple... on both time and value select...
+       std::set<sinfg::Time>   sel_times;
+       sinfgapp::ValueDesc             sel_value;
+       sinfg::Time                             actual_time;
+       sinfg::Time                             actual_dragtime;
+       int                                             mode;
+
+       //! ???
+       sinfg::Time selected_time;
+    
+       //! The path to the current item in the tree model
+       Glib::ustring path;
+       
+       //! ???
+       bool selection;
+
+       bool dragging;
+
+       sinfg::Time drag_time;
+       
+       etl::loose_handle<sinfgapp::CanvasInterface>    canvas_interface_;
+
+       /*
+ --    ** -- P R O P E R T I E S -------------------------------------------------
+       */
+
+private:
+       
+       //! ValueBase Desc
+       Glib::Property<sinfgapp::ValueDesc> property_valuedesc_;
+
+       //! Canvas
+       Glib::Property<sinfg::Canvas::Handle> property_canvas_;
+
+       //! ??? \see adjustment_
+       Glib::Property<Gtk::Adjustment* > property_adjustment_;
+
+       //! \writeme
+       Glib::Property<bool> property_enable_timing_info_;
+
+       /*
+ --    ** -- P R O P E R T Y   I N T E R F A C E S -------------------------------
+       */
+
+public:
+
+       Glib::PropertyProxy<sinfgapp::ValueDesc> property_value_desc();
+
+       Glib::PropertyProxy<sinfg::Canvas::Handle> property_canvas();
+
+       Glib::PropertyProxy<Gtk::Adjustment* > property_adjustment();
+
+       /*
+ --    ** -- S I G N A L   I N T E R F A C E S -----------------------------------
+       */
+
+public:
+
+       sigc::signal<void, const Glib::ustring&,sinfg::Waypoint,int> &signal_waypoint_clicked()
+       {return signal_waypoint_clicked_; }
+
+       sigc::signal<void, sinfg::Waypoint, sinfg::ValueNode::Handle> &signal_waypoint_changed()
+       {return signal_waypoint_changed_; }
+
+       /*
+ --    ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       CellRenderer_TimeTrack();
+    ~CellRenderer_TimeTrack();
+       
+       void show_timepoint_menu(const etl::handle<sinfg::Node>& node, const sinfg::Time& time, Side side=SIDE_RIGHT);
+
+       void set_adjustment(Gtk::Adjustment &x);
+       Gtk::Adjustment *get_adjustment();
+       const Gtk::Adjustment *get_adjustment()const;
+
+       etl::loose_handle<sinfgapp::CanvasInterface>    canvas_interface()const {return canvas_interface_;}
+       void set_canvas_interface(etl::loose_handle<sinfgapp::CanvasInterface> h); //this should only be called by smart people
+       
+       sinfg::Canvas::Handle get_canvas()const;
+       
+       bool is_selected(const sinfg::Waypoint& waypoint)const;
+
+       sinfg::ValueNode_Animated::WaypointList::iterator find_waypoint(const sinfg::Time& t, const sinfg::Time& scope=sinfg::Time::end());
+
+       virtual void
+       render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags);
+
+       virtual bool
+       activate_vfunc( GdkEvent* event,
+                                       Gtk::Widget& widget,
+                                       const Glib::ustring& path,
+                                       const Gdk::Rectangle& background_area,
+                                       const Gdk::Rectangle& cell_area,
+                                       Gtk::CellRendererState flags);
+
+}; // END of class CellRenderer_TimeTrack
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_value.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_value.cpp
new file mode 100644 (file)
index 0000000..9803c56
--- /dev/null
@@ -0,0 +1,588 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_value.cpp
+**     \brief Template File
+**
+**     $Id: cellrenderer_value.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include <ETL/stringf>
+#include <gtkmm/celleditable.h>
+#include <gtkmm/editable.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/eventbox.h>
+#include <gtk/gtkentry.h> /* see XXX below */
+
+#include "app.h"
+#include "widget_value.h"
+#include "widget_vector.h"
+#include "widget_filename.h"
+#include "widget_enum.h"
+#include "widget_color.h"
+#include "widget_canvaschooser.h"
+#include "widget_time.h"
+
+#include "cellrenderer_gradient.h"
+#include "cellrenderer_value.h"
+
+#include "widget_gradient.h"
+#include "dialog_gradient.h"
+#include "dialog_color.h"
+#include <gtkmm/textview.h>
+
+#endif
+
+using namespace sinfg;
+using namespace etl;
+using namespace std;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define DIGITS         15
+
+#define use_colorspace_gamma() App::use_colorspace_gamma
+#define colorspace_gamma()     (2.2f)
+#define gamma_in(x)            pow((float)x,1.0f/colorspace_gamma())
+#define gamma_out(x)   pow((float)x,colorspace_gamma())
+
+/* === G L O B A L S ======================================================= */
+
+class studio::ValueBase_Entry : public Gtk::EventBox, public Gtk::CellEditable
+{
+       Glib::ustring path;
+       Widget_ValueBase *valuewidget;
+       bool edit_done_called;
+       Gtk::Widget *parent;
+public:
+       ValueBase_Entry():
+               Glib::ObjectBase  (typeid(ValueBase_Entry)),
+               Gtk::EventBox     (),
+               Gtk::CellEditable ()
+       {
+               parent=0;
+               edit_done_called=false;
+/*
+                 Gtk::HBox *const hbox = new Gtk::HBox(false, 0);
+                 add(*Gtk::manage(hbox));
+
+                 Gtk::Entry *entry_ = new Gtk::Entry();
+                       entry_->set_text("bleh");
+                 hbox->pack_start(*Gtk::manage(entry_), Gtk::PACK_EXPAND_WIDGET);
+                 entry_->set_has_frame(false);
+                 entry_->gobj()->is_cell_renderer = true; // XXX
+
+*/
+               valuewidget=manage(new class Widget_ValueBase());
+               valuewidget->inside_cellrenderer();
+               add(*valuewidget);
+               valuewidget->show();
+
+               //set_flags(Gtk::CAN_FOCUS);
+               //set_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
+               
+               /*
+               set_events(//(Gdk::ALL_EVENTS_MASK)
+               ~(      Gdk::EXPOSURE_MASK      
+                       | Gdk::ENTER_NOTIFY_MASK        
+                       | Gdk::LEAVE_NOTIFY_MASK        
+                       | Gdk::FOCUS_CHANGE_MASK        
+                       | Gdk::STRUCTURE_MASK   
+                       | Gdk::PROPERTY_CHANGE_MASK     
+                       | Gdk::VISIBILITY_NOTIFY_MASK   
+                       | Gdk::PROXIMITY_IN_MASK        
+                       | Gdk::PROXIMITY_OUT_MASK       
+                       | Gdk::SUBSTRUCTURE_MASK
+               )
+               );
+               */
+               //signal_editing_done().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::hide));
+               //signal_remove_widget().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::hide));
+
+               show_all_children();
+               
+               //signal_show().connect(sigc::mem_fun(*this, &ValueBase_Entry::grab_focus));
+       }
+       ~ValueBase_Entry()
+       {
+               DEBUGPOINT();
+       }
+       
+       void on_editing_done()
+       {
+               hide();
+               if(parent)parent->grab_focus();
+               if(!edit_done_called)
+               {
+                       edit_done_called=true;
+                       Gtk::CellEditable::on_editing_done();
+               }
+               else
+               {
+                       sinfg::error("on_editing_done(): Called twice!");
+               }
+       }
+       void set_parent(Gtk::Widget*x) { parent=x; }
+       void on_remove_widget()
+       {
+               hide();
+               edit_done_called=true;
+               if(parent)parent->grab_focus();
+               Gtk::CellEditable::on_remove_widget();
+       }
+       void start_editing_vfunc(GdkEvent *event)
+       {
+               valuewidget->signal_activate().connect(sigc::mem_fun(*this, &studio::ValueBase_Entry::editing_done));
+               show();
+               //valuewidget->grab_focus();
+               //get_window()->set_focus(*valuewidget);
+       }
+       bool on_event(GdkEvent *event)
+       {
+               if(event->any.type==GDK_BUTTON_PRESS ||
+                       event->any.type==GDK_2BUTTON_PRESS ||
+                       event->any.type==GDK_KEY_PRESS ||
+                       event->any.type==GDK_KEY_RELEASE ||
+                       event->any.type==GDK_SCROLL ||
+                       event->any.type==GDK_3BUTTON_PRESS)
+                       return true;
+               return Gtk::EventBox::on_event(event);
+       }
+       void on_grab_focus()
+       {
+               Gtk::EventBox::on_grab_focus();
+               if(valuewidget)
+                       valuewidget->grab_focus();
+       }
+       void set_path(const Glib::ustring &p)
+       {
+               path=p;
+       }
+       void set_value(const sinfg::ValueBase &data)
+       {
+               if(valuewidget)
+                       valuewidget->set_value(data);
+               //valuewidget->grab_focus();
+       }
+       void set_canvas(const etl::handle<sinfg::Canvas> &data)
+       {
+               assert(data);
+               if(valuewidget)
+                       valuewidget->set_canvas(data);
+       }
+       void set_param_desc(const sinfg::ParamDesc &data)
+       {
+               if(valuewidget)
+                       valuewidget->set_param_desc(data);
+       }
+       
+       const sinfg::ValueBase &get_value()
+       {
+               if(valuewidget)
+                       return valuewidget->get_value();
+               return sinfg::ValueBase();
+       }
+       const Glib::ustring &get_path()
+       {
+               return path;
+       }
+
+};
+
+/* === P R O C E D U R E S ================================================= */
+
+bool get_paragraph(sinfg::String& text)
+{
+       Gtk::Dialog dialog(
+               _("Paragraph"),         // Title
+               true,           // Modal
+               true            // use_separator
+       );
+       Gtk::Label label(_("Enter Paragraph Text Here:"));
+       label.show();
+       dialog.get_vbox()->pack_start(label);
+
+
+       Glib::RefPtr<Gtk::TextBuffer> text_buffer(Gtk::TextBuffer::create());
+       text_buffer->set_text(text);
+
+       Gtk::TextView text_view(text_buffer);
+       text_view.show();
+       dialog.get_vbox()->pack_start(text_view);
+
+/*
+       Gtk::Entry entry;
+       entry.set_text(text);
+       entry.show();
+       entry.set_activates_default(true);
+       dialog.get_vbox()->pack_start(entry);
+*/
+       
+       dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL);
+       dialog.set_default_response(Gtk::RESPONSE_OK);
+       
+       //text_entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK));
+       
+       dialog.show();
+
+       if(dialog.run()!=Gtk::RESPONSE_OK)
+               return false;
+
+       text=text_buffer->get_text();
+
+       return true;
+}
+
+/* === M E T H O D S ======================================================= */
+
+CellRenderer_ValueBase::CellRenderer_ValueBase():
+       Glib::ObjectBase        (typeid(CellRenderer_ValueBase)),
+       Gtk::CellRendererText   (),
+       property_value_ (*this,"value",sinfg::ValueBase()),
+       property_canvas_(*this,"canvas",etl::handle<sinfg::Canvas>()),
+       property_param_desc_(*this,"param_desc",sinfg::ParamDesc())
+{
+       CellRendererText::signal_edited().connect(sigc::mem_fun(*this,&CellRenderer_ValueBase::string_edited_));
+       value_entry=new ValueBase_Entry();
+       value_entry->hide();
+       
+       Pango::AttrList attr_list;
+       {
+               Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
+               pango_size.set_start_index(0);
+               pango_size.set_end_index(64);
+               attr_list.change(pango_size);
+       }
+       property_attributes()=attr_list;
+       
+       property_foreground()=Glib::ustring("#7f7f7f");
+       property_inconsistant()=false;
+}
+
+CellRenderer_ValueBase::~CellRenderer_ValueBase()
+{
+//     sinfg::info("CellRenderer_ValueBase::~CellRenderer_ValueBase(): deleted");
+}
+
+void
+CellRenderer_ValueBase::string_edited_(const Glib::ustring&path,const Glib::ustring&str)
+{
+       ValueBase old_value=property_value_.get_value();
+       ValueBase value;
+       
+       if(old_value.get_type()==ValueBase::TYPE_TIME)
+       {
+               value=ValueBase(Time((String)str,get_canvas()->rend_desc().get_frame_rate()));
+       }
+       else 
+               value=ValueBase((String)str);
+       
+       if(old_value!=value)
+               signal_edited_(path,value);
+}
+
+void
+CellRenderer_ValueBase::render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags)
+{
+       if(!window)
+               return;
+//     const unsigned int cell_xpad = property_xpad();
+//     const unsigned int cell_ypad = property_ypad();
+
+       //int x_offset = 0, y_offset = 0;
+//     int     width = ca.get_width();
+       int     height = ca.get_height();
+//     get_size(widget, ca, x_offset, y_offset, width, height);
+
+//     width  -= cell_xpad * 2;
+//     height -= cell_ypad * 2;
+
+//     if(width <= 0 || height <= 0)
+//             return;
+
+       Gtk::StateType state = Gtk::STATE_INSENSITIVE;
+       if(property_editable())
+               state = Gtk::STATE_NORMAL;
+       if((flags & Gtk::CELL_RENDERER_SELECTED) != 0)
+               state = (widget.has_focus()) ? Gtk::STATE_SELECTED : Gtk::STATE_ACTIVE;
+
+       ValueBase data=property_value_.get_value();
+
+       switch(data.get_type())
+       {
+       case ValueBase::TYPE_REAL:
+               if(((sinfg::ParamDesc)property_param_desc_).get_is_distance())
+               {
+                       Distance x(data.get(Real()),Distance::SYSTEM_UNITS);
+                       x.convert(App::distance_system,get_canvas()->rend_desc());
+                       property_text()=(Glib::ustring)x.get_string(6).c_str();
+               }
+               else
+                       property_text()=(Glib::ustring)strprintf("%.6f",data.get(Real()));
+               break;
+       case ValueBase::TYPE_TIME:
+               property_text()=(Glib::ustring)data.get(Time()).get_string(get_canvas()->rend_desc().get_frame_rate(),App::get_time_format());
+               break;
+       case ValueBase::TYPE_ANGLE:
+               property_text()=(Glib::ustring)strprintf("%.2f DEG",(Real)Angle::deg(data.get(Angle())).get());
+               break;
+       case ValueBase::TYPE_INTEGER:
+               if(((sinfg::ParamDesc)property_param_desc_).get_hint()!="enum")
+               {
+                       property_text()=(Glib::ustring)strprintf("%i",data.get(int()));
+               }
+               else
+               {
+                       property_text()=(Glib::ustring)strprintf("(%i)",data.get(int()));
+                       std::list<sinfg::ParamDesc::EnumData> enum_list=((sinfg::ParamDesc)property_param_desc_).get_enum_list();
+                       std::list<sinfg::ParamDesc::EnumData>::iterator iter;
+                                               
+                       for(iter=enum_list.begin();iter!=enum_list.end();iter++)
+                               if(iter->value==data.get(int()))
+                               {
+                                       property_text()=(Glib::ustring)iter->local_name;
+                                       break;
+                               }
+               }
+                       
+               break;
+       case ValueBase::TYPE_VECTOR:
+               {
+                       Vector vector=data.get(Vector());
+                       Distance x(vector[0],Distance::SYSTEM_UNITS),y(vector[1],Distance::SYSTEM_UNITS);
+                       x.convert(App::distance_system,get_canvas()->rend_desc());
+                       y.convert(App::distance_system,get_canvas()->rend_desc());
+                       property_text()=static_cast<Glib::ustring>(strprintf("%s,%s",x.get_string(6).c_str(),y.get_string(6).c_str()));
+               }
+               break;
+       
+       case ValueBase::TYPE_STRING:
+       
+               if(data.get_type()==ValueBase::TYPE_STRING)
+               {
+                       if(!data.get(sinfg::String()).empty())
+                               property_text()=static_cast<Glib::ustring>(data.get(sinfg::String()));
+                       else
+                               property_text()=Glib::ustring("<empty>");
+               }
+               break;
+       case ValueBase::TYPE_CANVAS:
+               if(data.get(etl::handle<sinfg::Canvas>()))
+               {
+                       if(data.get(etl::handle<sinfg::Canvas>())->is_inline())
+                               property_text()="<Inline Canvas>";
+                       else
+                               property_text()=(Glib::ustring)data.get(etl::handle<sinfg::Canvas>())->get_id();
+               }
+               else
+                       property_text()="<No Image Selected>";
+               break;
+       case ValueBase::TYPE_COLOR:
+               {
+                       render_color_to_window(window,ca,data.get(Color()));
+                       return;
+               }
+               break;
+       case ValueBase::TYPE_BOOL:
+               {
+                       widget.get_style()->paint_check(
+                               Glib::RefPtr<Gdk::Window>::cast_static(window), state, 
+                               data.get(bool())?Gtk::SHADOW_IN:Gtk::SHADOW_OUT,
+                               ca, widget, "cellcheck",
+                               ca.get_x()/* + x_offset + cell_xpad*/,
+                               ca.get_y()/* + y_offset + cell_ypad*/,
+                               height-1,height-1);
+                       return;
+               }
+               break;
+       case ValueBase::TYPE_NIL:
+               //property_text()=(Glib::ustring)" ";
+               return;
+               break;
+       case ValueBase::TYPE_SEGMENT:
+               property_text()=(Glib::ustring)_("Segment");
+               break;
+       case ValueBase::TYPE_GRADIENT:
+               render_gradient_to_window(window,ca,data.get(Gradient()));
+               return;
+               break;
+       case ValueBase::TYPE_LIST:
+               property_text()=(Glib::ustring)_("List");
+               break;
+       case ValueBase::TYPE_BLINEPOINT:
+               property_text()=(Glib::ustring)_("BLine Point");
+               break;
+       default:
+               property_text()=static_cast<Glib::ustring>(_("UNKNOWN"));
+               break;  
+       }
+       CellRendererText::render_vfunc(window,widget,background_area,ca,expose_area,flags);
+}
+
+
+/*
+bool
+CellRenderer_ValueBase::activate_vfunc(        GdkEvent* event,
+       Gtk::Widget& widget,
+       const Glib::ustring& path,
+       const Gdk::Rectangle& background_area,
+       const Gdk::Rectangle& cell_area,
+       Gtk::CellRendererState flags)
+{
+       ValueBase data=(ValueBase)property_value_.get_value();
+
+       switch(data.type)
+       {
+       case ValueBase::TYPE_BOOL:
+               if(property_editable())
+                       signal_edited_(path,ValueBase(!data.get(bool())));
+       return true;
+       case ValueBase::TYPE_STRING:
+               return CellRendererText::activate_vfunc(event,widget,path,background_area,cell_area,flags);
+       }
+       return false;
+}
+*/
+
+void
+CellRenderer_ValueBase::gradient_edited(sinfg::Gradient gradient, Glib::ustring path)
+{
+       ValueBase old_value(property_value_.get_value());
+       ValueBase value(gradient);
+       if(old_value!=value)
+               signal_edited_(path,value);
+}
+
+void
+CellRenderer_ValueBase::color_edited(sinfg::Color color, Glib::ustring path)
+{
+       ValueBase old_value(property_value_.get_value());
+       ValueBase value(color);
+       if(old_value!=value)
+               signal_edited_(path,value);
+}
+
+Gtk::CellEditable*
+CellRenderer_ValueBase::start_editing_vfunc(
+       GdkEvent* event,
+       Gtk::Widget& widget,
+       const Glib::ustring& path,
+       const Gdk::Rectangle& background_area,
+       const Gdk::Rectangle& cell_area,
+       Gtk::CellRendererState flags)
+{
+       // If we aren't editable, then there is nothing to do
+       if(!property_editable())
+               return 0;
+               
+       ValueBase data=property_value_.get_value();
+
+       switch(data.get_type())
+       {
+       case ValueBase::TYPE_BOOL:
+               signal_edited_(path,ValueBase(!data.get(bool())));
+       return NULL;
+       //case ValueBase::TYPE_TIME:
+       //      property_text()=(Glib::ustring)data.get(Time()).get_string(get_canvas()->rend_desc().get_frame_rate(),App::get_time_format()|Time::FORMAT_FULL);
+       //      return CellRendererText::start_editing_vfunc(event,widget,path,background_area,cell_area,flags);
+               
+       case ValueBase::TYPE_GRADIENT:
+               App::dialog_gradient->reset();
+               App::dialog_gradient->set_gradient(data.get(Gradient()));
+               App::dialog_gradient->signal_edited().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::CellRenderer_ValueBase::gradient_edited),
+                               path
+                       )
+               );
+               App::dialog_gradient->present();
+       
+               return NULL;
+
+       case ValueBase::TYPE_COLOR:
+               App::dialog_color->reset();
+               App::dialog_color->set_color(data.get(Color()));
+               App::dialog_color->signal_edited().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::CellRenderer_ValueBase::color_edited),
+                               path
+                       )
+               );
+               App::dialog_color->present();
+       
+               return NULL;
+       case ValueBase::TYPE_STRING:
+               if(get_param_desc().get_hint()=="paragraph")
+               {
+                       sinfg::String string;
+                       string=data.get(string);
+                       if(get_paragraph(string))
+                       {
+                               signal_edited_(path,ValueBase(string));
+                       }                       
+                       return NULL;
+               }
+               if(get_param_desc().get_hint()!="filename")
+                       return CellRendererText::start_editing_vfunc(event,widget,path,background_area,cell_area,flags);
+       default:
+               {
+                       assert(get_canvas());
+                       //delete value_entry;
+                       value_entry=manage(new ValueBase_Entry());
+                       value_entry->set_path(path);
+                       value_entry->set_canvas(get_canvas());
+                       value_entry->set_param_desc(get_param_desc());
+                       value_entry->set_value(data);
+                       value_entry->set_parent(&widget);
+                       value_entry->signal_editing_done().connect(sigc::mem_fun(*this, &CellRenderer_ValueBase::on_value_editing_done));
+                       return value_entry;
+               }
+       }
+       return NULL;
+}
+
+void
+CellRenderer_ValueBase::on_value_editing_done()
+{
+       if(value_entry)
+       {
+               ValueBase old_value(property_value_.get_value());
+               ValueBase value(value_entry->get_value());
+
+               if(old_value!=value)
+                       signal_edited_(value_entry->get_path(),value);
+               
+               //delete value_entry;
+               //value_entry=0;
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_value.h b/synfig-studio/trunk/src/gtkmm/cellrenderer_value.h
new file mode 100644 (file)
index 0000000..90bcb79
--- /dev/null
@@ -0,0 +1,134 @@
+/* === S I N F G =========================================================== */
+/*!    \file cellrenderer_value.cpp
+**     \brief Template File
+**
+**     $Id: cellrenderer_value.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_CELLRENDERER_VALUE_H
+#define __SINFG_GTKMM_CELLRENDERER_VALUE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/ruler.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/statusbar.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+#include <atkmm/stateset.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/cellrenderer.h>
+#include <gtkmm/checkbutton.h>
+
+#include <gtkmm/colorselection.h>
+#include <gtkmm/optionmenu.h>
+
+//#include <sinfg/sinfg.h>
+#include <sinfg/paramdesc.h>
+#include <sinfg/value.h>
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_Color;
+class Widget_CanvasChooser;
+class Widget_Enum;
+class Widget_Filename;
+class Widget_Vector;
+class Widget_Time;
+
+class ValueBase_Entry;
+
+class CellRenderer_ValueBase : public Gtk::CellRendererText
+{
+       sigc::signal<void, const Glib::ustring&> signal_secondary_click_;
+       sigc::signal<void, const Glib::ustring&, sinfg::ValueBase> signal_edited_;
+
+       Glib::Property<sinfg::ValueBase> property_value_;
+       Glib::Property<etl::handle<sinfg::Canvas> > property_canvas_;
+       Glib::Property<sinfg::ParamDesc> property_param_desc_;
+
+       void string_edited_(const Glib::ustring&,const Glib::ustring&);
+
+       void gradient_edited(sinfg::Gradient gradient, Glib::ustring path);
+       void color_edited(sinfg::Color color, Glib::ustring path);
+       
+public:
+       sigc::signal<void, const Glib::ustring&> &signal_secondary_click()
+       {return signal_secondary_click_; }
+
+       sigc::signal<void, const Glib::ustring&, sinfg::ValueBase> &signal_edited()
+       {return signal_edited_; }
+
+       Glib::PropertyProxy<sinfg::ValueBase> property_value() { return property_value_.get_proxy();}
+       Glib::PropertyProxy<etl::handle<sinfg::Canvas> > property_canvas() { return property_canvas_.get_proxy();}
+       Glib::PropertyProxy<sinfg::ParamDesc> property_param_desc() { return property_param_desc_.get_proxy(); }
+       Glib::PropertyProxy<bool> property_inconsistant() { return property_foreground_set(); }
+
+       etl::handle<sinfg::Canvas> get_canvas()const { return property_canvas_; }
+       sinfg::ParamDesc get_param_desc()const { return property_param_desc_; }
+       
+       CellRenderer_ValueBase();
+       ~CellRenderer_ValueBase();
+
+       ValueBase_Entry *value_entry;
+
+       void on_value_editing_done();
+
+       virtual void
+       render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               Gtk::Widget& widget,
+               const Gdk::Rectangle& background_area,
+               const Gdk::Rectangle& ca,
+               const Gdk::Rectangle& expose_area,
+               Gtk::CellRendererState flags);
+       
+       virtual Gtk::CellEditable* start_editing_vfunc(GdkEvent* event,
+                                                 Gtk::Widget& widget,
+                                                 const Glib::ustring& path,
+                                                 const Gdk::Rectangle& background_area,
+                                                 const Gdk::Rectangle& cell_area,
+                                                 Gtk::CellRendererState flags);
+
+}; // END of class CellRenderer_ValueBase
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/childrentree.cpp b/synfig-studio/trunk/src/gtkmm/childrentree.cpp
new file mode 100644 (file)
index 0000000..82a675c
--- /dev/null
@@ -0,0 +1,381 @@
+/* === S I N F G =========================================================== */
+/*!    \file childrentree.cpp
+**     \brief Template File
+**
+**     $Id: childrentree.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "childrentree.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+       button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+ChildrenTree::ChildrenTree()
+{
+       const ChildrenTreeStore::Model model;
+
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ID")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_start(*icon_cellrenderer,false);
+               column->add_attribute(icon_cellrenderer->property_pixbuf(), model.icon);
+
+               // Pack the label into the column
+               column->pack_start(model.label,true);
+
+               // Finish setting up the column         
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               column->set_min_width(150);
+               column->set_sort_column_id(model.label);
+               tree_view.append_column(*column);
+               
+       }
+       {       // --- T Y P E --------------------------------------------------------
+               int cols_count = tree_view.append_column(_("Type"),model.type);
+               Gtk::TreeViewColumn* column = tree_view.get_column(cols_count-1);
+               if(column)
+               {
+                       column->set_reorderable();
+                       column->set_resizable();
+                       column->set_clickable();
+                       column->set_sort_column_id(model.type);
+               }
+       }
+       {       // --- V A L U E  -----------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
+               
+               // Set up the value cell-renderer
+               cellrenderer_value=ChildrenTreeStore::add_cell_renderer_value(column);
+               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_edited_value));
+               cellrenderer_value->property_value()=sinfg::ValueBase();
+
+               // Finish setting up the column
+               tree_view.append_column(*column);
+               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+               column->set_min_width(150);
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable(false);
+       }
+       {       // --- T I M E   T R A C K --------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+               column_time_track=column;
+               
+               // Set up the value-node cell-renderer
+               cellrenderer_time_track=ChildrenTreeStore::add_cell_renderer_value_node(column);
+               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+               cellrenderer_time_track->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_waypoint_clicked) );
+               column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
+               column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
+
+               //column->pack_start(*cellrenderer_time_track);
+                               
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               tree_view.append_column(*column);
+       }
+
+       // This makes things easier to read.
+       tree_view.set_rules_hint();
+       
+       // Make us more sensitive to several events
+       tree_view.add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+       
+       tree_view.signal_event().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_tree_event));
+
+       // Create a scrolled window for that tree
+       Gtk::ScrolledWindow *scroll_children_tree = manage(new class Gtk::ScrolledWindow());
+       scroll_children_tree->set_flags(Gtk::CAN_FOCUS);
+       scroll_children_tree->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scroll_children_tree->add(tree_view);
+       scroll_children_tree->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll_children_tree->show();
+
+       attach(*scroll_children_tree, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       hbox=manage(new Gtk::HBox());
+       
+       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       
+       
+       tree_view.set_enable_search(true);
+       tree_view.set_search_column(model.label);
+       
+       
+/*
+       Gtk::Image *icon;
+       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("sinfg-small_icon"));
+       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
+       SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
+       SMALL_BUTTON(button_duplicate,"sinfg-duplicate","Duplicate");
+       SMALL_BUTTON(button_delete,"gtk-delete","Delete");
+       
+       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+       button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_raise_pressed));
+       button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_lower_pressed));
+       button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_duplicate_pressed));
+       button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_delete_pressed));
+
+       button_raise->set_sensitive(false);
+       button_lower->set_sensitive(false);
+       button_duplicate->set_sensitive(false);
+       button_delete->set_sensitive(false);
+*/
+
+
+
+       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::ChildrenTree::on_selection_changed));
+
+
+       tree_view.set_reorderable(true);
+
+       hbox->show();
+       tree_view.show();
+
+       tooltips_.enable();
+
+       //get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+}
+
+
+ChildrenTree::~ChildrenTree()
+{
+}
+
+void
+ChildrenTree::set_show_timetrack(bool x)
+{
+       column_time_track->set_visible(x);
+}
+
+void
+ChildrenTree::set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store)
+{
+       children_tree_store_=children_tree_store;
+       tree_view.set_model(children_tree_store_);
+       children_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::ChildrenTree::on_dirty_preview));
+}
+
+void
+ChildrenTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+       cellrenderer_time_track->set_adjustment(adjustment);
+}
+
+void
+ChildrenTree::on_dirty_preview()
+{
+}
+
+void
+ChildrenTree::on_selection_changed()
+{      
+       if(0)
+               {
+               button_raise->set_sensitive(false);
+               button_lower->set_sensitive(false);
+               button_duplicate->set_sensitive(false);
+               button_delete->set_sensitive(false);
+               return;
+       }
+}
+
+
+void
+ChildrenTree::on_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+
+       row[model.value]=value;
+//     signal_edited_value()(row[model.value_desc],value);
+}
+
+void
+ChildrenTree::on_waypoint_clicked(const Glib::ustring &path_string, sinfg::Waypoint waypoint,int button)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+       
+       signal_waypoint_clicked()(static_cast<sinfgapp::ValueDesc>(row[model.value_desc]),waypoint,button);
+}
+
+bool
+ChildrenTree::on_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!tree_view.get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+                       
+                       if(column->get_first_cell_renderer()==cellrenderer_time_track)
+                       {
+                               return signal_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                       }
+                       else if(column->get_first_cell_renderer()==cellrenderer_value)
+                               return signal_user_click()(event->button.button,row,COLUMNID_VALUE);
+                       else
+                               return signal_user_click()(event->button.button,row,COLUMNID_ID);
+                       
+               }
+               break;
+               
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!tree_view.get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       
+                       if(!tree_view.get_model()->get_iter(path))
+                               break;
+                       
+                       Gtk::TreeRow row = *(tree_view.get_model()->get_iter(path));
+                       
+                       if(cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               // Movement on TimeLine
+                               return true;
+                       }
+                       else
+                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+void
+ChildrenTree::on_raise_pressed()
+{
+}
+
+void
+ChildrenTree::on_lower_pressed()
+{
+}
+
+void
+ChildrenTree::on_duplicate_pressed()
+{
+}
+
+void
+ChildrenTree::on_delete_pressed()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/childrentree.h b/synfig-studio/trunk/src/gtkmm/childrentree.h
new file mode 100644 (file)
index 0000000..40d68d1
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file childrentree.h
+**     \brief Template Header
+**
+**     $Id: childrentree.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_CHILDRENTREE_H
+#define __SINFG_STUDIO_CHILDRENTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "childrentreestore.h"
+#include <sinfg/valuenode_animated.h>
+
+#include "widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class ChildrenTree : public Gtk::Table
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef studio::ColumnID ColumnID;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       ChildrenTreeStore::Model model;
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Gtk::Tooltips tooltips_;
+
+       Gtk::TreePath last_tooltip_path;
+
+       Gtk::TreeView tree_view;
+
+       Gtk::HBox *hbox;
+
+       Glib::RefPtr<ChildrenTreeStore> children_tree_store_;
+
+       CellRenderer_TimeTrack *cellrenderer_time_track;
+
+       Gtk::TreeView::Column* column_time_track;
+
+       CellRenderer_ValueBase *cellrenderer_value;
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::ValueBase> signal_edited_value_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::Waypoint, int> signal_waypoint_clicked_;
+
+       Gtk::Button *button_raise;
+       Gtk::Button *button_lower;
+       Gtk::Button *button_duplicate;
+       Gtk::Button *button_delete;
+
+       Widget_ValueBase blend_method_widget;
+       
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value);
+
+       void on_waypoint_clicked(const Glib::ustring &, sinfg::Waypoint,int button);
+
+       bool on_tree_event(GdkEvent *event);
+
+       void on_selection_changed();
+
+       void on_dirty_preview();
+
+       void on_raise_pressed();
+
+       void on_lower_pressed();
+
+       void on_duplicate_pressed();
+
+       void on_delete_pressed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       Gtk::HBox& get_hbox() { return *hbox; }
+
+       Gtk::TreeView& get_tree_view() { return tree_view; }
+       
+       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return tree_view.get_selection(); }
+       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return tree_view.signal_event(); }
+       
+       ChildrenTree();
+       ~ChildrenTree();
+
+       void set_model(Glib::RefPtr<ChildrenTreeStore> children_tree_store_);
+
+       void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+       void set_show_timetrack(bool x=true);
+
+       //! Signal called with a value has been edited.
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::Waypoint, int>& signal_waypoint_clicked() { return signal_waypoint_clicked_; }
+
+       etl::handle<sinfgapp::SelectionManager> get_selection_manager() { return children_tree_store_->canvas_interface()->get_selection_manager(); }
+
+}; // END of ChildrenTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/childrentreestore.cpp b/synfig-studio/trunk/src/gtkmm/childrentreestore.cpp
new file mode 100644 (file)
index 0000000..73378fe
--- /dev/null
@@ -0,0 +1,380 @@
+/* === S I N F G =========================================================== */
+/*!    \file childrentreestore.cpp
+**     \brief Template File
+**
+**     $Id: childrentreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "childrentreestore.h"
+#include "iconcontroler.h"
+#include <gtkmm/button.h>
+#include <sinfg/paramdesc.h>
+#include <ETL/clock>
+
+class Profiler : private etl::clock
+{
+       const std::string name;
+public:
+       Profiler(const std::string& name):name(name) { reset(); }
+       ~Profiler() { float time(operator()()); sinfg::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static ChildrenTreeStore::Model& ModelHack()
+{
+       static ChildrenTreeStore::Model* model(0);
+       if(!model)model=new ChildrenTreeStore::Model;
+       return *model;
+}
+
+ChildrenTreeStore::ChildrenTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       CanvasTreeStore                 (canvas_interface_)
+{
+       canvas_row=*append();
+       canvas_row[model.label]=_("Canvases");
+       canvas_row[model.is_canvas] = false;
+       canvas_row[model.is_value_node] = false;
+
+       value_node_row=*append();
+       value_node_row[model.label]=_("ValueBase Nodes");
+       value_node_row[model.is_canvas] = false;
+       value_node_row[model.is_value_node] = false;
+
+       // Connect all the signals
+       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_changed));
+       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_added));
+       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_deleted));
+       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_value_node_replaced));
+       canvas_interface()->signal_canvas_added().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_added));
+       canvas_interface()->signal_canvas_removed().connect(sigc::mem_fun(*this,&studio::ChildrenTreeStore::on_canvas_removed));
+       
+       rebuild();
+}
+
+ChildrenTreeStore::~ChildrenTreeStore()
+{
+}
+
+Glib::RefPtr<ChildrenTreeStore>
+ChildrenTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<ChildrenTreeStore>(new ChildrenTreeStore(canvas_interface_));
+}
+
+void
+ChildrenTreeStore::rebuild()
+{
+       Profiler profiler("ChildrenTreeStore::rebuild()");
+       rebuild_value_nodes();
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh()
+{
+       Profiler profiler("ChildrenTreeStore::refresh()");
+       refresh_value_nodes();
+       refresh_canvases();
+}
+
+void
+ChildrenTreeStore::rebuild_value_nodes()
+{
+       Gtk::TreeModel::Children children(value_node_row.children());
+
+       while(!children.empty())erase(children.begin());
+       
+       clear_changed_queue();
+       
+       std::for_each(
+               canvas_interface()->get_canvas()->value_node_list().rbegin(), canvas_interface()->get_canvas()->value_node_list().rend(),
+               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_value_node_added)
+       );      
+}
+
+void
+ChildrenTreeStore::refresh_value_nodes()
+{
+       Gtk::TreeModel::Children children(value_node_row.children());
+
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       //DEBUGPOINT();
+                       refresh_row(row);
+               }
+}
+
+void
+ChildrenTreeStore::rebuild_canvases()
+{
+       Gtk::TreeModel::Children children(canvas_row.children());
+       
+       while(!children.empty())erase(children.begin());
+               
+       std::for_each(
+               canvas_interface()->get_canvas()->children().rbegin(), canvas_interface()->get_canvas()->children().rend(),
+               sigc::mem_fun(*this, &studio::ChildrenTreeStore::on_canvas_added)
+       );      
+}
+
+void
+ChildrenTreeStore::refresh_canvases()
+{
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::refresh_row(Gtk::TreeModel::Row &row, bool do_children)
+{
+       CanvasTreeStore::refresh_row(row,false);
+       
+       if((bool)row[model.is_value_node])
+       {
+               changed_set_.erase(row[model.value_node]);
+       }
+
+}
+
+void
+ChildrenTreeStore::on_canvas_added(Canvas::Handle canvas)
+{
+       Gtk::TreeRow row = *(prepend(canvas_row.children()));
+
+       row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("sinfg-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR); 
+       row[model.id] = canvas->get_id();
+       row[model.name] = canvas->get_name();
+       
+       if(!canvas->get_id().empty())
+               row[model.label] = canvas->get_id();
+       else
+       if(!canvas->get_name().empty())
+               row[model.label] = canvas->get_name();          
+       else
+               row[model.label] = _("[Unnamed]");              
+       
+       row[model.canvas] = canvas;
+       row[model.type] = _("Canvas");
+       //row[model.is_canvas] = true;
+       //row[model.is_value_node] = false;
+}
+
+void
+ChildrenTreeStore::on_canvas_removed(Canvas::Handle canvas)
+{
+       rebuild_canvases();
+}
+
+void
+ChildrenTreeStore::on_value_node_added(ValueNode::Handle value_node)
+{
+//     if(value_node->get_id().find("Unnamed")!=String::npos)
+//             return;
+
+       Gtk::TreeRow row = *prepend(value_node_row.children());
+       
+       set_row(row,sinfgapp::ValueDesc(canvas_interface()->get_canvas(),value_node->get_id()),false);
+}
+
+void
+ChildrenTreeStore::on_value_node_deleted(etl::handle<ValueNode> value_node)
+{
+       Gtk::TreeIter iter;
+       //int i(0);             
+
+       if(find_first_value_node(value_node,iter))
+       {
+               erase(iter);
+       }
+       //rebuild_value_nodes();
+}
+
+bool
+ChildrenTreeStore::execute_changed_value_nodes()
+{
+       Profiler profiler("ChildrenTreeStore::execute_changed_value_nodes()");
+       DEBUGPOINT();
+       if(!replaced_set_.empty())
+               rebuild_value_nodes();
+
+       etl::clock timer;
+       timer.reset();
+       
+       while(!changed_set_.empty())
+       {
+               ValueNode::Handle value_node(*changed_set_.begin());
+               changed_set_.erase(value_node);
+
+               Gtk::TreeIter iter;
+               
+               try
+               {
+                       Gtk::TreeIter iter;
+                       int i(0);               
+
+                       if(!value_node->is_exported() && find_first_value_node(value_node,iter))
+                       {
+                               rebuild_value_nodes();
+                               continue;
+                       }
+
+                       if(value_node->is_exported() && find_first_value_node(value_node,iter)) do
+                       {
+                               Gtk::TreeRow row(*iter);
+                               i++;
+                               refresh_row(row);
+                       }while(find_next_value_node(value_node,iter));
+                       
+                       if(!i)
+                       {
+                               refresh_value_nodes();
+                               return false;
+                       }
+                       
+               }
+               catch(...)
+               {
+                       rebuild_value_nodes();
+                       return false;
+               }
+
+               // If we are taking too long...
+               if(timer()>4)
+               {
+                       refresh_value_nodes();
+                       return false;
+               }
+       }
+               
+       return false;
+}
+
+void
+ChildrenTreeStore::on_value_node_changed(etl::handle<ValueNode> value_node)
+{
+
+       if(value_node->get_name()=="constant" || !value_node->is_exported())
+               return;
+       changed_connection.disconnect();
+//     if(!execute_changed_queued())
+//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+       changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+       
+       changed_set_.insert(value_node);
+       /*
+       try
+       {
+               Gtk::TreeIter iter;
+               int i(0);               
+               while(find_next_value_node(value_node,iter))
+               {
+                       Gtk::TreeRow row(*iter);
+                       i++;
+                       refresh_row(row);
+               }
+               if(!i)
+               {
+                       refresh_value_nodes();
+               }
+       }
+       catch(...)
+       {
+               rebuild_value_nodes();
+       }
+       */
+}
+
+void
+ChildrenTreeStore::on_value_node_replaced(sinfg::ValueNode::Handle replaced_value_node,sinfg::ValueNode::Handle new_value_node)
+{
+       changed_connection.disconnect();
+       //if(!execute_changed_queued())
+//             changed_connection=Glib::signal_idle().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes));
+               changed_connection=Glib::signal_timeout().connect(sigc::mem_fun(*this,&ChildrenTreeStore::execute_changed_value_nodes),150);
+       
+       replaced_set_.insert(replaced_value_node);
+}
+
+void
+ChildrenTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.value.index())
+               {
+                       Glib::Value<sinfg::ValueBase> x;
+                       g_value_init(x.gobj(),model.value.type());
+                       g_value_copy(value.gobj(),x.gobj());
+
+                       sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+                       if(value_desc)
+                       {
+                               canvas_interface()->change_value(value_desc,x.get());
+                               row_changed(get_path(*iter),*iter);
+                       }
+
+                       return;
+               }
+               else
+                       CanvasTreeStore::set_value_impl(iter,column, value);
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/childrentreestore.h b/synfig-studio/trunk/src/gtkmm/childrentreestore.h
new file mode 100644 (file)
index 0000000..bae0667
--- /dev/null
@@ -0,0 +1,140 @@
+/* === S I N F G =========================================================== */
+/*!    \file childrentreestore.h
+**     \brief Template Header
+**
+**     $Id: childrentreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_CHILDRENTREESTORE_H
+#define __SINFG_STUDIO_CHILDRENTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include "canvastreestore.h"
+#include <sinfg/value.h>
+#include <sinfg/valuenode.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class ChildrenTreeStore : public CanvasTreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       //! TreeModel for the layers
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+       
+       Gtk::TreeModel::Row value_node_row;
+       Gtk::TreeModel::Row canvas_row;
+       
+       std::set<sinfg::ValueNode::Handle> changed_set_;
+
+       std::set<sinfg::ValueNode::Handle> replaced_set_;
+       
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       sigc::connection changed_connection;
+       bool execute_changed_queued()const { return !changed_set_.empty() || !replaced_set_.empty(); }
+       bool execute_changed_value_nodes();
+       void clear_changed_queue() { changed_set_.clear(); replaced_set_.clear(); }
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_value_node_added(sinfg::ValueNode::Handle value_node);
+       void on_value_node_deleted(sinfg::ValueNode::Handle value_node);
+       void on_value_node_changed(sinfg::ValueNode::Handle value_node);
+       void on_value_node_replaced(sinfg::ValueNode::Handle replaced_value_node,sinfg::ValueNode::Handle new_value_node);
+       void on_canvas_added(sinfg::Canvas::Handle canvas);
+       void on_canvas_removed(sinfg::Canvas::Handle canvas);
+
+       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       ChildrenTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+       ~ChildrenTreeStore();
+
+       void rebuild();
+
+       void refresh();
+
+       void rebuild_value_nodes();
+
+       void refresh_value_nodes();
+
+       void rebuild_canvases();
+
+       void refresh_canvases();
+
+       void refresh_row(Gtk::TreeModel::Row &row, bool do_children=false);
+
+       Gtk::TreeModel::Row get_canvas_row()const { return canvas_row; }
+       
+       Gtk::TreeModel::Row get_value_node_row()const { return value_node_row; }
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+       
+       static Glib::RefPtr<ChildrenTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+}; // END of class ChildrenTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/compview.cpp b/synfig-studio/trunk/src/gtkmm/compview.cpp
new file mode 100644 (file)
index 0000000..58dd236
--- /dev/null
@@ -0,0 +1,608 @@
+/*! ========================================================================
+** Sinfg
+** Template File
+** $Id: compview.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "compview.h"
+#include "app.h"
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include <iostream>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "canvasview.h"
+#include <sinfgapp/action.h>
+
+#endif
+
+/* === M A C R O S ========================================================= */
+
+#define ADD_TOOLBOX_BUTTON(button,stockid,tooltip)     \
+       Gtk::Button *button = manage(new class Gtk::Button());  \
+       button->add(*manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::IconSize(4))));   \
+       tooltips.set_tip(*button,tooltip);      \
+       button->show_all()
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+#define COLUMNID_JUMP          (787584)
+#define ColumnID       int
+       
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CompView::CompView():
+       Gtk::Window(Gtk::WINDOW_TOPLEVEL),
+       dialog_settings(this,"compview")
+{
+       init_menu();
+       set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+
+       Gtk::Table *table = manage(new class Gtk::Table(2, 1, false));
+
+
+       table->attach(*create_instance_selector(), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+
+       notebook=manage(new class Gtk::Notebook());
+
+       table->attach(*notebook, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       notebook->append_page(*create_canvas_tree(),"Canvases");
+       notebook->append_page(*create_action_tree(),"History");
+
+       
+
+/*
+
+       studio::Instance::ImageColumnModel image_column_model;
+       image_list=manage(new class Gtk::TreeView());
+       image_list->append_column("Name",image_column_model.name);
+       image_list->signal_row_activated().connect(sigc::mem_fun(*this,&CompView::on_image_activate));
+       image_list->set_rules_hint();
+
+       Gtk::Table *image_page = manage(new class Gtk::Table(2, 1, false));
+       Gtk::ScrolledWindow *image_list_scroll = manage(new class Gtk::ScrolledWindow());
+       image_list_scroll->set_flags(Gtk::CAN_FOCUS);
+       image_list_scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       image_list_scroll->add(*image_list);
+       image_page->attach(*image_list_scroll, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       Gtk::HBox *image_buttons=manage(new class Gtk::HBox());
+       image_page->attach(*image_buttons, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       ADD_TOOLBOX_BUTTON(button_image_new,"gtk-new","Create a new image");
+       ADD_TOOLBOX_BUTTON(button_image_delete,"gtk-delete","Delete image");
+       ADD_TOOLBOX_BUTTON(button_image_rename,"gtk-rename","Rename image");
+       ADD_TOOLBOX_BUTTON(button_image_copy,"gtk-copy","Duplicate image");
+       button_image_new->signal_clicked().connect(sigc::mem_fun(*this,&CompView::new_image));
+       button_image_delete->signal_clicked().connect(sigc::mem_fun(*this,&CompView::delete_image));
+       button_image_rename->signal_clicked().connect(sigc::mem_fun(*this,&CompView::rename_image));
+       button_image_copy->signal_clicked().connect(sigc::mem_fun(*this,&CompView::copy_image));
+       image_buttons->pack_start(*button_image_new);
+       image_buttons->pack_start(*button_image_delete);
+       image_buttons->pack_start(*button_image_rename);
+       image_buttons->pack_start(*button_image_copy);
+
+       studio::Instance::ValueNodeColumnModel valuenode_column_model;
+       valuenode_list=manage(new class Gtk::TreeView());
+       valuenode_list->append_column("Name",valuenode_column_model.name);
+       valuenode_list->signal_row_activated().connect(sigc::mem_fun(*this,&CompView::on_valuenode_activate));
+       valuenode_list->set_rules_hint();
+
+       Gtk::Table *valuenode_page = manage(new class Gtk::Table(2, 1, false));
+       Gtk::ScrolledWindow *valuenode_list_scroll = manage(new class Gtk::ScrolledWindow());
+       valuenode_list_scroll->set_flags(Gtk::CAN_FOCUS);
+       valuenode_list_scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       valuenode_list_scroll->add(*valuenode_list);
+       valuenode_page->attach(*valuenode_list_scroll, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       Gtk::HBox *valuenode_buttons=manage(new class Gtk::HBox());
+       valuenode_page->attach(*valuenode_buttons, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       ADD_TOOLBOX_BUTTON(button_valuenode_new,"gtk-new","Create a new value_node");
+       ADD_TOOLBOX_BUTTON(button_valuenode_delete,"gtk-delete","Delete value_node");
+       ADD_TOOLBOX_BUTTON(button_valuenode_rename,"gtk-rename","Rename value_node");
+       ADD_TOOLBOX_BUTTON(button_valuenode_copy,"gtk-copy","Duplicate value_node");
+       button_valuenode_new->signal_clicked().connect(sigc::mem_fun(*this,&CompView::new_value_node));
+       button_valuenode_delete->signal_clicked().connect(sigc::mem_fun(*this,&CompView::delete_value_node));
+       button_valuenode_rename->signal_clicked().connect(sigc::mem_fun(*this,&CompView::rename_value_node));
+       button_valuenode_copy->signal_clicked().connect(sigc::mem_fun(*this,&CompView::copy_value_node));
+       valuenode_buttons->pack_start(*button_valuenode_new);
+       valuenode_buttons->pack_start(*button_valuenode_delete);
+       valuenode_buttons->pack_start(*button_valuenode_rename);
+       valuenode_buttons->pack_start(*button_valuenode_copy);
+
+
+       notebook->append_page(*image_page,"Images");
+       notebook->append_page(*valuenode_page,"ValueNodes");
+
+       image_page->show_all();
+       valuenode_page->show_all();
+*/
+//     notebook->set_current_page(0);
+       signal_delete_event().connect(sigc::hide(sigc::mem_fun(*this, &CompView::close)));
+       App::signal_instance_created().connect(sigc::mem_fun(*this,&studio::CompView::new_instance));
+       App::signal_instance_deleted().connect(sigc::mem_fun(*this,&studio::CompView::delete_instance));
+       App::signal_instance_selected().connect(sigc::mem_fun(*this,&studio::CompView::set_selected_instance_signal));
+       
+       table->show_all();
+       add(*table);
+
+
+       set_title("Canvas Browser");
+       set_modal(false);
+       set_resizable(true);
+       property_window_position().set_value(Gtk::WIN_POS_NONE);
+       set_default_size(200,300);
+}
+
+CompView::~CompView()
+{
+}
+
+etl::loose_handle<studio::CanvasView>
+CompView::get_selected_canvas_view()
+{
+       return get_selected_instance()->find_canvas_view(get_selected_canvas());
+}
+
+Gtk::Widget*
+CompView::create_canvas_tree()
+{
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+       canvas_tree=manage(new class Gtk::TreeView());
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("ID") );
+//             Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+
+               //column->pack_start(*icon_cellrenderer,false);
+               column->pack_start(canvas_tree_model.icon, false); //false = don't expand.
+               column->pack_start(canvas_tree_model.label);
+
+//#ifdef NDEBUG
+//             column->add_attribute(icon_cellrenderer->property_pixbuf(), canvas_tree_model.icon);
+//#endif
+               
+               canvas_tree->append_column(*column);
+       }
+       canvas_tree->set_rules_hint();
+       canvas_tree->signal_row_activated().connect(sigc::mem_fun(*this,&CompView::on_row_activate));
+       canvas_tree->signal_event().connect(sigc::mem_fun(*this,&CompView::on_tree_event));
+       canvas_tree->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       canvas_tree->add_events(Gdk::BUTTON1_MOTION_MASK);
+       canvas_tree->show();
+
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*canvas_tree);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show();
+
+       return scrolledwindow;
+}
+
+Gtk::Widget*
+CompView::create_action_tree()
+{
+       studio::HistoryTreeStore::Model history_tree_model;
+       action_tree=manage(new class Gtk::TreeView());
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("") );
+
+               Gtk::CellRendererToggle* toggle_cr = Gtk::manage( new Gtk::CellRendererToggle() );
+               toggle_cr->signal_toggled().connect(sigc::mem_fun(*this, &studio::CompView::on_action_toggle) );
+               
+               column->pack_start(*toggle_cr); //false = don't expand.
+               column->add_attribute(toggle_cr->property_active(),history_tree_model.is_active);
+               column->set_resizable();
+               column->set_clickable();
+                               
+               action_tree->append_column(*column);
+       }
+       /*{
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("Canvas") );
+               Gtk::CellRendererText *text_cr=Gtk::manage(new Gtk::CellRendererText());
+               text_cr->property_foreground()=Glib::ustring("#7f7f7f");
+               
+               column->pack_start(*text_cr);
+               column->add_attribute(text_cr->property_text(),history_tree_model.canvas_id);
+               column->add_attribute(text_cr->property_foreground_set(),history_tree_model.is_redo);
+                               
+               action_tree->append_column(*column);
+       }*/
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
+
+               Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_jump,true);
+               
+               cell_renderer_jump->property_text()="(JMP)";
+               cell_renderer_jump->property_foreground()="#003a7f";
+               
+               column->set_resizable();
+               column->set_clickable();
+               
+               column->set_sort_column_id(COLUMNID_JUMP);
+
+               action_tree->append_column(*column);
+               //column->clicked();
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("Action") );
+
+               Gtk::CellRendererText *text_cr=Gtk::manage(new Gtk::CellRendererText());
+               text_cr->property_foreground()=Glib::ustring("#7f7f7f");
+
+               
+
+               //column->pack_start(history_tree_model.icon, false); //false = don't expand.
+               column->pack_start(*text_cr);
+               column->add_attribute(text_cr->property_text(),history_tree_model.name);
+               column->add_attribute(text_cr->property_foreground_set(),history_tree_model.is_redo);
+                               
+               action_tree->append_column(*column);
+       }
+
+       
+       action_tree->set_rules_hint();
+//     action_tree->signal_row_activated().connect(sigc::mem_fun(*this,&CompView::on_row_activate));
+       action_tree->signal_event().connect(sigc::mem_fun(*this,&CompView::on_action_event));
+//     action_tree->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+//     action_tree->add_events(Gdk::BUTTON1_MOTION_MASK);
+       action_tree->show();
+
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*action_tree);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show();
+
+       Gtk::Button* clear_button(manage(new Gtk::Button(_("Clear Undo"))));
+       clear_button->signal_pressed().connect(sigc::mem_fun(*this,&studio::CompView::clear_history));
+
+       Gtk::Button* clear_redo_button(manage(new Gtk::Button(_("Clear Redo"))));
+       clear_redo_button->signal_pressed().connect(sigc::mem_fun(*this,&studio::CompView::clear_redo));
+       
+       Gtk::Table* table(manage(new Gtk::Table()));
+       table->attach(*scrolledwindow, 0, 2, 0,1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       table->attach(*clear_button, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       table->attach(*clear_redo_button, 1, 2, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0);
+       
+       table->show_all();
+       
+       return table;
+}
+
+Gtk::Widget*
+CompView::create_instance_selector()
+{
+       instance_selector=manage(new class Gtk::OptionMenu());
+       instance_selector->show();
+       instance_selector->set_menu(instance_list_menu);
+       return instance_selector;
+}
+
+bool
+CompView::close()
+{
+       hide();
+       return true;
+}
+
+void
+CompView::clear_history()
+{
+       if(selected_instance && App::dialog_yes_no(_("Clear History"), _("You will not be able to undo any changes that you have made!\nAre you sure you want to clear the undo stack?")))
+       {               
+               selected_instance->clear_undo_stack();
+       }
+}
+
+void
+CompView::clear_redo()
+{
+       if(selected_instance && App::dialog_yes_no(_("Clear History"), _("You will not be able to redo any changes that you have made!\nAre you sure you want to clear the redo stack?")))
+       {               
+               selected_instance->clear_redo_stack();
+       }
+}
+
+void
+CompView::init_menu()
+{
+       menu.items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       menu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-canvas_new"),
+               sigc::mem_fun(*this,&CompView::menu_new_canvas)));
+       menu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-delete"),
+               sigc::mem_fun(*this,&CompView::menu_delete)));
+       menu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-rename"),
+               sigc::mem_fun(*this,&CompView::menu_rename)));
+}
+
+etl::loose_handle<sinfg::Canvas>
+CompView::get_selected_canvas()
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=canvas_tree->get_selection();
+
+       if(!selection || !selection->get_selected())
+               return 0;
+
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+
+       return static_cast<etl::handle<sinfg::Canvas> >((*selection->get_selected())[canvas_tree_model.canvas]);
+}
+
+void
+CompView::menu_new_canvas()
+{
+#warning Update Me!
+#if 0
+       get_selected_canvas_view()->new_child_canvas();
+#endif
+}
+
+void
+CompView::menu_delete()
+{
+       studio::App::dialog_not_implemented();
+}
+
+void
+CompView::menu_rename()
+{
+       studio::App::dialog_not_implemented();
+}
+
+void
+CompView::set_selected_instance_signal(etl::handle<studio::Instance> x)
+{
+       set_selected_instance(x);
+}
+
+void
+CompView::set_selected_instance_(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       selected_instance=instance;
+       if(instance)
+       {
+               canvas_tree->set_model(instance->canvas_tree_store());
+               action_tree->set_model(instance->history_tree_store());
+               canvas_tree->show();
+               action_tree->show();
+       }
+       else
+       {
+               canvas_tree->set_model(Glib::RefPtr< Gtk::TreeModel >());
+               action_tree->set_model(Glib::RefPtr< Gtk::TreeModel >());
+               canvas_tree->hide();
+               action_tree->hide();
+       }
+}
+
+void
+CompView::set_selected_instance(etl::loose_handle<studio::Instance> x)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       // if it's already selected, don't select it again
+       if (x==selected_instance)
+               return;
+
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+
+       if(x)
+       {
+               int i;
+               for(i=0,iter=studio::App::instance_list.begin();iter!=studio::App::instance_list.end() && ((*iter)!=x);iter++,i++);
+
+               assert(*iter==x);
+
+               instance_selector->set_history(i);
+       }
+       else
+               instance_selector->set_history(0);
+
+       set_selected_instance_(x);      
+}
+
+void
+CompView::new_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+       
+       assert(instance);
+       
+       etl::loose_handle<studio::Instance> loose_instance(instance);
+       
+       instance->sinfgapp::Instance::signal_filename_changed().connect(sigc::mem_fun(*this,&CompView::refresh_instances));
+       instance->sinfgapp::Instance::signal_filename_changed().connect(
+               sigc::bind<etl::loose_handle<studio::Instance> >(
+                       sigc::mem_fun(*this,&CompView::set_selected_instance),
+                       loose_instance
+               )
+       );
+       
+       {
+               std::string name=basename(instance->get_file_name());
+
+               instance_list_menu.items().push_back(Gtk::Menu_Helpers::MenuElem(name,
+                       sigc::bind<etl::loose_handle<studio::Instance> >(sigc::mem_fun(&studio::App::set_selected_instance),loose_instance)     ));
+       }
+}
+
+void
+CompView::delete_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       refresh_instances();
+
+       if(selected_instance==instance)
+       {
+               set_selected_instance(0);
+               instance_selector->set_history(0);
+       }
+}
+
+void
+CompView::refresh_instances()
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       if(!instance_list_menu.items().empty())
+               instance_list_menu.items().clear();
+
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+       for(iter=studio::App::instance_list.begin();iter!=studio::App::instance_list.end();iter++)
+       {
+               std::string name=basename((*iter)->get_file_name());
+
+               instance_list_menu.items().push_back(Gtk::Menu_Helpers::MenuElem(name,
+                       sigc::bind<etl::loose_handle<studio::Instance> >(sigc::mem_fun(&studio::App::set_selected_instance),*iter)      ));
+       }
+       instance_selector->set_menu(instance_list_menu);
+}
+
+void
+CompView::on_row_activate(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *)
+{
+       assert(get_selected_instance());
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+       const Gtk::TreeRow row = *(get_selected_instance()->canvas_tree_store()->get_iter(path));
+       if(row[canvas_tree_model.is_canvas])
+               get_selected_instance()->focus(row[canvas_tree_model.canvas]);
+       else
+               studio::App::dialog_not_implemented();
+}
+
+bool
+CompView::on_action_event(GdkEvent *event)
+{
+       studio::HistoryTreeStore::Model model;
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!action_tree->get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(action_tree->get_model()->get_iter(path));
+                       
+                       //signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               etl::handle<sinfgapp::Action::Undoable> action(row[model.action]);
+                               if((bool)row[model.is_undo])
+                               {
+                                       while(get_selected_instance()->undo_action_stack().size() && get_selected_instance()->undo_action_stack().front()!=action)
+                                               get_selected_instance()->undo();
+                               }
+                               else if((bool)row[model.is_redo])
+                               {
+                                       while(get_selected_instance()->redo_action_stack().size() && get_selected_instance()->undo_action_stack().front()!=action)
+                                               get_selected_instance()->redo();
+                               }
+                       }
+               }
+               
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+bool
+CompView::on_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               switch(event->button.button)
+               {
+               case 3:
+               if(get_selected_canvas())
+               {
+                       menu.items().clear();
+
+                       sinfgapp::Action::ParamList param_list;
+                       param_list.add("canvas",sinfg::Canvas::Handle(get_selected_canvas()));
+                       param_list.add("canvas_interface",get_selected_instance()->find_canvas_interface(get_selected_canvas()));
+                       get_selected_instance()->find_canvas_view(get_selected_canvas())->add_actions_to_menu(&menu, param_list,sinfgapp::Action::CATEGORY_CANVAS);                                     
+                       menu.popup(0,0);
+                       menu.show();
+                       break;
+               }
+               default:
+                       break;
+               }
+               break;
+       case GDK_MOTION_NOTIFY:
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+void
+CompView::on_action_toggle(const Glib::ustring& path_string)
+{
+       studio::HistoryTreeStore::Model history_tree_model;
+
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(selected_instance->history_tree_store()->get_iter(path));
+
+       handle<sinfgapp::Action::Undoable> action=row[history_tree_model.action];
+       
+       selected_instance->sinfgapp::Instance::set_action_status(action,!action->is_active());
+}
diff --git a/synfig-studio/trunk/src/gtkmm/compview.h b/synfig-studio/trunk/src/gtkmm/compview.h
new file mode 100644 (file)
index 0000000..0fef090
--- /dev/null
@@ -0,0 +1,124 @@
+/*! ========================================================================
+** Sinfg
+** Template Header File
+** $Id: compview.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_COMPVIEW_H
+#define __SINFG_COMPVIEW_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/window.h>
+#include <gtkmm/image.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/box.h>
+
+#include <ETL/handle>
+
+#include "dialogsettings.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class Canvas; };
+
+namespace studio {
+
+class Instance;
+class CanvasView;
+
+class CompView : public Gtk::Window
+{
+       DialogSettings dialog_settings;
+       
+       Gtk::Tooltips tooltips;
+
+       Gtk::OptionMenu *instance_selector;
+       Gtk::Notebook *notebook;
+
+       Gtk::TreeView *canvas_tree;
+       Gtk::TreeView *action_tree;
+
+       Gtk::Menu       instance_list_menu;
+       Gtk::Menu       menu;
+
+       etl::loose_handle<studio::Instance>     selected_instance;
+
+       void set_selected_instance_(etl::handle<studio::Instance> x);
+
+       void clear_history();
+       void clear_redo();
+       
+public:
+       CompView();
+       ~CompView();
+
+       etl::loose_handle<studio::Instance> get_selected_instance() { return selected_instance; }
+
+       etl::loose_handle<sinfg::Canvas> get_selected_canvas();
+
+       etl::loose_handle<studio::CanvasView> get_selected_canvas_view();
+
+       void set_selected_instance(etl::loose_handle<studio::Instance> x);
+
+       void set_selected_instance_signal(etl::handle<studio::Instance> x);
+
+       void new_instance(etl::handle<studio::Instance> x);
+
+       void delete_instance(etl::handle<studio::Instance> x);
+
+       void refresh_instances();
+
+       bool close();
+
+private:
+       
+       Gtk::Widget* create_canvas_tree();
+       Gtk::Widget* create_action_tree();
+       Gtk::Widget* create_instance_selector();
+       
+       void on_row_activate(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *);
+       bool on_tree_event(GdkEvent *event);
+
+       bool on_action_event(GdkEvent *event);
+
+       void init_menu();
+
+       void menu_new_canvas();
+       void menu_delete();
+       void menu_rename();
+
+       void on_action_toggle(const Glib::ustring& path);
+};
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/devicetracker.cpp b/synfig-studio/trunk/src/gtkmm/devicetracker.cpp
new file mode 100644 (file)
index 0000000..6723e8f
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file devicetracker.cpp
+**     \brief Template File
+**
+**     $Id: devicetracker.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "devicetracker.h"
+#include <gdkmm/device.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+DeviceTracker::DeviceTracker()
+{
+       // By default, set the input mode on devices to
+       // GDK_MODE_SCREEN.
+       {
+               GList*  device_list;
+               GList*  iter;
+               device_list=gdk_devices_list();
+               
+               for(iter=device_list;iter;iter=g_list_next(iter))
+               {
+                       GdkDevice* device=reinterpret_cast<GdkDevice*>(iter->data);
+                       gdk_device_set_mode(device,GDK_MODE_SCREEN);
+                       
+                       sinfgapp::InputDevice::Handle input_device;
+                       input_device=sinfgapp::Main::add_input_device(device->name,sinfgapp::InputDevice::Type(device->source));
+                       if(input_device->get_type()==sinfgapp::InputDevice::TYPE_MOUSE)
+                               sinfgapp::Main::select_input_device(input_device);
+               }               
+       }
+}
+
+DeviceTracker::~DeviceTracker()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/devicetracker.h b/synfig-studio/trunk/src/gtkmm/devicetracker.h
new file mode 100644 (file)
index 0000000..cc25c04
--- /dev/null
@@ -0,0 +1,49 @@
+/* === S I N F G =========================================================== */
+/*!    \file devicetracker.h
+**     \brief Template Header
+**
+**     $Id: devicetracker.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DEVICETRACKER_H
+#define __SINFG_DEVICETRACKER_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class DeviceTracker
+{
+public:
+       DeviceTracker();
+       ~DeviceTracker();
+
+}; // END of class ToolTracker
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_color.cpp b/synfig-studio/trunk/src/gtkmm/dialog_color.cpp
new file mode 100644 (file)
index 0000000..5abb515
--- /dev/null
@@ -0,0 +1,136 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_gradient.cpp
+**     \brief Template File
+**
+**     $Id: dialog_color.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_color.h"
+#include "widget_color.h"
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <sinfg/general.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "widget_color.h"
+#include <gtkmm/spinbutton.h>
+#include <sinfgapp/main.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+#include <sigc++/hide.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_Color::Dialog_Color():
+       Dialog(_("Colors"),false,true),
+       dialog_settings(this,"color"),
+       busy_(false)
+//     adjustment_pos(0,0.0,1.0,0.001,0.001,0.001)
+{
+       set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+       // Setup the buttons
+       //Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+       //ok_button->show();
+       //add_action_widget(*ok_button,2);
+       //ok_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Color::on_ok_pressed));
+
+       //Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       //apply_button->show();
+       //add_action_widget(*apply_button,1);
+       //apply_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Color::on_apply_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::hide_return(sigc::mem_fun(*this, &Dialog_Color::on_close_pressed)));      
+       signal_delete_event().connect(sigc::hide(sigc::mem_fun(*this, &Dialog_Color::on_close_pressed)));
+
+       Gtk::Table* table(manage(new Gtk::Table(2,2,false)));
+       get_vbox()->pack_start(*table);
+
+       widget_color=manage(new Widget_ColorEdit());
+       widget_color->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Color::on_color_changed));
+       //widget_color->signal_activate().connect(sigc::mem_fun(*this,&studio::Dialog_Color::on_color_changed));
+       table->attach(*widget_color, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);   
+
+       add_accel_group(App::ui_manager()->get_accel_group());
+
+       show_all_children();
+}
+
+Dialog_Color::~Dialog_Color()
+{
+}
+
+void
+Dialog_Color::reset()
+{
+       signal_edited_.clear();
+}
+
+bool
+Dialog_Color::on_close_pressed()
+{
+//     signal_edited_(get_color());
+       busy_=false;
+       grab_focus();
+       reset();
+       hide();
+       return true;
+}
+
+void
+Dialog_Color::on_apply_pressed()
+{
+       busy_=true;
+       signal_edited_(get_color());
+       busy_=false;
+}
+
+void
+Dialog_Color::on_color_changed()
+{
+       busy_=true;
+       signal_edited_(get_color());
+       busy_=false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_color.h b/synfig-studio/trunk/src/gtkmm/dialog_color.h
new file mode 100644 (file)
index 0000000..4795a38
--- /dev/null
@@ -0,0 +1,103 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_color.h
+**     \brief Template Header
+**
+**     $Id: dialog_color.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_COLOR_H
+#define __SINFG_STUDIO_DIALOG_COLOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/checkbutton.h>
+
+#include <sinfg/gamma.h>
+#include <sinfg/time.h>
+
+#include "widget_coloredit.h"
+
+#include <sinfgapp/value_desc.h>
+#include <sinfg/time.h>
+
+#include "dialogsettings.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; class SpinButton; class Adjustment; };
+
+namespace sinfgapp {
+class CanvasInterface;
+};
+
+namespace studio {
+
+class Widget_Color;
+       
+class Dialog_Color : public Gtk::Dialog
+{
+       DialogSettings dialog_settings;
+       
+       sigc::signal<void,sinfg::Color> signal_edited_;
+       //sigc::signal<void,sinfg::Color> signal_apply_;
+
+       bool on_close_pressed();
+       void on_apply_pressed();
+       void on_color_changed();
+
+       Widget_ColorEdit* widget_color;
+
+       bool busy_;
+       
+public:
+       bool busy()const { return busy_; }
+       
+       sigc::signal<void,sinfg::Color>& signal_edited() { return signal_edited_; }
+       
+       //sigc::signal<void,sinfg::Color>& signal_apply() { return signal_apply_; }
+       
+       void set_color(const sinfg::Color& x) { widget_color->set_value(x); }
+
+       sinfg::Color get_color()const { return widget_color->get_value(); }
+               
+       void reset();
+
+       
+       Dialog_Color();
+       ~Dialog_Color();
+
+//     void edit(const sinfgapp::ValueDesc &x, etl::handle<sinfgapp::CanvasInterface> canvas_interface, sinfg::Time x=0);
+}; // END of Dialog_Color
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_gradient.cpp b/synfig-studio/trunk/src/gtkmm/dialog_gradient.cpp
new file mode 100644 (file)
index 0000000..e65c4fa
--- /dev/null
@@ -0,0 +1,194 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_gradient.cpp
+**     \brief Template File
+**
+**     $Id: dialog_gradient.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_gradient.h"
+#include "widget_gradient.h"
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <sinfg/general.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfgapp/main.h>
+#include "widget_color.h"
+#include <gtkmm/spinbutton.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_Gradient::Dialog_Gradient():
+       Dialog(_("Gradient Editor"),false,true),
+       dialog_settings(this,"gradient"),
+       adjustment_pos(0,0.0,1.0,0.001,0.001,0.001)
+{
+       set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+       // Setup the buttons
+       Gtk::Button *grab_button(manage(new class Gtk::Button(Gtk::StockID("Grab"))));
+       grab_button->show();
+       add_action_widget(*grab_button,2);
+       grab_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Gradient::on_grab_pressed));
+
+       /*
+       Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       apply_button->show();
+       add_action_widget(*apply_button,1);
+       apply_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Gradient::on_apply_pressed));
+       */
+       
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Gradient::hide));  
+
+       Gtk::Table* table(manage(new Gtk::Table(2,2,false)));
+       get_vbox()->pack_start(*table);
+
+       widget_gradient=manage(new Widget_Gradient());
+       widget_gradient->set_editable();
+       widget_gradient->signal_cpoint_selected().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_cpoint_selected));   
+       widget_gradient->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_changed));
+       //table->attach(*manage(new Gtk::Label(_("Not yet fully implemented"))), 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);       
+       table->attach(*widget_gradient, 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+
+       widget_color=manage(new Widget_ColorEdit());
+       widget_color->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_values_adjusted));
+       widget_color->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_changed));
+       widget_color->signal_activated().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_values_adjusted));
+       table->attach(*widget_color, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);   
+
+
+       spinbutton_pos=manage(new class Gtk::SpinButton(adjustment_pos,0.0001,4));
+       spinbutton_pos->set_update_policy(Gtk::UPDATE_ALWAYS);
+       adjustment_pos.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_values_adjusted));
+       adjustment_pos.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Gradient::on_changed));
+       table->attach(*spinbutton_pos, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+
+       
+       add_accel_group(App::ui_manager()->get_accel_group());
+
+       show_all_children();
+}
+
+Dialog_Gradient::~Dialog_Gradient()
+{
+}
+
+void
+Dialog_Gradient::set_gradient(const sinfg::Gradient& x)
+{
+       widget_gradient->set_value(x);
+}
+
+void
+Dialog_Gradient::reset()
+{
+       value_changed_connection.disconnect();
+       signal_edited_.clear();
+}
+
+void
+Dialog_Gradient::on_grab_pressed()
+{
+       sinfgapp::Main::set_gradient(get_gradient());
+//     signal_edited_(get_gradient());
+//     reset();
+//     hide();
+}
+
+void
+Dialog_Gradient::on_apply_pressed()
+{
+       signal_edited_(get_gradient());
+}
+
+void
+Dialog_Gradient::on_changed()
+{
+       signal_edited_(get_gradient());
+}
+
+void
+Dialog_Gradient::on_cpoint_selected(sinfg::Gradient::CPoint x)
+{
+       widget_color->set_value(x.color);
+       adjustment_pos.set_value(x.pos);
+}
+
+void
+Dialog_Gradient::on_values_adjusted()
+{
+       sinfg::Gradient::CPoint x(widget_gradient->get_selected_cpoint());
+       x.color=widget_color->get_value();
+       x.pos=adjustment_pos.get_value();
+       widget_gradient->update_cpoint(x);
+}
+
+static void
+dialog_gradient_value_desc_edit(sinfg::Gradient g,sinfgapp::ValueDesc x,handle<sinfgapp::CanvasInterface> canvas_interface)
+{
+//     canvas_interface->connect_value(x,ValueBase(g));
+}
+
+void
+Dialog_Gradient::edit(const sinfgapp::ValueDesc &x, etl::handle<sinfgapp::CanvasInterface> canvas_interface, sinfg::Time time)
+{
+       reset();
+       if(x.is_const())
+               set_gradient(x.get_value().get(Gradient()));
+       else if(x.is_value_node())
+               set_gradient((*x.get_value_node())(time).get(Gradient()));
+               
+       signal_edited().connect(
+               sigc::bind(
+                       sigc::bind(
+                               sigc::ptr_fun(dialog_gradient_value_desc_edit),
+                               canvas_interface
+                       ),
+                       x
+               )
+       );
+               
+       present();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_gradient.h b/synfig-studio/trunk/src/gtkmm/dialog_gradient.h
new file mode 100644 (file)
index 0000000..1c79609
--- /dev/null
@@ -0,0 +1,112 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_gradient.h
+**     \brief Template Header
+**
+**     $Id: dialog_gradient.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_GRADIENT_H
+#define __SINFG_STUDIO_DIALOG_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/checkbutton.h>
+
+#include <sinfg/gamma.h>
+#include <sinfg/time.h>
+
+#include "widget_gradient.h"
+#include "widget_coloredit.h"
+
+#include <sinfgapp/value_desc.h>
+#include <sinfg/time.h>
+
+#include "dialogsettings.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; class SpinButton; class Adjustment; };
+
+namespace sinfgapp {
+class CanvasInterface;
+};
+
+namespace studio {
+
+class Widget_Gradient;
+class Widget_ColorEdit;
+       
+class Dialog_Gradient : public Gtk::Dialog
+{
+       DialogSettings dialog_settings;
+       
+       Gtk::SpinButton *spinbutton_pos;
+
+       Gtk::Adjustment adjustment_pos;
+
+
+       sigc::signal<void,sinfg::Gradient> signal_edited_;
+
+       sigc::connection value_changed_connection;
+       
+       void on_ok_pressed();
+       void on_apply_pressed();
+       void on_grab_pressed();
+       
+       void on_cpoint_selected(sinfg::Gradient::CPoint x);
+       void on_values_adjusted();
+
+       Widget_Gradient* widget_gradient;
+       Widget_ColorEdit* widget_color;
+
+       void on_changed();
+       
+public:
+
+       sigc::signal<void,sinfg::Gradient>& signal_edited() { return signal_edited_; }
+       
+       void set_gradient(const sinfg::Gradient& x);
+
+       const sinfg::Gradient& get_gradient()const { return widget_gradient->get_value(); }
+               
+       void reset();
+
+       
+       Dialog_Gradient();
+       ~Dialog_Gradient();
+
+       void edit(const sinfgapp::ValueDesc &x, etl::handle<sinfgapp::CanvasInterface> canvas_interface, sinfg::Time x=0);
+}; // END of Dialog_Gradient
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_keyframe.cpp b/synfig-studio/trunk/src/gtkmm/dialog_keyframe.cpp
new file mode 100644 (file)
index 0000000..6f2196b
--- /dev/null
@@ -0,0 +1,145 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_keyframe.cpp
+**     \brief Template File
+**
+**     $Id: dialog_keyframe.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_keyframe.h"
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/button.h>
+#include "widget_waypointmodel.h"
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_Keyframe::Dialog_Keyframe(Gtk::Window& parent,handle<sinfgapp::CanvasInterface> canvas_interface):
+       Gtk::Dialog(_("Keyframe Dialog"),parent,false,true),
+       canvas_interface(canvas_interface)
+{
+       // Set up the buttons
+       {
+               Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+               ok_button->show();
+               add_action_widget(*ok_button,2);
+               ok_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Keyframe::on_ok_pressed));
+       
+/*             Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+               apply_button->show();
+               add_action_widget(*apply_button,1);
+               apply_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Keyframe::on_apply_pressed));
+*/     
+               Gtk::Button *delete_button(manage(new class Gtk::Button(Gtk::StockID("gtk-delete"))));
+               delete_button->show();
+               add_action_widget(*delete_button,3);
+               delete_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Keyframe::on_delete_pressed));
+       
+               Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+               cancel_button->show();
+               add_action_widget(*cancel_button,0);
+               cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Keyframe::hide));
+       }
+
+       Gtk::Table *table=manage(new Gtk::Table(2,2,false));
+
+       get_vbox()->pack_start(*table);
+
+       entry_description.set_text("Not yet implemented");
+       
+       //table->attach(*manage(new Gtk::Label(_("Description"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       //table->attach(entry_description, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+
+       table->show_all();
+       
+       widget_waypoint_model=Gtk::manage(new Widget_WaypointModel());
+       widget_waypoint_model->show();
+       table->attach(*widget_waypoint_model, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+
+}
+
+Dialog_Keyframe::~Dialog_Keyframe()
+{
+}
+
+const sinfg::Keyframe&
+Dialog_Keyframe::get_keyframe()const
+{
+       return keyframe_;
+}
+
+void
+Dialog_Keyframe::set_keyframe(const sinfg::Keyframe& x)
+{
+       keyframe_=x;
+}
+
+void
+Dialog_Keyframe::on_ok_pressed()
+{
+       if(widget_waypoint_model->get_waypoint_model().is_trivial())
+               return;
+       
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_waypoint_set"));
+       
+       assert(action);
+       
+       action->set_param("canvas",canvas_interface->get_canvas());                     
+       action->set_param("canvas_interface",canvas_interface);                 
+       action->set_param("keyframe",keyframe_);
+       action->set_param("model",widget_waypoint_model->get_waypoint_model());
+       
+       if(!canvas_interface->get_instance()->perform_action(action))
+       {
+       }
+}
+
+
+void
+Dialog_Keyframe::on_delete_pressed()
+{
+}
+
+
+void
+Dialog_Keyframe::on_apply_pressed()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_keyframe.h b/synfig-studio/trunk/src/gtkmm/dialog_keyframe.h
new file mode 100644 (file)
index 0000000..4d17a8d
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_keyframe.h
+**     \brief Template Header
+**
+**     $Id: dialog_keyframe.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_KEYFRAME_H
+#define __SINFG_STUDIO_DIALOG_KEYFRAME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/window.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/entry.h>
+
+#include <sinfgapp/canvasinterface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio
+{
+
+class Widget_WaypointModel;
+
+class Dialog_Keyframe : public Gtk::Dialog
+{
+       Gtk::Tooltips tooltips_;
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface;
+       
+       sinfg::Keyframe keyframe_;
+
+       Gtk::Entry entry_description;
+       
+       Widget_WaypointModel* widget_waypoint_model;
+
+       void on_ok_pressed();
+       void on_apply_pressed();
+       void on_delete_pressed();
+
+public:
+       Dialog_Keyframe(Gtk::Window& parent,etl::handle<sinfgapp::CanvasInterface> canvas_interface);
+       ~Dialog_Keyframe();
+
+       const sinfg::Keyframe& get_keyframe()const;
+       void set_keyframe(const sinfg::Keyframe& x);
+
+private:
+
+}; // END of class RenderSettings
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_preview.cpp b/synfig-studio/trunk/src/gtkmm/dialog_preview.cpp
new file mode 100644 (file)
index 0000000..da045fd
--- /dev/null
@@ -0,0 +1,156 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_preview.cpp
+**     \brief Preview dialog File
+**
+**     $Id: dialog_preview.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_preview.h"
+#include "preview.h"
+#include <gtkmm/spinbutton.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+using namespace Gtk;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+//dialog_preview stuff...
+Dialog_Preview::Dialog_Preview()
+:Dialog(_("Preview Window"),false,true),
+settings(this,"preview")
+{
+       get_vbox()->pack_start(preview);
+}
+
+Dialog_Preview::~Dialog_Preview()
+{
+}
+
+void Dialog_Preview::set_preview(handle<Preview>       prev)
+{
+       get_window().clear();
+       preview.set_preview(prev);
+       //preview.update();
+}
+
+void Dialog_Preview::on_hide()
+{
+       Dialog::on_hide();
+       preview.stop();
+       preview.stoprender();
+}
+
+//dialog_previewoptions stuff
+Dialog_PreviewOptions::Dialog_PreviewOptions()
+:Dialog(_("Preview Options"),false,true),
+adj_zoom(0.5,0.1,5.0,0.1,0.2),
+adj_fps(15,1,120,1,5),
+check_overbegin(_("Begin Time"),false),
+check_overend(_("End Time"),false),
+settings(this,"prevoptions")
+{
+       //framerate = 15.0f;
+       //zoom = 0.2f;
+       
+       //set the fps of the time widgets       
+       Gtk::Table      *ot = manage(new class Gtk::Table);
+       
+       ot->attach(*manage(new class Gtk::Label(_("Zoom"))),0,1,0,1);   
+       ot->attach(*manage(new class Gtk::Label(_("FPS"))),1,2,0,1);
+       
+       ot->attach(*manage(new class Gtk::SpinButton(adj_zoom,0.1,2)),0,1,1,2); 
+       ot->attach(*manage(new class Gtk::SpinButton(adj_fps,1,1)),1,2,1,2);
+       
+       ot->attach(check_overbegin,0,1,2,3);
+       ot->attach(check_overend,1,2,2,3);
+       check_overbegin.signal_toggled().connect(sigc::mem_fun(*this,&Dialog_PreviewOptions::on_overbegin_toggle));
+       check_overend.signal_toggled().connect(sigc::mem_fun(*this,&Dialog_PreviewOptions::on_overend_toggle));
+               
+       ot->attach(time_begin,0,1,3,4);
+       ot->attach(time_end,1,2,3,4);
+       
+       Gtk::Button *okbutton = manage(new Gtk::Button(_("Preview")));
+       okbutton->signal_clicked().connect(sigc::mem_fun(*this,&Dialog_PreviewOptions::on_ok_pressed));
+       ot->attach(*okbutton,0,2,4,5);
+       
+       ot->show_all();
+       
+       get_vbox()->pack_start(*ot);
+       
+       time_begin.set_sensitive(false);
+       time_end.set_sensitive(false);
+}
+
+Dialog_PreviewOptions::~Dialog_PreviewOptions()
+{
+}
+
+void Dialog_PreviewOptions::on_ok_pressed()
+{
+       PreviewInfo     i;
+       i.zoom = get_zoom();
+       i.fps = get_fps();
+       i.overbegin = get_begin_override();
+       i.overend = get_end_override();
+       if(i.overbegin) i.begintime = (float)get_begintime();
+       if(i.overend)   i.endtime = (float)get_endtime();
+       
+       hide();
+       signal_finish_(i);
+       signal_finish_.clear();
+}
+
+void Dialog_PreviewOptions::on_overbegin_toggle()
+{
+       time_begin.set_sensitive(get_begin_override());
+}
+
+void Dialog_PreviewOptions::on_overend_toggle()
+{
+       time_end.set_sensitive(get_end_override());
+}
+
+void studio::Dialog_PreviewOptions::set_global_fps(float f) 
+{ 
+       globalfps = f; 
+       time_begin.set_fps(f); 
+       time_end.set_fps(f);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_preview.h b/synfig-studio/trunk/src/gtkmm/dialog_preview.h
new file mode 100644 (file)
index 0000000..14417ea
--- /dev/null
@@ -0,0 +1,130 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_preview.h
+**     \brief Preview dialog Header
+**
+**     $Id: dialog_preview.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_DIALOG_PREVIEW_H
+#define __SINFG_GTKMM_DIALOG_PREVIEW_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/dialogsettings.h>
+
+#include "preview.h"
+#include <gtkmm/widget_time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+struct PreviewInfo
+{
+       float zoom,fps,begintime,endtime;
+       bool overbegin,overend;
+};
+
+class Dialog_Preview : public Gtk::Dialog
+{
+       Widget_Preview  preview;
+       DialogSettings  settings;
+       
+       //etl::handle<sinfg::Canvas> canvas;
+                       
+public:
+       Dialog_Preview();
+       ~Dialog_Preview();
+
+    void set_preview(etl::handle<Preview> prev);
+
+       Widget_Preview &get_widget() {return preview;}
+       const Widget_Preview &get_widget() const {return preview;}
+
+       virtual void on_hide();
+       //other forwarding functions...
+}; // END of Dialog_Preview
+
+class Dialog_PreviewOptions : public Gtk::Dialog
+{
+       //all the info needed to construct a render description...      
+       Gtk::Adjustment adj_zoom;       // factor at which to resize the window...
+       
+       Gtk::Adjustment adj_fps;        // how often to take samples of the animation
+       
+       studio::Widget_Time time_begin;
+       studio::Widget_Time time_end;
+                       
+       Gtk::CheckButton check_overbegin;
+       Gtk::CheckButton check_overend;
+       
+       DialogSettings  settings;
+       
+       float   globalfps;
+       
+       // for finishing
+       void on_ok_pressed();
+       
+       //for ui stuff
+       void on_overbegin_toggle();
+       void on_overend_toggle();
+       
+       sigc::signal<void,const PreviewInfo &>  signal_finish_;
+public:
+       Dialog_PreviewOptions();
+       ~Dialog_PreviewOptions();
+
+       float get_zoom() const { return adj_zoom.get_value(); }
+       void set_zoom(float z) { adj_zoom.set_value(z); }
+       
+       float get_fps() const { return adj_fps.get_value(); }
+       void set_fps(float z) { adj_fps.set_value(z); }
+       
+       float get_global_fps() const { return globalfps; }
+       void set_global_fps(float f);
+       
+       sinfg::Time get_begintime() const { return time_begin.get_value(); }
+       void set_begintime(const sinfg::Time &t) { time_begin.set_value(t); }
+       
+       sinfg::Time get_endtime() const { return time_end.get_value(); }
+       void set_endtime(const sinfg::Time &t) { time_end.set_value(t); }
+       
+       bool get_begin_override() const { return check_overbegin.get_active(); }
+       void set_begin_override(bool o) { check_overbegin.set_active(o); }
+       
+       bool get_end_override() const { return check_overend.get_active(); }
+       void set_end_override(bool o) { check_overend.set_active(o); }
+       
+       sigc::signal<void,const PreviewInfo &>  &signal_finish() {return signal_finish_;}
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp b/synfig-studio/trunk/src/gtkmm/dialog_setup.cpp
new file mode 100644 (file)
index 0000000..2788dd6
--- /dev/null
@@ -0,0 +1,619 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_setup.cpp
+**     \brief Template File
+**
+**     $Id: dialog_setup.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_setup.h"
+#include "app.h"
+#include <gtkmm/scale.h>
+#include <gtkmm/table.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/spinbutton.h>
+#include "widget_enum.h"
+
+#include <ETL/stringf>
+#include <ETL/misc>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_Setup::Dialog_Setup():
+       Dialog(_("SINFG Studio Setup"),false,true),
+       adj_gamma_r(2.2,0.1,3.0,0.025,0.025,0.025),
+       adj_gamma_g(2.2,0.1,3.0,0.025,0.025,0.025),
+       adj_gamma_b(2.2,0.1,3.0,0.025,0.025,0.025),
+       adj_recent_files(15,1,50,1,1,1),
+       adj_undo_depth(100,10,5000,1,1,1),
+       toggle_use_colorspace_gamma(_("Visually Linear Color Selection"))
+{
+       // Setup the buttons
+
+       Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+       ok_button->show();
+       add_action_widget(*ok_button,2);
+       ok_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Setup::on_ok_pressed));
+
+       Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       apply_button->show();
+       add_action_widget(*apply_button,1);
+       apply_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Setup::on_apply_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Setup::hide));
+
+
+       // Notebook
+       Gtk::Notebook *notebook=manage(new class Gtk::Notebook());
+       get_vbox()->pack_start(*notebook);
+
+
+       // Gamma
+       Gtk::Table *gamma_table=manage(new Gtk::Table(2,2,false));
+       notebook->append_page(*gamma_table,_("Gamma"));
+       //gamma_frame->add(*gamma_table);
+       
+       gamma_table->attach(gamma_pattern, 0, 2, 0, 1, Gtk::EXPAND, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+
+       Gtk::HScale* scale_gamma_r(manage(new Gtk::HScale(adj_gamma_r)));
+       gamma_table->attach(*manage(new Gtk::Label(_("Red"))), 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       gamma_table->attach(*scale_gamma_r, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       adj_gamma_r.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Setup::on_gamma_r_change));
+       
+       Gtk::HScale* scale_gamma_g(manage(new Gtk::HScale(adj_gamma_g)));
+       gamma_table->attach(*manage(new Gtk::Label(_("Green"))), 0, 1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       gamma_table->attach(*scale_gamma_g, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       adj_gamma_g.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Setup::on_gamma_g_change));
+
+       Gtk::HScale* scale_gamma_b(manage(new Gtk::HScale(adj_gamma_b)));
+       gamma_table->attach(*manage(new Gtk::Label(_("Blue"))), 0, 1, 3, 4, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       gamma_table->attach(*scale_gamma_b, 1, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       adj_gamma_b.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Setup::on_gamma_b_change));
+
+       gamma_table->attach(*manage(new Gtk::Label(_("Black Level"))), 0, 1, 4, 5, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       gamma_table->attach(black_level_selector, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+       black_level_selector.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Setup::on_black_level_change));
+
+       //gamma_table->attach(*manage(new Gtk::Label(_("Red-Blue Level"))), 0, 1, 5, 6, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       //gamma_table->attach(red_blue_level_selector, 1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       //red_blue_level_selector.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Dialog_Setup::on_red_blue_level_change));
+
+
+       // Misc
+       Gtk::Table *misc_table=manage(new Gtk::Table(2,2,false));
+       notebook->append_page(*misc_table,_("Misc."));
+       
+       // Misc - Timestamp
+       timestamp_menu=manage(new class Gtk::Menu());
+       misc_table->attach(*manage(new Gtk::Label(_("Timestamp"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       misc_table->attach(timestamp_optionmenu, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+
+#define ADD_TIMESTAMP(desc,x)  \
+       timestamp_menu->items().push_back(      \
+               Gtk::Menu_Helpers::MenuElem(    \
+                       desc,   \
+                       sigc::bind(     \
+                               sigc::mem_fun(  \
+                                       *this,  \
+                                       &studio::Dialog_Setup::set_time_format  \
+                               ),      \
+                               x       \
+                       )       \
+               )       \
+       );
+       ADD_TIMESTAMP("HH:MM:SS.FF",Time::FORMAT_VIDEO);
+       ADD_TIMESTAMP("(HHh MMm SSs) FFf",Time::FORMAT_NORMAL);
+       ADD_TIMESTAMP("(HHhMMmSSs)FFf",Time::FORMAT_NORMAL|Time::FORMAT_NOSPACES);
+       ADD_TIMESTAMP("HHh MMm SSs FFf",Time::FORMAT_NORMAL|Time::FORMAT_FULL);
+       ADD_TIMESTAMP("HHhMMmSSsFFf",Time::FORMAT_NORMAL|Time::FORMAT_NOSPACES|Time::FORMAT_FULL);
+
+       timestamp_optionmenu.set_menu(*timestamp_menu);
+       
+#undef ADD_TIMESTAMP
+
+       {
+               ParamDesc param_desc;
+               param_desc
+                       .set_hint("enum")
+                       .add_enum_value(Distance::SYSTEM_UNITS,"u",_("Units"))
+                       .add_enum_value(Distance::SYSTEM_PIXELS,"px",_("Pixels"))
+                       .add_enum_value(Distance::SYSTEM_POINTS,"pt",_("Points"))
+                       .add_enum_value(Distance::SYSTEM_INCHES,"in",_("Inches"))
+                       .add_enum_value(Distance::SYSTEM_METERS,"m",_("Meters"))
+                       .add_enum_value(Distance::SYSTEM_CENTIMETERS,"cm",_("Centimeters"))
+                       .add_enum_value(Distance::SYSTEM_MILLIMETERS,"mm",_("Millimeters"));
+
+               widget_enum=manage(new Widget_Enum());
+               widget_enum->set_param_desc(param_desc);
+
+               misc_table->attach(*manage(new Gtk::Label(_("Unit System"))), 0, 1, 3, 4, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+               misc_table->attach(*widget_enum, 1, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       }
+
+       // Misc - recent files
+       Gtk::SpinButton* recent_files_spinbutton(manage(new Gtk::SpinButton(adj_recent_files,1,0)));
+       misc_table->attach(*manage(new Gtk::Label(_("Recent Files"))), 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       misc_table->attach(*recent_files_spinbutton, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+
+       // Misc - use_colorspace_gamma
+       misc_table->attach(toggle_use_colorspace_gamma, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       
+       show_all_children();
+}
+
+Dialog_Setup::~Dialog_Setup()
+{
+}
+
+void
+Dialog_Setup::on_ok_pressed()
+{
+    on_apply_pressed();
+       hide();
+}
+
+void
+Dialog_Setup::on_apply_pressed()
+{
+       App::gamma.set_all(1.0/adj_gamma_r.get_value(),1.0/adj_gamma_g.get_value(),1.0/adj_gamma_b.get_value(),black_level_selector.get_value(),red_blue_level_selector.get_value());
+
+       App::set_max_recent_files((int)adj_recent_files.get_value());   
+       
+       // Set the time format
+       App::set_time_format(get_time_format());
+       
+       // Set the use_colorspace_gamma flag
+       App::use_colorspace_gamma=toggle_use_colorspace_gamma.get_active();
+
+       App::distance_system=Distance::System(widget_enum->get_value());
+       
+       App::save_settings();
+}
+
+void
+Dialog_Setup::on_gamma_r_change()
+{
+       gamma_pattern.set_gamma_r(1.0/adj_gamma_r.get_value());
+       gamma_pattern.refresh();
+       gamma_pattern.queue_draw();
+}
+
+void
+Dialog_Setup::on_gamma_g_change()
+{
+       gamma_pattern.set_gamma_g(1.0/adj_gamma_g.get_value());
+       gamma_pattern.refresh();
+       gamma_pattern.queue_draw();
+}
+
+void
+Dialog_Setup::on_gamma_b_change()
+{
+       gamma_pattern.set_gamma_b(1.0/adj_gamma_b.get_value());
+       gamma_pattern.refresh();
+       gamma_pattern.queue_draw();
+}
+
+void
+Dialog_Setup::on_black_level_change()
+{
+       gamma_pattern.set_black_level(black_level_selector.get_value());
+       gamma_pattern.refresh();
+       gamma_pattern.queue_draw();
+}
+
+void
+Dialog_Setup::on_red_blue_level_change()
+{
+       gamma_pattern.set_red_blue_level(red_blue_level_selector.get_value());
+       gamma_pattern.refresh();
+       gamma_pattern.queue_draw();
+}
+
+
+void
+Dialog_Setup::refresh()
+{
+       adj_gamma_r.set_value(1.0/App::gamma.get_gamma_r());    
+       adj_gamma_g.set_value(1.0/App::gamma.get_gamma_g());    
+       adj_gamma_b.set_value(1.0/App::gamma.get_gamma_b());    
+       black_level_selector.set_value(App::gamma.get_black_level());
+       red_blue_level_selector.set_value(App::gamma.get_red_blue_level());
+       
+       // Refresh the temporary gamma
+       gamma_pattern.set_gamma_r(1.0/adj_gamma_r.get_value());
+       gamma_pattern.set_gamma_g(1.0/adj_gamma_g.get_value());
+       gamma_pattern.set_gamma_b(1.0/adj_gamma_b.get_value());
+       gamma_pattern.set_black_level(black_level_selector.get_value());
+       gamma_pattern.set_red_blue_level(red_blue_level_selector.get_value());
+       gamma_pattern.refresh();
+       
+       adj_recent_files.set_value(App::get_max_recent_files());
+       
+       // Refresh the time format
+       set_time_format(App::get_time_format());
+
+       widget_enum->set_value(App::distance_system);
+       
+       // Refresh the status of the use_colorspace_gamma flag
+       toggle_use_colorspace_gamma.set_active(App::use_colorspace_gamma);
+
+}
+
+GammaPattern::GammaPattern():
+       tile_w(80),
+       tile_h(80)
+{
+       set_size_request(tile_w*4,tile_h*3);
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::GammaPattern::redraw));
+}
+       
+GammaPattern::~GammaPattern()
+{
+}
+
+void
+GammaPattern::refresh()
+{
+       black[0].set_rgb_p(
+               r_F32_to_F32(0.0),      
+               g_F32_to_F32(0.0),      
+               b_F32_to_F32(0.0)
+       );
+       white[0].set_rgb_p(
+               r_F32_to_F32(1.0),      
+               g_F32_to_F32(1.0),      
+               b_F32_to_F32(1.0)
+       );
+       gray50[0].set_rgb_p(
+               r_F32_to_F32(0.5),      
+               g_F32_to_F32(0.5),      
+               b_F32_to_F32(0.5)
+       );
+       gray25[0].set_rgb_p(
+               r_F32_to_F32(0.25),     
+               g_F32_to_F32(0.25),     
+               b_F32_to_F32(0.25)
+       );
+
+       // Reds
+       black[1].set_rgb(black[0].get_red(),0,0);
+       gray25[1].set_rgb(gray25[0].get_red(),0,0);
+       gray50[1].set_rgb(gray50[0].get_red(),0,0);
+       white[1].set_rgb(white[0].get_red(),0,0);
+
+       // Greens
+       black[2].set_rgb(0,black[0].get_green(),0);
+       gray25[2].set_rgb(0,gray25[0].get_green(),0);
+       gray50[2].set_rgb(0,gray50[0].get_green(),0);
+       white[2].set_rgb(0,white[0].get_green(),0);
+
+       // blues
+       black[3].set_rgb(0,0,black[0].get_blue());
+       gray25[3].set_rgb(0,0,gray25[0].get_blue());
+       gray50[3].set_rgb(0,0,gray50[0].get_blue());
+       white[3].set_rgb(0,0,white[0].get_blue());
+}
+
+bool
+GammaPattern::redraw(GdkEventExpose*bleh)
+{
+       static const char hlines[] = { 3, 0 };
+
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+       
+       int i;
+       Gdk::Color trueblack("#000000");
+       
+       // 50% Pattern
+       for(i=0;i<4;i++)
+       {
+               gc->set_rgb_fg_color(black[i]);
+               get_window()->draw_rectangle(gc, true, i*tile_w, 0, tile_w, tile_h);
+       
+               gc->set_stipple(Gdk::Bitmap::create(hlines,2,2));
+               gc->set_fill(Gdk::STIPPLED);
+               gc->set_rgb_fg_color(white[i]);
+               get_window()->draw_rectangle(gc, true, i*tile_w, 0, tile_w, tile_h);
+       
+               gc->set_fill(Gdk::SOLID);
+               gc->set_rgb_fg_color(gray50[i]);
+       
+               get_window()->draw_rectangle(gc, true, i*tile_w+tile_w/4, tile_h/4, tile_w-tile_w/2, tile_h-tile_h/2);
+       }
+
+       // 25% Pattern
+       for(i=0;i<4;i++)
+       {
+               gc->set_rgb_fg_color(black[i]);
+               get_window()->draw_rectangle(gc, true, i*tile_w, tile_h, tile_w, tile_h);
+       
+               gc->set_stipple(Gdk::Bitmap::create(hlines,2,2));
+               gc->set_fill(Gdk::STIPPLED);
+               gc->set_rgb_fg_color(gray50[i]);
+               get_window()->draw_rectangle(gc, true, i*tile_w, tile_h, tile_w, tile_h);
+       
+               gc->set_fill(Gdk::SOLID);
+               gc->set_rgb_fg_color(gray25[i]);
+       
+               get_window()->draw_rectangle(gc, true, i*tile_w+tile_w/4, tile_h+tile_h/4, tile_w-tile_w/2, tile_h-tile_h/2);
+       }
+
+       // Black-level Pattern
+       gc->set_rgb_fg_color(trueblack);
+       get_window()->draw_rectangle(gc, true, 0, tile_h*2, tile_w*4, tile_h);
+       gc->set_fill(Gdk::SOLID);
+       for(i=0;i<4;i++)
+       {
+               gc->set_rgb_fg_color(black[i]);
+       
+               get_window()->draw_rectangle(gc, true, i*tile_w+tile_w/4, tile_h*2+tile_h/4, tile_w-tile_w/2, tile_h-tile_h/2);
+       }
+
+       return true;
+}
+
+       
+BlackLevelSelector::BlackLevelSelector()
+{
+       set_size_request(-1,24);        
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::BlackLevelSelector::redraw));
+       
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+}
+
+BlackLevelSelector::~BlackLevelSelector()
+{
+}
+
+bool
+BlackLevelSelector::redraw(GdkEventExpose*bleh)
+{
+       const int w(get_width()),h(get_height());
+
+       Gdk::Color color;
+
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+
+       int i;
+       
+       // Draw the gradient
+       for(i=0;i<w;i++)
+       {
+               color.set_rgb(i*65536/w,i*65536/w,i*65536/w);
+               
+               gc->set_rgb_fg_color(color);
+               get_window()->draw_rectangle(gc, true, i, 0, 1, h);
+       }
+               
+       // Draw a frame
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       get_window()->draw_rectangle(gc, false, 0, 0, w-1, h-1);
+
+       // Draw the position of the current value
+       i=(int)(level*w+0.5);
+       gc->set_rgb_fg_color(Gdk::Color("#ff0000"));
+       get_window()->draw_rectangle(gc, true, i, 1, 1, h-1);
+
+       // Print out the value
+       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_pango_context()));         
+       layout->set_text(etl::strprintf("%0.01f%%",level*100.0f));
+       layout->set_alignment(Pango::ALIGN_CENTER);
+       gc->set_rgb_fg_color(Gdk::Color("#a00000"));
+       get_window()->draw_layout(gc, w/2, 4, layout);
+
+       return true;
+}
+
+
+
+bool
+BlackLevelSelector::on_event(GdkEvent *event)
+{
+       int x(round_to_int(event->button.x));
+       //int y(round_to_int(event->button.y));
+
+    switch(event->type)
+    {
+       case GDK_MOTION_NOTIFY:
+               level=(float)x/(float)get_width();
+               if(level<0.0f)level=0.0f;
+               if(level>1.0f)level=1.0f;
+               signal_value_changed_();
+               queue_draw();
+               return true;
+               break;
+       case GDK_BUTTON_PRESS:
+       case GDK_BUTTON_RELEASE:
+               if(event->button.button==1)
+               {
+                       level=(float)x/(float)get_width();
+                       if(level<0.0f)level=0.0f;
+                       if(level>1.0f)level=1.0f;
+                       signal_value_changed_();
+                       queue_draw();
+                       return true;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return false;
+}
+
+
+void
+Dialog_Setup::set_time_format(Time::Format x)
+{
+       time_format=x;
+       if(x<=Time::FORMAT_VIDEO)
+               timestamp_optionmenu.set_history(0);
+       else
+       {
+               if(x==(Time::FORMAT_NOSPACES|Time::FORMAT_FULL))
+                       timestamp_optionmenu.set_history(4);
+               else if(x==(Time::FORMAT_FULL))
+                       timestamp_optionmenu.set_history(3);
+               else if(x==(Time::FORMAT_NOSPACES))
+                       timestamp_optionmenu.set_history(2);
+               else
+                       timestamp_optionmenu.set_history(1);
+       }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RedBlueLevelSelector::RedBlueLevelSelector()
+{
+       set_size_request(-1,24);        
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::RedBlueLevelSelector::redraw));
+       
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+}
+
+RedBlueLevelSelector::~RedBlueLevelSelector()
+{
+}
+
+bool
+RedBlueLevelSelector::redraw(GdkEventExpose*bleh)
+{
+       const int w(get_width()),h(get_height());
+
+       Gdk::Color color;
+
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+
+       int i;
+       
+       // Draw the gradient
+       for(i=0;i<w;i++)
+       {
+               float red_blue(((float(i)/float(w)+0.5f)-1.0f)/2.0f+1.0f);
+               float blue_red(2.0f-(red_blue));
+               if(red_blue>1.0f)red_blue=1.0f;
+               if(blue_red>1.0f)blue_red=1.0f;
+                       
+               color.set_rgb(
+                       round_to_int(min(red_blue,1.0f)*65535),
+                       round_to_int(sqrt(min(red_blue,blue_red))*65535),
+                       round_to_int(min(blue_red,1.0f)*65535)
+               );
+               
+               gc->set_rgb_fg_color(color);
+               get_window()->draw_rectangle(gc, true, i, 0, 1, h);
+       }
+               
+       // Draw a frame
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       get_window()->draw_rectangle(gc, false, 0, 0, w-1, h-1);
+
+       // Draw the position of the current value
+       i=(int)(((level-1.0f)*2.0f+1.0f-0.5f)*w+0.5);
+       gc->set_rgb_fg_color(Gdk::Color("#00ff00"));
+       get_window()->draw_rectangle(gc, true, i, 1, 1, h-1);
+
+       // Print out the value
+       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_pango_context()));         
+       layout->set_text(etl::strprintf("%0.02f",level));
+       layout->set_alignment(Pango::ALIGN_CENTER);
+       gc->set_rgb_fg_color(Gdk::Color("#a00000"));
+       get_window()->draw_layout(gc, w/2, 4, layout);
+
+       return true;
+}
+
+
+
+bool
+RedBlueLevelSelector::on_event(GdkEvent *event)
+{
+       int x(round_to_int(event->button.x));
+       //int y(round_to_int(event->button.y));
+
+    switch(event->type)
+    {
+       case GDK_MOTION_NOTIFY:
+               level=(((float)(x)/(float)get_width()+0.5)-1.0f)/2.0f+1.0f;
+               if(level<0.5f)level=0.5f;
+               if(level>1.5f)level=1.5f;
+               signal_value_changed_();
+               queue_draw();
+               return true;
+               break;
+       case GDK_BUTTON_PRESS:
+       case GDK_BUTTON_RELEASE:
+               if(event->button.button==1)
+               {
+                       level=(((float)(x)/(float)get_width()+0.5)-1.0f)/2.0f+1.0f;
+                       if(level<0.5f)level=0.5f;
+                       if(level>1.5f)level=1.5f;
+                       signal_value_changed_();
+                       queue_draw();
+                       return true;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_setup.h b/synfig-studio/trunk/src/gtkmm/dialog_setup.h
new file mode 100644 (file)
index 0000000..672b6c4
--- /dev/null
@@ -0,0 +1,186 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_setup.h
+**     \brief Template Header
+**
+**     $Id: dialog_setup.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_SETUP_H
+#define __SINFG_STUDIO_DIALOG_SETUP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/checkbutton.h>
+
+#include <sinfg/gamma.h>
+#include <sinfg/time.h>
+#include <algorithm>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; };
+
+namespace studio {
+
+class GammaPattern : public Gtk::DrawingArea
+{
+       float gamma_r;
+       float gamma_g;
+       float gamma_b;
+       float black_level;
+       float red_blue_level;
+
+       int tile_w, tile_h;
+
+       Gdk::Color black[4],white[4],gray50[4],gray25[4];
+
+       float r_F32_to_F32(float x)const { float f((pow(x,gamma_r)*std::min(red_blue_level,1.0f)*(1.0f-black_level)+black_level)); if(f<0)f=0; if(f>1)f=1; return f; }
+       float g_F32_to_F32(float x)const { float f((pow(x,gamma_g)*sqrt(std::min(2.0f-red_blue_level,red_blue_level))*(1.0f-black_level)+black_level)); if(f<0)f=0; if(f>1)f=1; return f; }
+       float b_F32_to_F32(float x)const { float f((pow(x,gamma_b)*std::min(2.0f-red_blue_level,1.0f)*(1.0f-black_level)+black_level)); if(f<0)f=0; if(f>1)f=1; return f; }
+       
+public:
+       
+       void refresh();
+       
+       void set_gamma_r(float x) { gamma_r=x; }
+       void set_gamma_g(float x) { gamma_g=x; };
+       void set_gamma_b(float x) { gamma_b=x; };
+       void set_black_level(float x) { black_level=x; };
+       void set_red_blue_level(float x) { red_blue_level=x; };
+
+       float get_gamma_r()const { return gamma_r; }
+       float get_gamma_g()const { return gamma_g; }
+       float get_gamma_b()const { return gamma_b; }
+       float get_black_level()const { return black_level; }
+       float get_red_blue_level()const { return red_blue_level; }
+       
+       GammaPattern();
+       
+       ~GammaPattern();
+
+       bool redraw(GdkEventExpose*bleh=NULL);
+}; // END of class GammaPattern
+
+class BlackLevelSelector : public Gtk::DrawingArea
+{
+       float level;
+
+       sigc::signal<void> signal_value_changed_;
+
+public:
+       
+       BlackLevelSelector();
+       
+       ~BlackLevelSelector();
+
+       sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+       
+       void set_value(float x) { level=x; queue_draw(); }
+
+       const float &get_value()const { return level; } 
+
+       bool redraw(GdkEventExpose*bleh=NULL);
+
+       bool on_event(GdkEvent *event);
+}; // END of class BlackLevelSelector
+
+class RedBlueLevelSelector : public Gtk::DrawingArea
+{
+       float level;
+
+       sigc::signal<void> signal_value_changed_;
+
+public:
+       
+       RedBlueLevelSelector();
+       
+       ~RedBlueLevelSelector();
+
+       sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+       
+       void set_value(float x) { level=x; queue_draw(); }
+
+       const float &get_value()const { return level; } 
+
+       bool redraw(GdkEventExpose*bleh=NULL);
+
+       bool on_event(GdkEvent *event);
+}; // END of class RedBlueSelector
+
+class Widget_Enum;
+
+class Dialog_Setup : public Gtk::Dialog
+{
+               
+       void on_ok_pressed();
+       void on_apply_pressed();
+
+       void on_gamma_r_change();
+       void on_gamma_g_change();
+       void on_gamma_b_change();
+       void on_black_level_change();
+       void on_red_blue_level_change();
+
+       GammaPattern gamma_pattern;     
+       BlackLevelSelector black_level_selector;
+       RedBlueLevelSelector red_blue_level_selector;
+       Gtk::OptionMenu timestamp_optionmenu;
+       
+       Gtk::Adjustment adj_gamma_r;
+       Gtk::Adjustment adj_gamma_g;
+       Gtk::Adjustment adj_gamma_b;
+
+       Gtk::Adjustment adj_recent_files;
+       Gtk::Adjustment adj_undo_depth;
+
+       Gtk::CheckButton toggle_use_colorspace_gamma;
+
+       sinfg::Time::Format time_format;
+       
+       Gtk::Menu *timestamp_menu;
+       Widget_Enum *widget_enum;
+public:
+
+       void set_time_format(sinfg::Time::Format time_format);
+
+       const sinfg::Time::Format& get_time_format()const { return time_format; }
+       
+       Dialog_Setup();
+       ~Dialog_Setup();
+
+    void refresh();
+
+}; // END of Dialog_Waypoint
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_soundselect.cpp b/synfig-studio/trunk/src/gtkmm/dialog_soundselect.cpp
new file mode 100644 (file)
index 0000000..a207ba6
--- /dev/null
@@ -0,0 +1,97 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: dialog_soundselect.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialog_soundselect.h"
+#include <gtkmm/table.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+studio::Dialog_SoundSelect::Dialog_SoundSelect(Gtk::Window &parent, etl::handle<sinfgapp::CanvasInterface> ci)
+:Dialog(_("Sound Select")),
+okbutton(_("Ok")),
+canvas_interface(ci)
+{
+       Gtk::Table *table = manage(new Gtk::Table);
+
+       table->attach(soundfile,0,1,0,1);
+       table->attach(offset,1,2,0,1);
+       table->attach(okbutton,0,2,1,2);
+       
+       table->show_all();
+       get_vbox()->pack_start(*table);
+       
+       offset.set_value(0);
+       
+       okbutton.signal_clicked().connect(sigc::mem_fun(*this,&Dialog_SoundSelect::on_ok));
+}
+
+studio::Dialog_SoundSelect::~Dialog_SoundSelect()
+{
+}
+
+void studio::Dialog_SoundSelect::on_file()
+{
+       signal_file_changed_(soundfile.get_value());
+}
+
+void studio::Dialog_SoundSelect::on_offset()
+{
+       signal_offset_changed_(offset.get_value());
+}
+
+void studio::Dialog_SoundSelect::on_ok()
+{
+       hide();
+               
+       //signal_finish_(a);
+       signal_file_changed_(soundfile.get_value());
+       signal_offset_changed_(offset.get_value());
+}
+
+void studio::Dialog_SoundSelect::set_global_fps(float f)
+{
+       offset.set_fps(f);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_soundselect.h b/synfig-studio/trunk/src/gtkmm/dialog_soundselect.h
new file mode 100644 (file)
index 0000000..9897bff
--- /dev/null
@@ -0,0 +1,84 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_soundselect.h
+**     \brief Sound Select Header
+**
+**     $Id: dialog_soundselect.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DIALOG_SOUNDSELECT_H
+#define __SINFG_DIALOG_SOUNDSELECT_H
+
+/* === H E A D E R S ======================================================= */
+#include "dockdialog.h"
+#include "widget_filename.h"
+#include "widget_time.h"
+
+#include <sinfgapp/canvasinterface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+struct AudioBaseInfo
+{
+       std::string             file;
+       sinfg::Time             offset;
+};
+       
+class Dialog_SoundSelect : public Gtk::Dialog
+{
+       Widget_Filename         soundfile;
+       Widget_Time                     offset;
+       Gtk::Button                     okbutton;
+       
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface;
+       
+       sigc::signal<void,const std::string &>  signal_file_changed_;
+       sigc::signal<void,const sinfg::Time &>  signal_offset_changed_;
+       
+       void on_file();
+       void on_offset();
+       void on_ok();
+       
+public:
+       Dialog_SoundSelect(Gtk::Window &parent,etl::handle<sinfgapp::CanvasInterface> ci );
+       ~Dialog_SoundSelect();
+
+       //float get_global_fps() const { return globalfps; }
+       void set_global_fps(float f);
+
+       sinfg::Time get_offset() const { return offset.get_value(); }
+       void set_offset(const sinfg::Time &t) {offset.set_value(t); }
+       
+       std::string get_file() const { return soundfile.get_value(); }
+       void set_file(const std::string &f) {soundfile.set_value(f); }
+       
+       sigc::signal<void,const std::string &> &signal_file_changed() { return signal_file_changed_; }
+       sigc::signal<void,const sinfg::Time &> &signal_offset_changed() { return signal_offset_changed_; }
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_tooloptions.cpp b/synfig-studio/trunk/src/gtkmm/dialog_tooloptions.cpp
new file mode 100644 (file)
index 0000000..30bb55d
--- /dev/null
@@ -0,0 +1,98 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_tooloptions.cpp
+**     \brief Template File
+**
+**     $Id: dialog_tooloptions.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include <gtkmm/scrolledwindow.h>
+#include <sinfg/general.h>
+#include "dialog_tooloptions.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_ToolOptions::Dialog_ToolOptions():
+       Dockable("tool_options",_("Tool Options"),Gtk::StockID("sinfg-normal")),
+       empty_label(_("This tool has no options"))
+{
+       //scrolled_.add(sub_vbox_);
+       //scrolled_.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
+       //scrolled_.show();     
+       //get_vbox()->pack_start(scrolled_);
+
+       add(sub_vbox_);
+       
+       set_widget(empty_label);
+       empty_label.show();
+}
+
+Dialog_ToolOptions::~Dialog_ToolOptions()
+{
+}
+
+void
+Dialog_ToolOptions::clear()
+{
+       Dockable::clear();
+       set_local_name(_("Tool Options"));
+       add(sub_vbox_);
+       set_widget(empty_label);
+       empty_label.show();
+
+       set_stock_id(Gtk::StockID("sinfg-normal"));
+}
+
+void
+Dialog_ToolOptions::set_widget(Gtk::Widget&x)
+{
+       if(!sub_vbox_.children().empty())
+               sub_vbox_.children().clear();
+
+       sub_vbox_.show();
+       sub_vbox_.pack_start(x,false,false);
+       x.show();
+}
+
+void
+Dialog_ToolOptions::set_name(const sinfg::String& name)
+{
+       set_stock_id(Gtk::StockID("sinfg-"+name));
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_tooloptions.h b/synfig-studio/trunk/src/gtkmm/dialog_tooloptions.h
new file mode 100644 (file)
index 0000000..9358a5a
--- /dev/null
@@ -0,0 +1,62 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_tooloptions.h
+**     \brief Template Header
+**
+**     $Id: dialog_tooloptions.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_TOOLOPTIONS_H
+#define __SINFG_STUDIO_DIALOG_TOOLOPTIONS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/label.h>
+#include <gtkmm/scrolledwindow.h>
+#include "dockable.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+class Dialog_ToolOptions : public Dockable
+{              
+       Gtk::Label empty_label;
+       Gtk::ScrolledWindow scrolled_;
+       Gtk::VBox sub_vbox_;
+       
+public:
+               
+       void clear();
+       void set_widget(Gtk::Widget&);
+       void set_name(const sinfg::String& name);
+
+       Dialog_ToolOptions();
+       ~Dialog_ToolOptions();
+}; // END of Dialog_ToolOptions
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_waypoint.cpp b/synfig-studio/trunk/src/gtkmm/dialog_waypoint.cpp
new file mode 100644 (file)
index 0000000..4d2da18
--- /dev/null
@@ -0,0 +1,138 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypoint.cpp
+**     \brief Template Header
+**
+**     $Id: dialog_waypoint.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include "dialog_waypoint.h"
+#include <gtk/gtk.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/combo.h>
+#include <ETL/stringf>
+#include "widget_value.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <gtkmm/optionmenu.h>
+#include "widget_time.h"
+#include "widget_waypoint.h"
+
+#endif
+
+using namespace sinfg;
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dialog_Waypoint::Dialog_Waypoint(Gtk::Window& parent,etl::handle<sinfg::Canvas> canvas):
+       Dialog(_("Waypoint Editor"),parent,false,true),
+       canvas(canvas)
+{
+       assert(canvas);
+    waypointwidget=manage(new class Widget_Waypoint(canvas));
+       get_vbox()->pack_start(*waypointwidget);
+
+       Gtk::Button *ok_button(manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))));
+       ok_button->show();
+       add_action_widget(*ok_button,2);
+       ok_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Waypoint::on_ok_pressed));
+
+       Gtk::Button *apply_button(manage(new class Gtk::Button(Gtk::StockID("gtk-apply"))));
+       apply_button->show();
+       add_action_widget(*apply_button,1);
+       apply_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Waypoint::on_apply_pressed));
+
+       Gtk::Button *delete_button(manage(new class Gtk::Button(Gtk::StockID("gtk-delete"))));
+       delete_button->show();
+       add_action_widget(*delete_button,3);
+       delete_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Waypoint::on_delete_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-close"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &Dialog_Waypoint::hide));
+
+       
+       waypointwidget->show_all();
+}
+
+Dialog_Waypoint::~Dialog_Waypoint()
+{
+}
+
+void
+Dialog_Waypoint::on_ok_pressed()
+{
+       hide();
+    signal_changed_();
+}
+
+void
+Dialog_Waypoint::on_apply_pressed()
+{
+    signal_changed_(); 
+}
+
+void
+Dialog_Waypoint::on_delete_pressed()
+{
+       hide();
+    signal_delete_();  
+}
+
+void
+Dialog_Waypoint::set_waypoint(sinfg::ValueNode_Animated::Waypoint x)
+{
+       waypointwidget->set_waypoint(x);
+}
+
+const sinfg::ValueNode_Animated::Waypoint &
+Dialog_Waypoint::get_waypoint()const
+{
+       return waypointwidget->get_waypoint();
+}
+
+void
+Dialog_Waypoint::set_value_desc(sinfgapp::ValueDesc value_desc)
+{
+       value_desc_=value_desc;
+       if(value_desc.get_value_node() && value_desc.get_value_node()->get_parent_canvas())
+               waypointwidget->set_canvas(value_desc.get_value_node()->get_parent_canvas());
+}
+
+void
+Dialog_Waypoint::reset()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialog_waypoint.h b/synfig-studio/trunk/src/gtkmm/dialog_waypoint.h
new file mode 100644 (file)
index 0000000..f8ea8e7
--- /dev/null
@@ -0,0 +1,109 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypoint.h
+**     \brief Template Header
+**
+**     $Id: dialog_waypoint.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_DIALOG_WAYPOINT_H
+#define __SINFG_GTKMM_DIALOG_WAYPOINT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/ruler.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/statusbar.h>
+#include <gtkmm/button.h>
+#include <gtkmm/progressbar.h>
+#include <atkmm/stateset.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/scrollbar.h>
+#include <gtkmm/cellrenderer.h>
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/menu.h>
+
+
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_ValueBase;
+class Widget_Waypoint;
+
+class Dialog_Waypoint : public Gtk::Dialog
+{
+       Widget_Waypoint *waypointwidget;
+       etl::handle<sinfg::Canvas> canvas;
+       sinfg::ValueNode_Animated::WaypointList::iterator waypoint;
+       sinfgapp::ValueDesc value_desc_;
+               
+       sigc::signal<void> signal_changed_;
+
+       sigc::signal<void> signal_delete_;
+       void on_ok_pressed();
+       void on_apply_pressed();
+       void on_delete_pressed();
+
+public:
+       Dialog_Waypoint(Gtk::Window& parent,etl::handle<sinfg::Canvas> canvas);
+       ~Dialog_Waypoint();
+
+    void reset();
+
+       void set_value_desc(sinfgapp::ValueDesc value_desc);
+       sinfgapp::ValueDesc get_value_desc()const { return value_desc_; }
+
+       void set_waypoint(sinfg::ValueNode_Animated::Waypoint x);
+       const sinfg::ValueNode_Animated::Waypoint &get_waypoint()const;
+
+       sigc::signal<void> &signal_changed()
+       {return signal_changed_; }
+
+       sigc::signal<void> &signal_delete()
+       {return signal_delete_; }
+}; // END of Dialog_Waypoint
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dialogsettings.cpp b/synfig-studio/trunk/src/gtkmm/dialogsettings.cpp
new file mode 100644 (file)
index 0000000..260b750
--- /dev/null
@@ -0,0 +1,185 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialogsettings.cpp
+**     \brief Template File
+**
+**     $Id: dialogsettings.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dialogsettings.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+DialogSettings::DialogSettings(Gtk::Window* window,const sinfg::String& name):
+       window(window),
+       name(name)
+{
+       sinfgapp::Main::settings().add_domain(this,"window."+name);
+}
+
+DialogSettings::~DialogSettings()
+{
+       sinfgapp::Main::settings().remove_domain("window."+name);
+}
+
+bool
+DialogSettings::get_value(const sinfg::String& key, sinfg::String& value)const
+{
+       if(key=="pos")
+       {
+               if(!window->is_visible())return false;
+               int x,y; window->get_position(x,y);
+               value=strprintf("%d %d",x,y);
+               return true;
+       }
+       if(key=="size")
+       {
+               if(!window->is_visible())return false;
+               int x,y; window->get_size(x,y);
+               value=strprintf("%d %d",x,y);
+               return true;
+       }
+       if(key=="x")
+       {
+               int x,y; window->get_position(x,y);
+               value=strprintf("%d",x);
+               return true;
+       }
+       if(key=="y")
+       {
+               int x,y; window->get_position(x,y);
+               value=strprintf("%d",y);
+               return true;
+       }
+       if(key=="w")
+       {
+               int x,y; window->get_size(x,y);
+               value=strprintf("%d",x);
+               return true;
+       }
+       if(key=="h")
+       {
+               int x,y; window->get_size(x,y);
+               value=strprintf("%d",y);
+               return true;
+       }
+       if(key=="visible")
+       {
+               value=window->is_visible()?"1":"0";
+               return true;
+       }
+
+       return sinfgapp::Settings::get_value(key,value);
+}
+
+bool
+DialogSettings::set_value(const sinfg::String& key,const sinfg::String& value)
+{
+       if(value.empty())
+               return false;
+       
+       if(key=="pos") 
+       {
+               int x,y;
+               if(!strscanf(value,"%d %d",&x, &y))
+                       return false;
+               window->move(x,y);
+               return true;
+       }
+       if(key=="size") 
+       {
+               int x,y;
+               if(!strscanf(value,"%d %d",&x, &y))
+                       return false;
+               window->set_default_size(x,y);
+               return true;
+       }
+       if(key=="x") 
+       {
+               int x,y; window->get_position(x,y);
+               x=atoi(value.c_str());
+               window->move(x,y);
+               return true;
+       }
+       if(key=="y")
+       {
+               int x,y; window->get_position(x,y);
+               y=atoi(value.c_str());
+               window->move(x,y);
+               return true;
+       }
+       if(key=="w")
+       {
+               int x,y; window->get_size(x,y);
+               x=atoi(value.c_str());
+               window->set_default_size(x,y);
+               return true;
+       }
+       if(key=="h")
+       {
+               int x,y; window->get_size(x,y);
+               y=atoi(value.c_str());
+               window->set_default_size(x,y);
+               return true;
+       }
+       if(key=="visible")
+       {
+               if(value=="0")
+                       window->hide();
+               else
+                       window->present();
+               return true;
+       }
+
+       return sinfgapp::Settings::set_value(key,value);
+}
+
+sinfgapp::Settings::KeyList
+DialogSettings::get_key_list()const
+{
+       sinfgapp::Settings::KeyList ret(sinfgapp::Settings::get_key_list());
+       
+       ret.push_back("size");
+       ret.push_back("pos");
+       ret.push_back("visible");
+       
+       return ret;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dialogsettings.h b/synfig-studio/trunk/src/gtkmm/dialogsettings.h
new file mode 100644 (file)
index 0000000..e32f385
--- /dev/null
@@ -0,0 +1,57 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialogsettings.h
+**     \brief Template Header
+**
+**     $Id: dialogsettings.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DIALOGSETTINGS_H
+#define __SINFG_DIALOGSETTINGS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/settings.h>
+#include <gtkmm/window.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class DialogSettings : public sinfgapp::Settings
+{
+       Gtk::Window* window;
+       sinfg::String name;
+public:
+       DialogSettings(Gtk::Window* window,const sinfg::String& name);
+       virtual ~DialogSettings();
+
+       virtual bool get_value(const sinfg::String& key, sinfg::String& value)const;
+       virtual bool set_value(const sinfg::String& key,const sinfg::String& value);
+       virtual KeyList get_key_list()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_canvases.cpp b/synfig-studio/trunk/src/gtkmm/dock_canvases.cpp
new file mode 100644 (file)
index 0000000..e6c8d01
--- /dev/null
@@ -0,0 +1,248 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_history.cpp
+**     \brief Template File
+**
+**     $Id: dock_canvases.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_canvases.h"
+#include "app.h"
+#include "canvasview.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Canvases::Dock_Canvases():
+       Dockable("canvases",_("Canvas Browser"),Gtk::StockID("sinfg-canvas"))
+{
+
+       App::signal_instance_created().connect(sigc::mem_fun(*this,&studio::Dock_Canvases::new_instance));
+       App::signal_instance_deleted().connect(sigc::mem_fun(*this,&studio::Dock_Canvases::delete_instance));
+       App::signal_instance_selected().connect(sigc::mem_fun(*this,&studio::Dock_Canvases::set_selected_instance_signal));
+
+       
+       add(*create_canvas_tree());
+
+/*
+       add_button(
+               Gtk::StockID("sinfg-canvas_new"),
+               _("Insert a new canvas")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Canvases::menu_new_canvas
+               )
+       );
+
+       add_button(
+               Gtk::StockID("gtk-delete"),
+               _("Remove selected canvas")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Canvases::menu_delete
+               )
+       );
+
+       add_button(
+               Gtk::StockID("sinfg-rename"),
+               _("Rename selected canvas")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Canvases::menu_rename
+               )
+       );
+       */
+}
+
+Dock_Canvases::~Dock_Canvases()
+{
+}
+
+Gtk::Widget*
+Dock_Canvases::create_canvas_tree()
+{
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+       canvas_tree=manage(new class Gtk::TreeView());
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("ID") );
+//             Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+
+               //column->pack_start(*icon_cellrenderer,false);
+               column->pack_start(canvas_tree_model.icon, false); //false = don't expand.
+               column->pack_start(canvas_tree_model.label);
+
+//#ifdef NDEBUG
+//             column->add_attribute(icon_cellrenderer->property_pixbuf(), canvas_tree_model.icon);
+//#endif
+               
+               canvas_tree->append_column(*column);
+       }
+       canvas_tree->set_rules_hint();
+       canvas_tree->signal_row_activated().connect(sigc::mem_fun(*this,&Dock_Canvases::on_row_activate));
+       //canvas_tree->signal_event().connect(sigc::mem_fun(*this,&Dock_Canvases::on_tree_event));
+       canvas_tree->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       canvas_tree->add_events(Gdk::BUTTON1_MOTION_MASK);
+       canvas_tree->show();
+       canvas_tree->set_headers_visible(false);
+       
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*canvas_tree);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show_all();
+
+       return scrolledwindow;
+}
+
+etl::loose_handle<studio::CanvasView>
+Dock_Canvases::get_selected_canvas_view()
+{
+       return get_selected_instance()->find_canvas_view(get_selected_canvas());
+}
+
+etl::loose_handle<sinfg::Canvas>
+Dock_Canvases::get_selected_canvas()
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=canvas_tree->get_selection();
+
+       if(!selection || !selection->get_selected())
+               return 0;
+
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+
+       return static_cast<etl::handle<sinfg::Canvas> >((*selection->get_selected())[canvas_tree_model.canvas]);
+}
+
+
+
+void
+Dock_Canvases::set_selected_instance_signal(etl::handle<studio::Instance> x)
+{
+       set_selected_instance(x);
+}
+
+void
+Dock_Canvases::set_selected_instance_(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       selected_instance=instance;
+       if(instance)
+       {
+               canvas_tree->set_model(instance->canvas_tree_store());
+               canvas_tree->show();
+       }
+       else
+       {
+               canvas_tree->set_model(Glib::RefPtr< Gtk::TreeModel >());
+               canvas_tree->hide();
+       }
+}
+
+void
+Dock_Canvases::set_selected_instance(etl::loose_handle<studio::Instance> x)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       // if it's already selected, don't select it again
+       if (x==selected_instance)
+               return;
+
+       set_selected_instance_(x);      
+}
+
+void
+Dock_Canvases::new_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+       
+       assert(instance);
+       
+       etl::loose_handle<studio::Instance> loose_instance(instance);
+       
+       instance->sinfgapp::Instance::signal_filename_changed().connect(sigc::mem_fun(*this,&Dock_Canvases::refresh_instances));
+       instance->sinfgapp::Instance::signal_filename_changed().connect(
+               sigc::bind<etl::loose_handle<studio::Instance> >(
+                       sigc::mem_fun(*this,&Dock_Canvases::set_selected_instance),
+                       loose_instance
+               )
+       );
+       
+       present();
+       
+}
+
+void
+Dock_Canvases::delete_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       refresh_instances();
+
+       if(selected_instance==instance)
+       {
+               set_selected_instance(0);
+       }
+}
+
+void
+Dock_Canvases::refresh_instances()
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+}
+
+void
+Dock_Canvases::on_row_activate(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *)
+{
+       assert(get_selected_instance());
+       studio::Instance::CanvasTreeModel canvas_tree_model;
+       const Gtk::TreeRow row = *(get_selected_instance()->canvas_tree_store()->get_iter(path));
+       if(row[canvas_tree_model.is_canvas])
+               get_selected_instance()->focus(row[canvas_tree_model.canvas]);
+       else
+               studio::App::dialog_not_implemented();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_canvases.h b/synfig-studio/trunk/src/gtkmm/dock_canvases.h
new file mode 100644 (file)
index 0000000..1380167
--- /dev/null
@@ -0,0 +1,87 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_canvases.h
+**     \brief Template Header
+**
+**     $Id: dock_canvases.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_CANVASES_H
+#define __SINFG_STUDIO_DIALOG_CANVASES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_Canvases : public Dockable
+{      
+       Gtk::TreeView *canvas_tree;
+       //Gtk::Menu     menu;
+       etl::loose_handle<studio::Instance>     selected_instance;
+
+private:
+       
+       void set_selected_instance_(etl::handle<studio::Instance> x);
+
+       etl::loose_handle<studio::Instance> get_selected_instance() { return selected_instance; }
+
+       etl::loose_handle<sinfg::Canvas> get_selected_canvas();
+
+       etl::loose_handle<studio::CanvasView> get_selected_canvas_view();
+
+       void set_selected_instance(etl::loose_handle<studio::Instance> x);
+
+       void set_selected_instance_signal(etl::handle<studio::Instance> x);
+
+       void new_instance(etl::handle<studio::Instance> x);
+
+       void delete_instance(etl::handle<studio::Instance> x);
+
+       void refresh_instances();
+
+       bool close();
+       
+       void on_row_activate(const Gtk::TreeModel::Path &path, Gtk::TreeViewColumn *);
+       //bool on_tree_event(GdkEvent *event);
+
+
+
+       void on_action_toggle(const Glib::ustring& path);
+       Gtk::Widget* create_canvas_tree();
+
+public:
+
+       Dock_Canvases();
+       ~Dock_Canvases();
+}; // END of Dock_Canvases
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_canvasspecific.cpp b/synfig-studio/trunk/src/gtkmm/dock_canvasspecific.cpp
new file mode 100644 (file)
index 0000000..e22501d
--- /dev/null
@@ -0,0 +1,172 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_canvasspecific.cpp
+**     \brief Template File
+**
+**     $Id: dock_canvasspecific.cpp,v 1.3 2005/01/13 20:23:01 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "app.h"
+#include "dock_canvasspecific.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/adaptors/hide.h>
+//#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "metadatatreestore.h"
+#include "canvasview.h"
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_CanvasSpecific::Dock_CanvasSpecific(const sinfg::String& name,const sinfg::String& local_name,Gtk::StockID stock_id_):
+       Dockable(name,local_name,stock_id_)
+{
+       App::signal_instance_created().connect(sigc::mem_fun(*this,&Dock_CanvasSpecific::init_instance));
+}
+
+Dock_CanvasSpecific::~Dock_CanvasSpecific()
+{
+}
+
+etl::loose_handle<studio::CanvasView>
+Dock_CanvasSpecific::get_canvas_view()
+{
+       return App::get_selected_canvas_view();
+}
+
+etl::loose_handle<sinfgapp::CanvasInterface>
+Dock_CanvasSpecific::get_canvas_interface()
+{
+       if(get_canvas_view())
+               return get_canvas_view()->canvas_interface();
+       return 0;
+}
+
+void
+Dock_CanvasSpecific::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+}
+
+void
+Dock_CanvasSpecific::init_instance_vfunc(etl::loose_handle<Instance> instance)
+{
+}
+
+void
+Dock_CanvasSpecific::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+}
+
+void
+Dock_CanvasSpecific::init_instance(etl::handle<Instance> instance)
+{
+       etl::clock timer;timer.reset();
+       instance->signal_canvas_view_created().connect(sigc::mem_fun(*this,&Dock_CanvasSpecific::init_canvas_view));
+       init_instance_vfunc(instance);
+       sinfg::info("%s init_instance() took %f seconds",get_local_name().c_str(),float(timer()));
+}
+
+void
+Dock_CanvasSpecific::delete_instance(etl::handle<Instance> instance)
+{
+       changed_canvas_view_vfunc(0);
+}
+
+void
+Dock_CanvasSpecific::init_canvas_view(CanvasView* canvas_view)
+{
+       /*
+       canvas_view->signal_focus_in_event().connect(
+               sigc::hide(
+                       sigc::bind_return(
+                               sigc::mem_fun(
+                                       *this,
+                                       &Dock_CanvasSpecific::canvas_view_changed
+                               ),
+                               false
+                       )
+               )       
+       );
+       */
+       sinfg::info("%s init_canvas_view() Starting init...",get_local_name().c_str());
+       etl::clock timer;timer.reset();
+       App::signal_canvas_view_focus().connect(
+               sigc::hide(
+                       sigc::mem_fun(
+                               *this,
+                               &Dock_CanvasSpecific::canvas_view_changed
+                       )
+               )
+       );
+       init_canvas_view_vfunc(canvas_view);
+       sinfg::info("%s init_canvas_view() took %f seconds",get_local_name().c_str(),float(timer()));
+}
+
+void
+Dock_CanvasSpecific::canvas_view_changed()
+{
+       etl::loose_handle<CanvasView> canvas_view(App::get_selected_canvas_view());
+/*     if(canvas_view)
+       {
+               canvas_delete_connection.disconnect();
+               canvas_delete_connection=canvas_view->signal_deleted().connect(
+                       sigc::bind(
+                               sigc::mem_fun(
+                                       *this,
+                                       &Dock_CanvasSpecific::changed_canvas_view
+                               ),
+                               etl::loose_handle<CanvasView>(0)
+                       )
+               );
+       }
+*/
+       
+#ifdef _DEBUG
+       sinfg::info("%s canvas_view_changed: start",get_local_name().c_str());
+#endif
+       changed_canvas_view_vfunc(canvas_view);
+#ifdef _DEBUG
+       sinfg::info("%s canvas_view_changed: end",get_local_name().c_str());
+#endif
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_canvasspecific.h b/synfig-studio/trunk/src/gtkmm/dock_canvasspecific.h
new file mode 100644 (file)
index 0000000..542ac28
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_canvasspecific.h
+**     \brief Template Header
+**
+**     $Id: dock_canvasspecific.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_CANVASSPECIFIC_H
+#define __SINFG_STUDIO_DOCK_CANVASSPECIFIC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CanvasView;
+class Instance;
+       
+class Dock_CanvasSpecific : public Dockable
+{              
+       SigC::Connection canvas_delete_connection;
+protected:
+       virtual void init_instance_vfunc(etl::loose_handle<Instance> instance);
+
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+private:
+       void init_canvas_view(CanvasView* canvas_view);
+       void init_instance(etl::handle<Instance> instance);
+       void delete_instance(etl::handle<Instance> instance);
+       void canvas_view_changed();
+       void changed_canvas_view(etl::loose_handle<CanvasView> canvas_view) { return changed_canvas_view_vfunc(canvas_view); }
+public:
+
+       etl::loose_handle<studio::CanvasView> get_canvas_view();
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface();
+
+       Dock_CanvasSpecific(const sinfg::String& name,const sinfg::String& local_name,Gtk::StockID stock_id_=Gtk::StockID(" "));
+       virtual ~Dock_CanvasSpecific();
+}; // END of Dock_CanvasSpecific
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_children.cpp b/synfig-studio/trunk/src/gtkmm/dock_children.cpp
new file mode 100644 (file)
index 0000000..2f1fc1c
--- /dev/null
@@ -0,0 +1,112 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_children.cpp
+**     \brief Template File
+**
+**     $Id: dock_children.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_children.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/slot.h>
+#include "childrentreestore.h"
+#include "childrentree.h"
+#include "canvasview.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Children::Dock_Children():
+       Dock_CanvasSpecific("children",_("Children"),Gtk::StockID("sinfg-children"))
+{
+       set_use_scrolled(false);
+/*
+       add(*create_action_tree());
+
+       add_button(
+               Gtk::StockID("sinfg-clear_redo"),
+               _("Clear the REDO Stack")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Children::clear_redo
+               )
+       );
+*/
+}
+
+Dock_Children::~Dock_Children()
+{
+}
+
+void
+Dock_Children::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       Glib::RefPtr<ChildrenTreeStore> children_tree_store;
+       children_tree_store=ChildrenTreeStore::create(canvas_view->canvas_interface());
+
+       ChildrenTree* children_tree(new ChildrenTree());
+       children_tree->set_model(children_tree_store);
+       children_tree->set_time_adjustment(canvas_view->time_adjustment());
+
+       
+       canvas_view->set_tree_model(get_name(),children_tree_store);
+       canvas_view->set_ext_widget(get_name(),children_tree);
+}
+
+void
+Dock_Children::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               Gtk::Widget* tree_view(canvas_view->get_ext_widget(get_name()));
+       
+               add(*tree_view);
+               tree_view->show();
+       }
+       else clear_previous();
+
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_children.h b/synfig-studio/trunk/src/gtkmm/dock_children.h
new file mode 100644 (file)
index 0000000..5402900
--- /dev/null
@@ -0,0 +1,59 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_children.h
+**     \brief Template Header
+**
+**     $Id: dock_children.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_CHILDREN_H
+#define __SINFG_STUDIO_DOCK_CHILDREN_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_Children : public Dock_CanvasSpecific
+{      
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+public:
+
+
+       Dock_Children();
+       ~Dock_Children();
+}; // END of Dock_Children
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_curves.cpp b/synfig-studio/trunk/src/gtkmm/dock_curves.cpp
new file mode 100644 (file)
index 0000000..bdd17e6
--- /dev/null
@@ -0,0 +1,195 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_params.cpp
+**     \brief Template File
+**
+**     $Id: dock_curves.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_curves.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "canvasview.h"
+#include "layerparamtreestore.h"
+#include "workarea.h"
+#include "widget_curves.h"
+#include "layerparamtreestore.h"
+#include <gtkmm/table.h>
+#include <gtkmm/scrollbar.h>
+#include "widget_timeslider.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Curves::Dock_Curves():
+       Dock_CanvasSpecific("curves",_("Curves"),Gtk::StockID("sinfg-curves"))
+{
+       last_widget_curves_=0;
+       table_=0;
+       
+       hscrollbar_=new Gtk::HScrollbar();
+       vscrollbar_=new Gtk::VScrollbar();
+       widget_timeslider_= new Widget_Timeslider();
+}
+
+Dock_Curves::~Dock_Curves()
+{
+       if(table_)delete table_;
+       delete hscrollbar_;
+       delete vscrollbar_;
+       delete widget_timeslider_;
+}
+
+static void
+_curve_selection_changed(Gtk::TreeView* param_tree_view,Widget_Curves* curves)
+{
+       LayerParamTreeStore::Model model;
+       Gtk::TreeIter iter;
+       if(!param_tree_view->get_selection()->count_selected_rows())
+       {
+               curves->clear();
+               return;
+       }
+       
+       std::list<sinfgapp::ValueDesc> value_descs;
+
+       //std::list<Gtk::TreePath> path_list(
+       //param_tree_view->get_selection()->selected_foreach_iter(tmp);
+       iter=param_tree_view->get_selection()->get_selected();
+       
+       value_descs.push_back((*iter)[model.value_desc]);
+       curves->set_value_descs(value_descs);
+       
+       //curves->set_value_descs(tmp.value_descs);     
+}
+
+void
+Dock_Curves::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       Widget_Curves* curves(new Widget_Curves());
+       curves->set_time_adjustment(canvas_view->time_adjustment());
+       
+       Gtk::TreeView* param_tree_view(
+               static_cast<Gtk::TreeView*>(canvas_view->get_ext_widget("params"))
+       );
+       
+       param_tree_view->get_selection()->signal_changed().connect(
+               sigc::bind(
+                       sigc::bind(
+                               sigc::ptr_fun(
+                                       _curve_selection_changed
+                               ),curves
+                       ),param_tree_view
+               )
+       );
+       
+       canvas_view->set_ext_widget(get_name(),curves);
+}
+
+void
+Dock_Curves::refresh_selected_param()
+{
+/*     Gtk::TreeView* tree_view(
+               static_cast<Gtk::TreeView*>(get_canvas_view()->get_ext_widget(get_name()))
+       );
+       Gtk::TreeModel::iterator iter(tree_view->get_selection()->get_selected());
+       
+       if(iter)
+       {
+               LayerParamTreeStore::Model model;
+               get_canvas_view()->work_area->set_selected_value_node(
+                       (sinfg::ValueNode::Handle)(*iter)[model.value_node]
+               );
+       }
+       else
+       {
+               get_canvas_view()->work_area->set_selected_value_node(0);
+       }
+*/
+}
+
+void
+Dock_Curves::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(table_)
+       {
+               table_->hide();
+               delete table_;
+               hscrollbar_->unset_adjustment();
+               vscrollbar_->unset_adjustment();
+               //widget_timeslider_->unset_adjustment();
+               table_=0;
+       }
+
+       
+       if(canvas_view)
+       {
+               last_widget_curves_=dynamic_cast<Widget_Curves*>(
+                       canvas_view->get_ext_widget(get_name())
+               );
+
+               vscrollbar_->set_adjustment(last_widget_curves_->get_range_adjustment());
+               hscrollbar_->set_adjustment(canvas_view->time_window_adjustment());
+               widget_timeslider_->set_time_adjustment(&canvas_view->time_adjustment());
+               widget_timeslider_->set_bounds_adjustment(&canvas_view->time_window_adjustment());
+               widget_timeslider_->set_global_fps(canvas_view->get_canvas()->rend_desc().get_frame_rate());
+
+               table_=new Gtk::Table(2,2);
+               table_->attach(*widget_timeslider_, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK);
+               table_->attach(*last_widget_curves_, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+               table_->attach(*hscrollbar_, 0, 1, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK);
+               table_->attach(*vscrollbar_, 1, 2, 0, 2, Gtk::FILL|Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
+               add(*table_);
+               
+               //add(*last_widget_curves_);
+               last_widget_curves_->show();
+               table_->show_all();
+               show_all();
+       }
+       else
+       {
+               //clear_previous();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_curves.h b/synfig-studio/trunk/src/gtkmm/dock_curves.h
new file mode 100644 (file)
index 0000000..234747b
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_curves.h
+**     \brief Template Header
+**
+**     $Id: dock_curves.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_CURVES_H
+#define __SINFG_STUDIO_DOCK_CURVES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Table; class HScrollbar; class VScrollbar; };
+
+namespace studio {
+
+class Widget_Curves;
+class Widget_Timeslider;
+       
+class Dock_Curves : public Dock_CanvasSpecific
+{      
+       Gtk::Table* table_;
+       Gtk::HScrollbar* hscrollbar_;
+       Gtk::VScrollbar* vscrollbar_;
+       
+       Widget_Timeslider* widget_timeslider_;
+       Widget_Curves* last_widget_curves_;
+       
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+       void refresh_selected_param();
+
+public:
+
+
+       Dock_Curves();
+       ~Dock_Curves();
+}; // END of Dock_Keyframes
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_history.cpp b/synfig-studio/trunk/src/gtkmm/dock_history.cpp
new file mode 100644 (file)
index 0000000..dde2718
--- /dev/null
@@ -0,0 +1,405 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_history.cpp
+**     \brief Template File
+**
+**     $Id: dock_history.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_history.h"
+#include "app.h"
+
+
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include <sinfgapp/action.h>
+#include "historytreestore.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+#define COLUMNID_JUMP          (787584)
+#define ColumnID       int
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_History::Dock_History():
+       Dock_CanvasSpecific("history",_("History"),Gtk::StockID("gtk-undo")),
+       action_group(Gtk::ActionGroup::create())
+{
+       App::signal_instance_deleted().connect(sigc::mem_fun(*this,&studio::Dock_History::delete_instance));
+       App::signal_instance_selected().connect(sigc::mem_fun(*this,&studio::Dock_History::set_selected_instance_signal));
+       
+       action_group->add(Gtk::Action::create(
+               "clear-undo",
+               Gtk::StockID("sinfg-clear_undo"),
+               _("Clear the UNDO Stack"),
+               _("Clear the UNDO Stack")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &Dock_History::clear_undo
+               )
+       );
+       action_group->add(Gtk::Action::create(
+               "clear-redo",
+               Gtk::StockID("sinfg-clear_redo"),
+               _("Clear the REDO Stack"),
+               _("Clear the REDO Stack")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &Dock_History::clear_redo
+               )
+       );
+       action_group->add(Gtk::Action::create(
+               "undo",
+               Gtk::StockID("gtk-undo"),
+               _("Undo previous action"),
+               _("Undo previous action")
+       ),
+               sigc::ptr_fun(studio::App::undo)        
+       );
+       action_group->add(Gtk::Action::create(
+               "redo",
+               Gtk::StockID("gtk-redo"),
+               _("Redo previous action"),
+               _("Redo previous action")
+       ),
+               sigc::ptr_fun(studio::App::redo)        
+       );
+
+       action_group->add( Gtk::Action::create("toolbar-history", "History") );
+       App::ui_manager()->insert_action_group(action_group);
+
+       Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-history'>"
+       "       <toolitem action='undo' />"
+       "       <toolitem action='clear-undo' />"
+       "       <toolitem action='clear-redo' />"
+       "       <toolitem action='redo' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       action_group->set_sensitive(false);
+
+       set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-history")));   
+       add(*create_action_tree());
+       
+       /*
+       add_button(
+               Gtk::StockID("sinfg-clear_undo"),
+               _("Clear the UNDO Stack")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_History::clear_undo
+               )
+       );
+       add_button(
+               Gtk::StockID("sinfg-clear_redo"),
+               _("Clear the REDO Stack")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_History::clear_redo
+               )
+       );
+       */
+}
+
+Dock_History::~Dock_History()
+{
+}
+
+void
+Dock_History::init_instance_vfunc(etl::loose_handle<Instance> instance)
+{
+       instance->signal_undo_redo_status_changed().connect(
+               sigc::mem_fun(*this,&Dock_History::update_undo_redo)
+       );
+}
+
+Gtk::Widget*
+Dock_History::create_action_tree()
+{
+       studio::HistoryTreeStore::Model history_tree_model;
+       action_tree=manage(new class Gtk::TreeView());
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("") );
+
+               Gtk::CellRendererToggle* toggle_cr = Gtk::manage( new Gtk::CellRendererToggle() );
+               toggle_cr->signal_toggled().connect(sigc::mem_fun(*this, &studio::Dock_History::on_action_toggle) );
+               
+               column->pack_start(*toggle_cr); //false = don't expand.
+               column->add_attribute(toggle_cr->property_active(),history_tree_model.is_active);
+               column->set_resizable();
+               column->set_clickable();
+                               
+               action_tree->append_column(*column);
+       }
+       /*{
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("Canvas") );
+               Gtk::CellRendererText *text_cr=Gtk::manage(new Gtk::CellRendererText());
+               text_cr->property_foreground()=Glib::ustring("#7f7f7f");
+               
+               column->pack_start(*text_cr);
+               column->add_attribute(text_cr->property_text(),history_tree_model.canvas_id);
+               column->add_attribute(text_cr->property_foreground_set(),history_tree_model.is_redo);
+                               
+               action_tree->append_column(*column);
+       }*/
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
+
+               Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_jump,true);
+               
+               cell_renderer_jump->property_text()="(JMP)";
+               cell_renderer_jump->property_foreground()="#003a7f";
+               
+               column->set_resizable();
+               column->set_clickable();
+               
+               column->set_sort_column_id(COLUMNID_JUMP);
+
+               action_tree->append_column(*column);
+               //column->clicked();
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column("Action") );
+
+               Gtk::CellRendererText *text_cr=Gtk::manage(new Gtk::CellRendererText());
+               text_cr->property_foreground()=Glib::ustring("#7f7f7f");
+
+               
+
+               //column->pack_start(history_tree_model.icon, false); //false = don't expand.
+               column->pack_start(*text_cr);
+               column->add_attribute(text_cr->property_text(),history_tree_model.name);
+               column->add_attribute(text_cr->property_foreground_set(),history_tree_model.is_redo);
+                               
+               action_tree->append_column(*column);
+       }
+
+       
+       action_tree->set_rules_hint();
+//     action_tree->signal_row_activated().connect(sigc::mem_fun(*this,&Dock_History::on_row_activate));
+       action_tree->signal_event().connect(sigc::mem_fun(*this,&Dock_History::on_action_event));
+//     action_tree->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+//     action_tree->add_events(Gdk::BUTTON1_MOTION_MASK);
+       action_tree->show();
+
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*action_tree);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show_all();
+
+/*     {
+               Gtk::Widget& widget(*action_tree);
+               Pango::FontDescription font(widget.get_modifier_style()->get_font());
+               font.set_size(Pango::SCALE*5);
+               widget.get_modifier_style()->set_font(font);
+               widget.modify_font(font);
+       }
+*/
+       return scrolledwindow;
+}
+
+void
+Dock_History::clear_undo()
+{
+       if(selected_instance && App::dialog_yes_no(_("Clear History"), _("You will not be able to undo any changes that you have made!\nAre you sure you want to clear the undo stack?")))
+       {               
+               selected_instance->clear_undo_stack();
+       }
+}
+
+void
+Dock_History::clear_redo()
+{
+       if(selected_instance && App::dialog_yes_no(_("Clear History"), _("You will not be able to redo any changes that you have made!\nAre you sure you want to clear the redo stack?")))
+       {               
+               selected_instance->clear_redo_stack();
+       }
+}
+
+void
+Dock_History::update_undo_redo()
+{
+       etl::handle<Instance> instance=App::get_selected_instance();
+       if(instance)
+       {
+               action_group->get_action("undo")->set_sensitive(instance->get_undo_status());
+               action_group->get_action("clear-undo")->set_sensitive(instance->get_undo_status());
+               action_group->get_action("redo")->set_sensitive(instance->get_redo_status());
+               action_group->get_action("clear-redo")->set_sensitive(instance->get_redo_status());
+       }
+}
+
+void
+Dock_History::set_selected_instance_(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       selected_instance=instance;
+       if(instance)
+       {
+               action_tree->set_model(instance->history_tree_store());
+               action_tree->show();
+               update_undo_redo();
+               action_group->set_sensitive(true);
+       }
+       else
+       {
+               action_tree->set_model(Glib::RefPtr< Gtk::TreeModel >());
+               action_tree->hide();
+               action_group->set_sensitive(false);
+       }
+}
+
+void
+Dock_History::set_selected_instance_signal(etl::handle<studio::Instance> x)
+{
+       set_selected_instance(x);
+}
+
+void
+Dock_History::set_selected_instance(etl::loose_handle<studio::Instance> x)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       // if it's already selected, don't select it again
+       if (x==selected_instance)
+               return;
+
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+
+       set_selected_instance_(x);      
+}
+
+void
+Dock_History::delete_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       if(selected_instance==instance)
+       {
+               set_selected_instance(0);
+       }
+}
+
+bool
+Dock_History::on_action_event(GdkEvent *event)
+{
+       studio::HistoryTreeStore::Model model;
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!action_tree->get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(action_tree->get_model()->get_iter(path));
+                       
+                       //signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               etl::handle<sinfgapp::Action::Undoable> action(row[model.action]);
+                               try{
+                               if((bool)row[model.is_undo])
+                               {
+                                       while(get_selected_instance()->undo_action_stack().size() && get_selected_instance()->undo_action_stack().front()!=action)
+                                               if(get_selected_instance()->undo()==false)
+                                                       throw int();
+                               }
+                               else if((bool)row[model.is_redo])
+                               {
+                                       while(get_selected_instance()->redo_action_stack().size() && get_selected_instance()->undo_action_stack().front()!=action)
+                                               if(get_selected_instance()->redo()==false)
+                                                       throw int();
+                               }
+                               }
+                               catch(int)
+                               {
+                                       return true;
+                               }
+                       }
+               }
+               
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+void
+Dock_History::on_action_toggle(const Glib::ustring& path_string)
+{
+       studio::HistoryTreeStore::Model history_tree_model;
+
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(selected_instance->history_tree_store()->get_iter(path));
+
+       handle<sinfgapp::Action::Undoable> action=row[history_tree_model.action];
+       
+       selected_instance->sinfgapp::Instance::set_action_status(action,!action->is_active());
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_history.h b/synfig-studio/trunk/src/gtkmm/dock_history.h
new file mode 100644 (file)
index 0000000..495dd59
--- /dev/null
@@ -0,0 +1,83 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_history.h
+**     \brief Template Header
+**
+**     $Id: dock_history.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DIALOG_HISTORY_H
+#define __SINFG_STUDIO_DIALOG_HISTORY_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include <gtkmm/actiongroup.h>
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_History : public Dock_CanvasSpecific
+{      
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+       Gtk::TreeView *action_tree;
+
+       etl::loose_handle<studio::Instance>     selected_instance;
+       void set_selected_instance_(etl::handle<studio::Instance> x);
+
+
+       void set_selected_instance(etl::loose_handle<studio::Instance> x);
+
+       void set_selected_instance_signal(etl::handle<studio::Instance> x);
+
+       void delete_instance(etl::handle<studio::Instance> x);
+
+       Gtk::Widget* create_action_tree();
+
+public:
+
+       etl::loose_handle<studio::Instance> get_selected_instance() { return selected_instance; }
+
+       void clear_undo();
+       void clear_redo();
+
+       bool on_action_event(GdkEvent *event);
+       void on_action_toggle(const Glib::ustring& path);
+
+       void update_undo_redo();
+       
+       Dock_History();
+       ~Dock_History();
+protected:
+       virtual void init_instance_vfunc(etl::loose_handle<Instance> instance);
+
+}; // END of Dock_History
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_info.cpp b/synfig-studio/trunk/src/gtkmm/dock_info.cpp
new file mode 100644 (file)
index 0000000..d5b8063
--- /dev/null
@@ -0,0 +1,143 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_info.cpp
+**     \brief Dock Info File
+**
+**     $Id: dock_info.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_info.h"
+#include "canvasview.h"
+#include "workarea.h"
+
+#include <sinfg/canvas.h>
+#include <sinfg/context.h>
+
+#include <gtkmm/separator.h>
+#include <gtkmm/invisible.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+#define use_colorspace_gamma() App::use_colorspace_gamma
+#define colorspace_gamma()     (2.2f)
+#define gamma_in(x)            ((x>=0)?pow((float)x,1.0f/colorspace_gamma()):-pow((float)-x,1.0f/colorspace_gamma()))
+#define gamma_out(x)   ((x>=0)?pow((float)x,colorspace_gamma()):-pow((float)-x,colorspace_gamma()))
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+void studio::Dock_Info::on_mouse_move()
+{
+       Point pos = get_canvas_view()->work_area->get_cursor_pos();
+       
+       Distance xv(pos[0],Distance::SYSTEM_UNITS); 
+       xv.convert(App::distance_system, get_canvas_view()->get_canvas()->rend_desc());
+       
+       Distance yv(pos[1],Distance::SYSTEM_UNITS); 
+       yv.convert(App::distance_system, get_canvas_view()->get_canvas()->rend_desc());
+       
+       //get the color and set the labels
+       
+       x.set_text(xv.get_string(3));   
+       y.set_text(yv.get_string(3));
+       
+       Color c = get_canvas_view()->get_canvas()->get_context().get_color(pos);
+       float cr = c.get_r(),cg = c.get_g(), cb = c.get_b();
+       
+       if(use_colorspace_gamma())
+       {
+               cr = gamma_in(cr);
+               cg = gamma_in(cg);
+               cb = gamma_in(cb);              
+       }
+       
+       r.set_text(strprintf("%.1f%%",cr*100));
+       g.set_text(strprintf("%.1f%%",cg*100));
+       b.set_text(strprintf("%.1f%%",cb*100));
+       a.set_text(strprintf("%.1f%%",c.get_a()*100));
+}
+
+studio::Dock_Info::Dock_Info()
+:Dock_CanvasSpecific("info",_("Info"),Gtk::StockID("sinfg-info"))
+{
+       set_use_scrolled(false);
+       
+       Gtk::Table *table = manage(new Gtk::Table);
+       
+       //pos labels
+       table->attach(*manage(new Gtk::Label(_("X: "))),0,1,0,2,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(*manage(new Gtk::Label(_("Y: "))),0,1,2,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //pos
+       table->attach(x,1,2,0,2,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(y,1,2,2,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //seperator
+       table->attach(*manage(new Gtk::VSeparator),2,3,0,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //color label
+       table->attach(*manage(new Gtk::Label(_("R: "))),3,4,0,1,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(*manage(new Gtk::Label(_("G: "))),3,4,1,2,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(*manage(new Gtk::Label(_("B: "))),3,4,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(*manage(new Gtk::Label(_("A: "))),3,4,3,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //color
+       table->attach(r,4,5,0,1,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(g,4,5,1,2,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(b,4,5,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       table->attach(a,4,5,3,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       table->attach(*manage(new Gtk::Label),0,5,4,5);
+       
+       table->show_all();
+       
+       add(*table);
+}
+
+studio::Dock_Info::~Dock_Info()
+{
+}
+
+void studio::Dock_Info::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       mousecon.disconnect();
+       
+       if(canvas_view && canvas_view->get_work_area())
+       {
+               mousecon = get_canvas_view()->work_area->signal_cursor_moved().connect(sigc::mem_fun(*this,&Dock_Info::on_mouse_move));
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_info.h b/synfig-studio/trunk/src/gtkmm/dock_info.h
new file mode 100644 (file)
index 0000000..2d2cc5b
--- /dev/null
@@ -0,0 +1,64 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_info.h
+**     \brief Info Dock Header
+**
+**     $Id: dock_info.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DOCK_INFO_H
+#define __SINFG_DOCK_INFO_H
+
+/* === H E A D E R S ======================================================= */
+#include "dock_canvasspecific.h"
+#include "sigc++/signal.h"
+
+#include "widget_distance.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_Info : public Dock_CanvasSpecific
+{
+       //bool                  valid;
+       //sinfg::Point  pos;
+       
+       Gtk::Label  r,g,b,a;
+       Gtk::Label      x,y;
+       
+       SigC::Connection mousecon;      
+       
+       void on_mouse_move();   
+               
+public:
+       Dock_Info();
+       ~Dock_Info();
+
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_keyframes.cpp b/synfig-studio/trunk/src/gtkmm/dock_keyframes.cpp
new file mode 100644 (file)
index 0000000..2733c04
--- /dev/null
@@ -0,0 +1,187 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_keyframes.cpp
+**     \brief Template File
+**
+**     $Id: dock_keyframes.cpp,v 1.3 2005/01/13 20:23:01 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_keyframes.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "keyframetreestore.h"
+#include "keyframetree.h"
+#include "canvasview.h"
+#include "keyframeactionmanager.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Keyframes::Dock_Keyframes():
+       Dock_CanvasSpecific("keyframes",_("Keyframes"),Gtk::StockID("sinfg-keyframes")),
+       action_group(Gtk::ActionGroup::create()),
+       keyframe_action_manager(new KeyframeActionManager)
+{
+       keyframe_action_manager->set_ui_manager(App::ui_manager());
+       keyframe_action_manager->signal_show_keyframe_properties().connect(
+               sigc::mem_fun(*this,&Dock_Keyframes::show_keyframe_properties)
+       );
+/*     add_button(
+               Gtk::StockID("gtk-add"),
+               _("Inserts a Keyframe at the current time")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Keyframes::add_keyframe_pressed
+               )
+       );
+
+       add_button(
+               Gtk::StockID("sinfg-duplicate"),
+               _("Duplicates the selected keyframe at the current time")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Keyframes::duplicate_keyframe_pressed
+               )
+       );
+
+       add_button(
+               Gtk::StockID("gtk-delete"),
+               _("Deletes the selected Keyframe")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_Keyframes::delete_keyframe_pressed
+               )
+       );
+*/
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-keyframe'>"
+       "       <toolitem action='action-keyframe_add' />"
+       "       <toolitem action='action-keyframe_duplicate' />"
+       "       <toolitem action='action-keyframe_remove' />"
+       "       <toolitem action='keyframe-properties' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-keyframe")));  
+}
+
+Dock_Keyframes::~Dock_Keyframes()
+{
+}
+
+void
+Dock_Keyframes::show_keyframe_properties()
+{
+       if(get_canvas_view())
+               get_canvas_view()->show_keyframe_dialog();
+}
+
+/*
+void
+Dock_Keyframes::add_keyframe_pressed()
+{
+       if(get_canvas_view())
+               get_canvas_view()->on_keyframe_add_pressed();
+}
+
+void
+Dock_Keyframes::duplicate_keyframe_pressed()
+{
+       if(get_canvas_view())
+               get_canvas_view()->on_keyframe_duplicate_pressed();
+}
+
+void
+Dock_Keyframes::delete_keyframe_pressed()
+{
+       if(get_canvas_view())
+               get_canvas_view()->on_keyframe_remove_pressed();
+}
+*/
+
+void
+Dock_Keyframes::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store;
+       keyframe_tree_store=KeyframeTreeStore::create(canvas_view->canvas_interface());
+
+       KeyframeTree* keyframe_tree(new KeyframeTree());
+       keyframe_tree->set_model(keyframe_tree_store);
+       keyframe_tree->set_editable(true);
+
+       canvas_view->set_tree_model(get_name(),keyframe_tree_store);
+       canvas_view->set_ext_widget(get_name(),keyframe_tree);
+}
+
+void
+Dock_Keyframes::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               Gtk::Widget* tree_view(canvas_view->get_ext_widget(get_name()));
+       
+               add(*tree_view);
+               tree_view->show();
+               
+               keyframe_action_manager->set_keyframe_tree(dynamic_cast<KeyframeTree*>(canvas_view->get_ext_widget(get_name())));
+               keyframe_action_manager->set_canvas_interface(canvas_view->canvas_interface());
+               keyframe_action_manager->refresh();
+       }
+       else
+       {
+               clear_previous();
+               
+               keyframe_action_manager->set_keyframe_tree(0);
+               keyframe_action_manager->set_canvas_interface(0);
+               keyframe_action_manager->refresh();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_keyframes.h b/synfig-studio/trunk/src/gtkmm/dock_keyframes.h
new file mode 100644 (file)
index 0000000..30ac815
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_keyframes.h
+**     \brief Template Header
+**
+**     $Id: dock_keyframes.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_KEYFRAMES_H
+#define __SINFG_STUDIO_DOCK_KEYFRAMES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include "dock_canvasspecific.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include <gtkmm/actiongroup.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class KeyframeTreeStore;
+class KeyframeTree;
+
+class KeyframeActionManager;
+       
+class Dock_Keyframes : public Dock_CanvasSpecific
+{      
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+
+       /*
+       void add_keyframe_pressed();
+       void duplicate_keyframe_pressed();
+       void delete_keyframe_pressed();
+       */
+       
+       void show_keyframe_properties();
+       
+       KeyframeActionManager* keyframe_action_manager;
+       
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+
+public:
+
+
+       Dock_Keyframes();
+       ~Dock_Keyframes();
+}; // END of Dock_Keyframes
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_layergroups.cpp b/synfig-studio/trunk/src/gtkmm/dock_layergroups.cpp
new file mode 100644 (file)
index 0000000..ec12b7f
--- /dev/null
@@ -0,0 +1,133 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_layergroups.cpp
+**     \brief Template File
+**
+**     $Id: dock_layergroups.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_layergroups.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/slot.h>
+#include "canvasview.h"
+
+#include "layergrouptreestore.h"
+#include "layergrouptree.h"
+#include "groupactionmanager.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_LayerGroups::Dock_LayerGroups():
+       Dock_CanvasSpecific("groups",_("Groups"),Gtk::StockID("sinfg-group")),
+       action_group_group_ops(Gtk::ActionGroup::create()),
+       group_action_manager(new GroupActionManager)
+{      
+       group_action_manager->set_ui_manager(App::ui_manager());
+
+       action_group_group_ops->add( Gtk::Action::create("toolbar-groups", "Group Ops") );
+
+       action_group_add=Gtk::Action::create("action-group_add", Gtk::Stock::ADD,_("Add a New Group"),_("Add a New Group"));
+       action_group_group_ops->add(action_group_add);
+       action_group_add->set_sensitive(false);
+       
+       App::ui_manager()->insert_action_group(action_group_group_ops);
+
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-groups'>"
+       "       <toolitem action='action-group_remove' />"
+       "       <toolitem action='action-group_add' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-groups")));    
+}
+
+Dock_LayerGroups::~Dock_LayerGroups()
+{
+       delete group_action_manager;
+}
+
+void
+Dock_LayerGroups::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store;
+       layer_group_tree_store=LayerGroupTreeStore::create(canvas_view->canvas_interface());
+
+       LayerGroupTree* layer_group_tree(new LayerGroupTree());
+       layer_group_tree->set_model(layer_group_tree_store);
+       layer_group_tree->signal_popup_layer_menu().connect(sigc::mem_fun(*canvas_view,&CanvasView::popup_layer_menu));
+
+       canvas_view->set_tree_model(get_name(),layer_group_tree_store);
+       canvas_view->set_ext_widget(get_name(),layer_group_tree);
+}
+
+void
+Dock_LayerGroups::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               Gtk::Widget* tree_view(canvas_view->get_ext_widget(get_name()));
+       
+               add(*tree_view);
+               tree_view->show();
+               
+               group_action_manager->set_group_tree(dynamic_cast<LayerGroupTree*>(tree_view));
+               group_action_manager->set_canvas_interface(canvas_view->canvas_interface());
+               group_action_manager->refresh();
+       }
+       else
+       {
+               clear_previous();               
+               group_action_manager->clear();
+               group_action_manager->set_canvas_interface(0);
+               group_action_manager->set_group_tree(0);
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_layergroups.h b/synfig-studio/trunk/src/gtkmm/dock_layergroups.h
new file mode 100644 (file)
index 0000000..af6be44
--- /dev/null
@@ -0,0 +1,70 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_layergroups.h
+**     \brief Template Header
+**
+**     $Id: dock_layergroups.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_LAYERGROUPS_H
+#define __SINFG_STUDIO_DOCK_LAYERGROUPS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+#include <gtkmm/actiongroup.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class HScale; }
+
+namespace studio {
+
+class GroupActionManager ;
+       
+class Dock_LayerGroups : public Dock_CanvasSpecific
+{      
+       Glib::RefPtr<Gtk::ActionGroup> action_group_group_ops;
+       Glib::RefPtr<Gtk::Action> action_group_add;
+
+       GroupActionManager *group_action_manager;
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+private:
+
+public:
+
+
+       Dock_LayerGroups();
+       ~Dock_LayerGroups();
+}; // END of Dock_LayerGroups
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_layers.cpp b/synfig-studio/trunk/src/gtkmm/dock_layers.cpp
new file mode 100644 (file)
index 0000000..3cfa166
--- /dev/null
@@ -0,0 +1,275 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_layers.cpp
+**     \brief Template File
+**
+**     $Id: dock_layers.cpp,v 1.2 2005/01/12 07:03:42 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_layers.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/slot.h>
+#include "layertreestore.h"
+#include "layertree.h"
+#include "canvasview.h"
+#include "layeractionmanager.h"
+//#include <ETL/ref_count>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/*static void do_nothing(reference_counter x)
+{
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,x.count());
+}*/
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Layers::Dock_Layers():
+       Dock_CanvasSpecific("layers",_("Layers"),Gtk::StockID("sinfg-layer")),
+//     layer_action_manager(0)
+       layer_action_manager(new LayerActionManager)
+{
+       if(layer_action_manager)layer_action_manager->set_ui_manager(App::ui_manager());
+
+       action_group_new_layers=Gtk::ActionGroup::create();
+       action_group_layer_ops=Gtk::ActionGroup::create();
+       
+       std::map<sinfg::String,sinfg::String> category_map;
+
+       // Build layer creation actions
+       sinfg::Layer::Book::iterator iter;
+       for(iter=sinfg::Layer::book().begin();iter!=sinfg::Layer::book().end();++iter)
+       {
+               sinfg::Layer::Book::value_type lyr(*iter);
+               
+               if(lyr.second.category==_("Do Not Use"))
+                       continue;
+               
+               action_group_new_layers->add(Gtk::Action::create(
+                       strprintf("layer-new-%s",lyr.first.c_str()),
+                       layer_icon(lyr.first.c_str()),
+                       lyr.second.local_name,lyr.second.local_name
+               ),
+                       sigc::hide_return(
+                               sigc::bind(
+                                       sigc::mem_fun(*this,&studio::Dock_Layers::add_layer),
+                                       lyr.first
+                               )
+                       )
+               );
+
+               category_map[lyr.second.category]+=strprintf("<menuitem action='layer-new-%s' />",lyr.first.c_str());
+       
+               //(*category_map)[lyr.second.category]->items().push_back(Gtk::Menu_Helpers::MenuElem(lyr.second.local_name,
+               //));
+       }
+       
+       {
+               Glib::RefPtr<Gtk::ActionGroup> action_group_categories(Gtk::ActionGroup::create("layer-category"));
+               sinfg::String layer_ui_info;
+               
+               layer_ui_info+="<ui><menubar action='menu-main'><menu action='menu-layer'><menu action='menu-layer-new'>";
+
+               std::map<sinfg::String,sinfg::String>::iterator iter;
+               for(iter=category_map.begin();iter!=category_map.end();++iter)
+               {
+                       layer_ui_info+=strprintf("<menu action='%s'>%s</menu>",iter->first.c_str(),iter->second.c_str());
+                       action_group_categories->add(Gtk::Action::create(iter->first.c_str(),iter->first.c_str()));
+               }
+
+               layer_ui_info+="</menu></menu></menubar></ui>";
+               
+               App::ui_manager()->insert_action_group(action_group_categories);
+               App::ui_manager()->insert_action_group(action_group_new_layers);
+               App::ui_manager()->add_ui_from_string(layer_ui_info);
+       }
+       
+       
+       action_group_layer_ops->add( Gtk::Action::create("toolbar-layer", "Layer Ops") );
+       App::ui_manager()->insert_action_group(action_group_layer_ops);
+
+
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-layer'>"
+       "       <toolitem action='action-layer_raise' />"
+       "       <toolitem action='action-layer_lower' />"
+       "       <toolitem action='action-layer_duplicate' />"
+       "       <toolitem action='action-layer_remove' />"
+       "       <toolitem action='cut' />"
+       "       <toolitem action='copy' />"
+       "       <toolitem action='paste' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       action_group_new_layers->set_sensitive(false);
+
+       set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-layer")));     
+
+
+
+
+
+       /*
+       reference_counter ref_count;
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+
+       {
+               sigc::signal<void> tmp_signal;
+               
+               tmp_signal.connect(
+                       sigc::bind(
+                               sigc::ptr_fun(do_nothing),
+                               ref_count
+                       )
+               );
+               
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+               tmp_signal();
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+               
+               tmp_signal.clear();
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+               
+               tmp_signal();
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+               tmp_signal.connect(
+                       sigc::bind(
+                               sigc::ptr_fun(do_nothing),
+                               ref_count
+                       )
+               );
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+       }
+       sinfg::info(__FILE__":%d:ref_count.count()=%d",__LINE__,ref_count.count());
+       assert(ref_count.count()==1);   
+       */
+}
+
+
+Dock_Layers::~Dock_Layers()
+{
+       delete layer_action_manager;
+}
+
+
+void
+Dock_Layers::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       Glib::RefPtr<LayerTreeStore> layer_tree_store;
+       layer_tree_store=LayerTreeStore::create(canvas_view->canvas_interface());
+
+       canvas_view->set_tree_model(get_name(),layer_tree_store);
+       LayerTree* layer_tree(new LayerTree());
+       layer_tree->set_model(layer_tree_store);
+       layer_tree->set_time_adjustment(canvas_view->time_adjustment());
+
+       layer_tree->signal_edited_value().connect(
+               sigc::hide_return(
+                       sigc::mem_fun(*canvas_view->canvas_interface(), &sinfgapp::CanvasInterface::change_value)
+               )
+       );
+
+       canvas_view->set_ext_widget(get_name()+"_cmp",layer_tree);
+       canvas_view->set_ext_widget(get_name(),&layer_tree->get_layer_tree_view());
+       canvas_view->set_ext_widget("params",&layer_tree->get_param_tree_view());
+       canvas_view->set_tree_model("params",layer_tree->get_param_tree_view().get_model());
+
+       /*
+       canvas_view->layermenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-delete"),Gtk::AccelKey("Delete"),
+               sigc::mem_fun(*layer_tree, &LayerTree::on_delete_pressed))
+       );
+       */
+
+       // Hide the time bar
+       if(canvas_view->get_canvas()->rend_desc().get_time_start()==canvas_view->get_canvas()->rend_desc().get_time_end())
+               canvas_view->hide_timebar();
+       layer_tree_store->rebuild();
+       present();
+}
+
+void
+Dock_Layers::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               Gtk::Widget* tree_view(canvas_view->get_ext_widget(get_name()));
+       
+               add(*tree_view);
+               tree_view->show();
+               action_group_new_layers->set_sensitive(true);
+               if(layer_action_manager)
+               {
+                       layer_action_manager->set_layer_tree(dynamic_cast<LayerTree*>(canvas_view->get_ext_widget(get_name()+"_cmp")));
+                       layer_action_manager->set_canvas_interface(canvas_view->canvas_interface());
+                       layer_action_manager->refresh();
+               }
+       }
+       else
+       {
+               action_group_new_layers->set_sensitive(false);
+               if(layer_action_manager)
+               {
+                       layer_action_manager->clear();
+                       layer_action_manager->set_canvas_interface(0);
+                       layer_action_manager->set_layer_tree(0);
+               }
+               
+               clear_previous();               
+       }
+}
+
+void
+Dock_Layers::add_layer(sinfg::String id)
+{
+       etl::loose_handle<CanvasView> canvas_view(get_canvas_view());
+       if(canvas_view)
+       {
+               canvas_view->add_layer(id);
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_layers.h b/synfig-studio/trunk/src/gtkmm/dock_layers.h
new file mode 100644 (file)
index 0000000..c0c2332
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_layers.h
+**     \brief Template Header
+**
+**     $Id: dock_layers.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_LAYERS_H
+#define __SINFG_STUDIO_DOCK_LAYERS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+#include <gtkmm/actiongroup.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class HScale; }
+
+namespace studio {
+
+class LayerActionManager;
+
+class Dock_Layers : public Dock_CanvasSpecific
+{      
+       Glib::RefPtr<Gtk::ActionGroup> action_group_new_layers;
+       Glib::RefPtr<Gtk::ActionGroup> action_group_layer_ops;
+       
+       Gtk::HScale *layer_amount_hscale;
+
+       LayerActionManager* layer_action_manager;
+       
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+private:
+
+       void add_layer(sinfg::String id);
+       void increase_amount();
+       void decrease_amount();
+
+public:
+
+
+       Dock_Layers();
+       ~Dock_Layers();
+}; // END of Dock_Layers
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_metadata.cpp b/synfig-studio/trunk/src/gtkmm/dock_metadata.cpp
new file mode 100644 (file)
index 0000000..5700a01
--- /dev/null
@@ -0,0 +1,141 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_metadata.cpp
+**     \brief Template File
+**
+**     $Id: dock_metadata.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_metadata.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "metadatatreestore.h"
+#include "canvasview.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_MetaData::Dock_MetaData():
+       Dock_CanvasSpecific("meta_data",_("Canvas MetaData"),Gtk::StockID("sinfg-meta_data")),
+       tree_view(manage(new Gtk::TreeView()))
+{
+       MetaDataTreeStore::Model model;
+       
+       tree_view->append_column(_("Key"),model.key);
+       tree_view->append_column_editable(_("Data"),model.data);
+       tree_view->set_rules_hint();
+       
+       Gtk::ScrolledWindow *scrolledwindow = manage(new class Gtk::ScrolledWindow());
+       scrolledwindow->set_flags(Gtk::CAN_FOCUS);
+       scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       scrolledwindow->add(*tree_view);
+       scrolledwindow->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scrolledwindow->show();
+
+       add(*scrolledwindow);
+
+       add_button(
+               Gtk::StockID("gtk-add"),
+               _("Add new MetaData entry")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_MetaData::on_add_pressed
+               )
+       );
+
+       add_button(
+               Gtk::StockID("gtk-delete"),
+               _("Remove selected MetaData entry")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_MetaData::on_delete_pressed
+               )
+       );
+}
+
+Dock_MetaData::~Dock_MetaData()
+{
+}
+
+void
+Dock_MetaData::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       canvas_view->set_tree_model(get_name(),MetaDataTreeStore::create(canvas_view->canvas_interface()));
+}
+
+void
+Dock_MetaData::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               tree_view->set_model(canvas_view->get_tree_model(get_name()));
+               tree_view->show();
+       }
+       else
+       {
+               tree_view->set_model(Glib::RefPtr<Gtk::TreeModel>());
+               tree_view->hide();
+       }
+}
+
+void
+Dock_MetaData::on_add_pressed()
+{
+       if(get_canvas_interface())
+       {
+               sinfg::String key;
+               if(App::dialog_entry("New MetaData Entry", "Please enter the name of the key",key) && !key.empty())
+               {
+                       get_canvas_interface()->set_meta_data(key," ");
+               }
+       }
+}
+
+void
+Dock_MetaData::on_delete_pressed()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_metadata.h b/synfig-studio/trunk/src/gtkmm/dock_metadata.h
new file mode 100644 (file)
index 0000000..f2036c2
--- /dev/null
@@ -0,0 +1,70 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_metadata.h
+**     \brief Template Header
+**
+**     $Id: dock_metadata.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_METADATA_H
+#define __SINFG_STUDIO_DOCK_METADATA_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CanvasView;
+class Instance;
+       
+class Dock_MetaData : public Dock_CanvasSpecific
+{      
+
+       Gtk::TreeView *tree_view;
+       
+
+       void on_add_pressed();
+       void on_delete_pressed();
+
+protected:
+       
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       
+public:
+
+
+       Dock_MetaData();
+       ~Dock_MetaData();
+}; // END of Dock_MetaData
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_navigator.cpp b/synfig-studio/trunk/src/gtkmm/dock_navigator.cpp
new file mode 100644 (file)
index 0000000..022e6e3
--- /dev/null
@@ -0,0 +1,512 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_navigator.cpp
+**     \brief Dock Nagivator File
+**
+**     $Id: dock_navigator.cpp,v 1.3 2005/01/12 00:31:11 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_navigator.h"
+#include "canvasview.h"
+#include "workarea.h"
+
+#include <cassert>
+#include <sinfg/canvas.h>
+#include <sinfg/context.h>
+#include <sinfg/target_scanline.h>
+#include <sinfg/surface.h>
+
+#include <gtkmm/separator.h>
+
+#include "asyncrenderer.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+const double log_10_2 = log(2.0);
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+studio::Widget_NavView::Widget_NavView(CanvasView::LooseHandle cv)
+:canvview(cv),
+adj_zoom(0,-4,4,1,2),
+surface(new sinfg::Surface)
+{
+       attach(drawto,0,4,0,1);
+       
+       attach(*manage(new Gtk::HSeparator),0,4,1,2,Gtk::SHRINK|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //zooming stuff
+       attach(zoom_print,0,1,2,3,Gtk::SHRINK|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       zoom_print.set_size_request(40,-1);
+       
+       Gtk::HScale *s = manage(new Gtk::HScale(adj_zoom));
+       s->set_draw_value(false);
+       //s->set_update_policy(Gtk::UPDATE_DELAYED);
+       //s->signal_event().connect(sigc::mem_fun(*this,&Dock_Navigator::on_scroll_event));
+       attach(*s,1,4,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+               
+       show_all();
+       
+       adj_zoom.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_NavView::on_number_modify));
+       
+       if(cv)
+       {
+               drawto.signal_expose_event().connect(sigc::mem_fun(*this,&Widget_NavView::on_expose_draw));
+               drawto.signal_event().connect(sigc::mem_fun(*this,&Widget_NavView::on_mouse_event));
+               
+               drawto.add_events(Gdk::BUTTON_MOTION_MASK|Gdk::BUTTON_PRESS_MASK);
+               
+               //get_canvas_view()->canvas_interface()->signal_dirty_preview()
+               //                              .connect(sigc::mem_fun(*this,&Widget_NavView::on_dirty_preview));
+               get_canvas_view()->work_area->signal_rendering()
+                                               .connect(sigc::mem_fun(*this,&Widget_NavView::on_dirty_preview));
+               
+               get_canvas_view()->work_area->signal_view_window_changed()
+                                               .connect(sigc::mem_fun(*this,&Widget_NavView::on_workarea_view_change));
+               
+               //update with this canvas' view
+               on_workarea_view_change();
+                               
+               dirty = true;
+               queue_draw();
+       }
+       
+       adj_zoom.set_value(0);
+}
+
+studio::Widget_NavView::~Widget_NavView()
+{
+}
+
+
+static void freegu8(const guint8 *p)
+{
+       delete [] p;
+}
+
+void studio::Widget_NavView::on_start_render()
+{
+       if(dirty)
+       {
+               //sinfg::warning("Nav: Starting render");
+               //sinfg::warning("Nav: Rendering canvas");
+               etl::handle<Target_Scanline>    targ = surface_target(surface.get());
+               
+               targ->set_canvas(get_canvas_view()->get_canvas());
+               targ->set_remove_alpha();
+               targ->set_avoid_time_sync();
+               targ->set_quality(get_canvas_view()->get_work_area()->get_quality());
+               //sinfg::info("Set the quality level to: %d", get_canvas_view()->get_work_area()->get_quality());
+               
+               //this should set it to render a single frame
+               RendDesc        r = get_canvas_view()->get_canvas()->rend_desc();
+               r.set_time(get_canvas_view()->canvas_interface()->get_time());
+               
+               //this changes the size of the canvas to the closest thing we can find
+               int sw = r.get_w(), sh = r.get_h();
+               
+               //sinfg::warning("Nav: source image is %d x %d", sw,sh);
+               
+               //resize so largest dimension is 128
+               int dw = sw > sh ? 128 : sw*128/sh,
+                       dh = sh > sw ? 128 : sh*128/sw;
+               
+               //sinfg::warning("Nav: dest image is %d x %d", dw,dh);
+               
+               r.set_w(dw);
+               r.set_h(dh);
+
+               //get the pw and ph
+               //float pw = r.get_pw();
+               //float ph = r.get_ph();
+               
+               //sinfg::warning("Nav: pixel size is %f x %f", pw,ph);
+               
+               //this renders that single frame
+               targ->set_rend_desc(&r);
+               
+               //sinfg::warning("Nav: Building async renderer and starting it...");
+               
+               renderer = new AsyncRenderer(targ);
+               renderer->signal_success().connect(sigc::mem_fun(*this,&Widget_NavView::on_finish_render));
+               renderer->start();
+               dirty = false;
+       }
+}
+
+void studio::Widget_NavView::on_finish_render()
+{
+       //convert it into our pixmap
+       PixelFormat pf(PF_RGB);
+       
+       //sinfg::warning("Nav: It hath succeeded!!!");
+       
+       //assert(renderer && renderer->has_success());
+       DEBUGPOINT();
+       //sinfg::warning("Nav: now we know it really succeeded");
+       if(!*surface)
+       {
+               sinfg::warning("dock_navigator: Bad surface");
+               return;
+       }
+       
+       int w = 0, h = 0;
+       int dw = surface->get_w();
+       int dh = surface->get_h();
+       
+       if(prev)
+       {
+               w = prev->get_width();
+               h = prev->get_height();
+       }
+       
+       if(w != dw || h != dh || !prev)
+       {
+               const int total_bytes(dw*dh*sinfg::channels(pf));
+               
+               //sinfg::warning("Nav: Updating the pixbuf to be the right size, etc. (%d bytes)", total_bytes);
+               
+               prev.clear();
+               guint8 *bytes = new guint8[total_bytes]; //24 bits per pixel
+               
+               //convert into our buffered dataS
+               //sinfg::warning("Nav: converting color format into buffer");
+               convert_color_format((unsigned char *)bytes, (*surface)[0], dw*dh, pf, App::gamma);
+               
+               prev = 
+               Gdk::Pixbuf::create_from_data(
+                       bytes,  // pointer to the data
+                       Gdk::COLORSPACE_RGB, // the colorspace
+                       ((pf&PF_A)==PF_A), // has alpha?
+                       8, // bits per sample
+                       dw,     // width
+                       dh,     // height
+                       dw*sinfg::channels(pf), // stride (pitch)
+                       SigC::slot(freegu8)
+               );
+       }
+       else
+       {
+               //sinfg::warning("Nav: Don't need to resize");
+               //convert into our buffered dataS
+               //sinfg::warning("Nav: converting color format into buffer");
+               if(prev) //just in case we're stupid
+               {
+                       convert_color_format((unsigned char *)prev->get_pixels(), (*surface)[0], dw*dh, pf, App::gamma);
+               }
+       }
+       queue_draw();   
+}
+
+/*     zoom slider is on exponential scale
+
+       map: -4,4 -> small number,1600 with 100 at 0
+
+       f(x) = 100*2^x
+*/
+
+static double unit_to_zoom(double f)
+{
+       return pow(2.0,f);
+}
+
+static double zoom_to_unit(double f)
+{
+       if(f > 0)
+       {
+               return log(f) / log_10_2;
+       }else return -999999.0;
+}
+
+bool studio::Widget_NavView::on_expose_draw(GdkEventExpose *exp)
+{
+       //print out the zoom
+       //HACK kind of...
+       //zoom_print.set_text(strprintf("%.1f%%",100*unit_to_zoom(adj_zoom.get_value())));
+       
+       //draw the good stuff
+       on_start_render();
+       
+       //if we've got a preview etc. display it...
+       if(get_canvas_view() && prev)
+       {
+               //axis transform from units to pixel coords
+               float xaxis = 0, yaxis = 0;
+               
+               int canvw = get_canvas_view()->get_canvas()->rend_desc().get_w();
+               //int canvh = get_canvas_view()->get_canvas()->rend_desc().get_h();
+               
+               float pw = get_canvas_view()->get_canvas()->rend_desc().get_pw();
+               float ph = get_canvas_view()->get_canvas()->rend_desc().get_ph();
+               
+               int w = prev->get_width();
+               int h = prev->get_height();
+                               
+               //scale up/down to the nearest pixel ratio...
+               //and center in center
+               int offx=0, offy=0;
+               
+               float sx, sy;
+               int nw,nh;
+               
+               sx = drawto.get_width() / (float)w;
+               sy = drawto.get_height() / (float)h;
+               
+               //sinfg::warning("Nav redraw: now to scale the bitmap: %.3f x %.3f",sx,sy);
+               
+               //round to smallest scale (fit entire thing in window without distortion)
+               if(sx > sy) sx = sy;
+               //else sy = sx;
+               
+               //scaling and stuff
+               // the point to navpixel space conversion should be:
+               //              (navpixels / canvpixels) * (canvpixels / canvsize)
+               //      or (navpixels / prevpixels) * (prevpixels / navpixels)
+               xaxis = sx * w / (float)canvw;
+               yaxis = xaxis/ph;
+               xaxis /= pw;
+               
+               //scale to a new pixmap and then copy over to the window
+               nw = (int)(w*sx);
+               nh = (int)(h*sx);
+               
+               //must now center to be cool
+               offx = (drawto.get_width() - nw)/2;
+               offy = (drawto.get_height() - nh)/2;
+               
+               //trivial escape
+               if(nw == 0 || nh == 0)return true;
+                                                       
+               //draw to drawing area
+               Glib::RefPtr<Gdk::GC>   gc = Gdk::GC::create(drawto.get_window());
+               
+               //sinfg::warning("Nav: Scaling pixmap to off (%d,%d) with size (%d,%d)", offx,offy,nw, nh);
+               Glib::RefPtr<Gdk::Pixbuf> scalepx = prev->scale_simple(nw,nh,Gdk::INTERP_NEAREST);
+               
+               //sinfg::warning("Nav: Drawing scaled bitmap");
+               drawto.get_window()->draw_pixbuf(
+                       gc, //GC
+                       scalepx, //pixbuf
+                       0, 0,   // Source X and Y
+                       offx, offy,     // Dest X and Y
+                       -1,-1,  // Width and Height
+                       Gdk::RGB_DITHER_MAX, // RgbDither
+                       2, 2 // Dither offset X and Y
+               );
+                               
+               //draw fancy red rectangle around focus point
+               const Point &wtl = get_canvas_view()->work_area->get_window_tl(),
+                                       &wbr = get_canvas_view()->work_area->get_window_br();
+               
+               gc->set_rgb_fg_color(Gdk::Color("#ff0000"));
+               gc->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               
+               //it must be clamped to the drawing area though
+               int l=0,rw=0,t=0,rh=0;
+               const Point fp = -get_canvas_view()->work_area->get_focus_point();
+               
+               //get focus point in normal space
+               rw = (int)(abs((wtl[0]-wbr[0])*xaxis));
+               rh = (int)(abs((wtl[1]-wbr[1])*yaxis));
+
+               //transform into pixel space
+               l = (int)(drawto.get_width()/2 + fp[0]*xaxis - rw/2);
+               t = (int)(drawto.get_height()/2 + fp[1]*yaxis - rh/2);
+       
+               //coord system:
+               // tl : (offx,offy)
+               // axis multipliers = xaxis,yaxis
+               //sinfg::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
+               //sinfg::warning("Nav: tl (%f,%f), br (%f,%f)", wtl[0],wtl[1],wbr[0],wbr[1]);
+               //sinfg::warning("Nav: Drawing Rectangle (%d,%d) with dim (%d,%d)", l,t,rw,rh);
+               drawto.get_window()->draw_rectangle(gc,false,l,t,rw,rh);
+       }
+       
+       return false; //draw everything else too
+}
+
+void studio::Widget_NavView::on_dirty_preview()
+{
+       dirty = true;
+       queue_draw();
+}
+
+bool studio::Widget_NavView::on_scroll_event(GdkEvent *event)
+{      
+       if(get_canvas_view() && get_canvas_view()->get_work_area())
+       {
+               double z = unit_to_zoom(adj_zoom.get_value());
+               
+               switch(event->type)
+               {
+                       case GDK_BUTTON_PRESS:
+                       {
+                               if(event->button.button == 1)
+                               {
+                                       scrolling = true;
+                                       get_canvas_view()->get_work_area()->set_zoom(z);                                        
+                                       scrolling = false;
+                               }
+                               break;
+                       }
+                       
+                       case GDK_MOTION_NOTIFY:
+                       {
+                               if(Gdk::ModifierType(event->motion.state) & Gdk::BUTTON1_MASK)
+                               {
+                                       scrolling = true;
+                                       get_canvas_view()->get_work_area()->set_zoom(z);
+                                       scrolling = false;
+                               }
+                               break;
+                       }
+                       
+                       default:
+                               break;
+               }
+       }
+       
+       return false;
+}
+
+void studio::Widget_NavView::on_number_modify()
+{
+       double z = unit_to_zoom(adj_zoom.get_value());
+       zoom_print.set_text(strprintf("%.1f%%",z*100.0));       
+       //sinfg::warning("Updating zoom to %f",adj_zoom.get_value());
+       
+       if(get_canvas_view() && z != get_canvas_view()->get_work_area()->get_zoom())
+       {
+               scrolling = true;
+               get_canvas_view()->get_work_area()->set_zoom(z);
+               scrolling = false;
+       }
+}
+
+void studio::Widget_NavView::on_workarea_view_change()
+{
+       double wz = get_canvas_view()->get_work_area()->get_zoom();
+       double z = zoom_to_unit(wz);
+
+       //sinfg::warning("Updating zoom to %f -> %f",wz,z);
+       if(!scrolling && z != adj_zoom.get_value())
+       {
+               adj_zoom.set_value(z);
+               //adj_zoom.value_changed();
+       }
+       queue_draw();
+}
+
+bool studio::Widget_NavView::on_mouse_event(GdkEvent * e)
+{
+       Point p;
+       bool    setpos = false;
+               
+       if(e->type == GDK_BUTTON_PRESS && e->button.button == 1)
+       {
+               p[0] = e->button.x - drawto.get_width()/2;
+               p[1] = e->button.y - drawto.get_height()/2;
+               
+               setpos = true;
+       }
+       
+       if(e->type == GDK_MOTION_NOTIFY && (Gdk::ModifierType(e->motion.state) & Gdk::BUTTON1_MASK))
+       {               
+               p[0] = e->motion.x - drawto.get_width()/2;
+               p[1] = e->motion.y - drawto.get_height()/2;     
+               
+               setpos = true;
+       }
+       
+       if(setpos && prev && get_canvas_view())
+       {
+               const Point &tl = get_canvas_view()->get_canvas()->rend_desc().get_tl();
+               const Point &br = get_canvas_view()->get_canvas()->rend_desc().get_br();
+               
+               float max = abs((br[0]-tl[0]) / drawto.get_width());
+               
+               if((prev->get_width() / drawto.get_width()) < (prev->get_height() / drawto.get_height()))
+                       max = abs((br[1]-tl[1]) / drawto.get_height());
+               
+               float signx = (br[0]-tl[0]) < 0 ? -1 : 1;
+               float signy = (br[1]-tl[1]) < 0 ? -1 : 1;
+               
+               Point pos;
+               
+               pos[0] = p[0] * max * signx;
+               pos[1] = p[1] * max * signy;
+               
+               get_canvas_view()->get_work_area()->set_focus_point(-pos);
+               
+               return true;
+       }
+       
+       return false;
+}
+
+//Navigator Dock Definitions
+
+studio::Dock_Navigator::Dock_Navigator()
+:Dock_CanvasSpecific("navigator",_("Navigator"),Gtk::StockID("sinfg-navigator"))
+{
+       add(dummy);
+}
+
+studio::Dock_Navigator::~Dock_Navigator()
+{
+}
+
+void studio::Dock_Navigator::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{      
+       if(canvas_view)
+       {               
+               Widget *v = canvas_view->get_ext_widget("navview");
+               
+               if(!v)
+               {
+                       v = new Widget_NavView(canvas_view);
+                       canvas_view->set_ext_widget("navview",v);
+               }
+
+               add(*v);
+       }else
+       {
+               clear_previous();
+               //add(dummy);                   
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_navigator.h b/synfig-studio/trunk/src/gtkmm/dock_navigator.h
new file mode 100644 (file)
index 0000000..94c145c
--- /dev/null
@@ -0,0 +1,120 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_navigator.h
+**     \brief Navigator Dock Header
+**
+**     $Id: dock_navigator.h,v 1.3 2005/01/12 00:31:11 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DOCK_NAVIGATOR_H
+#define __SINFG_DOCK_NAVIGATOR_H
+
+/* === H E A D E R S ======================================================= */
+#include "sigc++/signal.h"
+
+#include <gtkmm/drawingarea.h>
+#include <gdkmm/pixbuf.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/label.h>
+
+#include <sinfg/renddesc.h>
+
+#include "canvasview.h"
+#include "dock_canvasspecific.h"
+#include "widget_distance.h"
+
+#include <ETL/smart_ptr>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class AsyncRenderer;
+       
+class Widget_NavView : public Gtk::Table
+{
+       //handle to out parent canvas
+       CanvasView::LooseHandle         canvview;
+       
+       Glib::RefPtr<Gdk::Pixbuf>       prev;
+       bool dirty;
+       
+       //The drawing stuff     
+       Gtk::DrawingArea        drawto;
+       
+       //The input stuff
+       Gtk::Adjustment         adj_zoom;
+       Gtk::Label                      zoom_print;
+       
+       //zoom window stuff
+       bool                            scrolling;
+       
+       //asyncronous rendering stuff
+       etl::handle<AsyncRenderer>      renderer;
+       etl::smart_ptr<sinfg::Surface> surface;
+       bool                                            rendering;
+       
+       //drawing functionality
+       void on_start_render(); //breaks out into asynchronous rendering
+       void on_finish_render();
+       void on_draw(); //renders the small thing we have
+       void on_dirty_preview(); //dirties the preview for rerender
+       
+       //for the zoom buttons
+       void on_zoom_in();
+       void on_zoom_out();
+       
+       //handles the zoom scroller
+       bool on_scroll_event(GdkEvent *event);
+       void on_number_modify();
+       
+       //
+       bool on_mouse_event(GdkEvent * e);
+       
+       //draws the gotten bitmap on the draw area
+       bool on_expose_draw(GdkEventExpose *exp=0);
+       
+       //for when the canvasview view changes (boolean value scrolling solves cyclic problems)
+       void on_workarea_view_change();
+
+public:
+       Widget_NavView(CanvasView::LooseHandle cv = CanvasView::LooseHandle());
+       ~Widget_NavView();
+
+       etl::loose_handle<studio::CanvasView> get_canvas_view() {return canvview;}
+};
+       
+class Dock_Navigator : public Dock_CanvasSpecific
+{
+       Widget_NavView  dummy;
+               
+public:
+       Dock_Navigator();
+       ~Dock_Navigator();
+
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_params.cpp b/synfig-studio/trunk/src/gtkmm/dock_params.cpp
new file mode 100644 (file)
index 0000000..e51e92c
--- /dev/null
@@ -0,0 +1,138 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_params.cpp
+**     \brief Template File
+**
+**     $Id: dock_params.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_params.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "canvasview.h"
+#include "layerparamtreestore.h"
+#include "workarea.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Params::Dock_Params():
+       Dock_CanvasSpecific("params",_("Params"),Gtk::Stock::INDEX/*Gtk::StockID("sinfg-params")*/),
+       action_group(Gtk::ActionGroup::create())
+{
+/*
+       App::ui_manager()->insert_action_group(action_group_layer_ops);
+
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-palette'>"
+       "       <toolitem action='amount-increase' />"
+       "       <toolitem action='amount-decrease' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+       */
+}
+
+Dock_Params::~Dock_Params()
+{
+}
+
+
+void
+Dock_Params::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       DEBUGPOINT();
+       Gtk::TreeView* tree_view(
+               static_cast<Gtk::TreeView*>(canvas_view->get_ext_widget(get_name()))
+       );
+       
+       if(tree_view)
+       {
+               tree_view->get_selection()->signal_changed().connect(
+                       sigc::mem_fun(
+                               *this,
+                               &Dock_Params::refresh_selected_param
+                       )
+               );
+       }
+}
+
+void
+Dock_Params::refresh_selected_param()
+{
+       Gtk::TreeView* tree_view(
+               static_cast<Gtk::TreeView*>(get_canvas_view()->get_ext_widget(get_name()))
+       );
+       Gtk::TreeModel::iterator iter(tree_view->get_selection()->get_selected());
+       
+       if(iter)
+       {
+               LayerParamTreeStore::Model model;
+               get_canvas_view()->work_area->set_selected_value_node(
+                       (sinfg::ValueNode::Handle)(*iter)[model.value_node]
+               );
+       }
+       else
+       {
+               get_canvas_view()->work_area->set_selected_value_node(0);
+       }
+}
+
+void
+Dock_Params::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(canvas_view)
+       {
+               Gtk::Widget* tree_view(canvas_view->get_ext_widget(get_name()));
+               
+               add(*tree_view);
+               tree_view->show();
+               show_all();
+       }
+       else clear_previous();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_params.h b/synfig-studio/trunk/src/gtkmm/dock_params.h
new file mode 100644 (file)
index 0000000..1f3dbf5
--- /dev/null
@@ -0,0 +1,63 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_params.h
+**     \brief Template Header
+**
+**     $Id: dock_params.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_PARAMS_H
+#define __SINFG_STUDIO_DOCK_PARAMS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_Params : public Dock_CanvasSpecific
+{
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+       
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+       void refresh_selected_param();
+
+public:
+
+
+       Dock_Params();
+       ~Dock_Params();
+}; // END of Dock_Keyframes
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dock_timetrack.cpp b/synfig-studio/trunk/src/gtkmm/dock_timetrack.cpp
new file mode 100644 (file)
index 0000000..c81a6cd
--- /dev/null
@@ -0,0 +1,500 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_timetrack.cpp
+**     \brief Template File
+**
+**     $Id: dock_timetrack.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_timetrack.h"
+#include "app.h"
+
+#include <gtkmm/scrolledwindow.h>
+#include <cassert>
+#include "instance.h"
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include "canvasview.h"
+#include "layerparamtreestore.h"
+#include "workarea.h"
+#include "widget_timeslider.h"
+#include "layerparamtreestore.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S ======================================================= */
+
+class TimeTrackView : public Gtk::TreeView
+{
+       CellRenderer_TimeTrack *cellrenderer_time_track;
+
+       Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
+       
+       Gtk::TreeView *mimic_tree_view; 
+public:
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::Waypoint,int> signal_waypoint_clicked;
+
+       LayerParamTreeStore::Model model;
+
+       void set_canvas_view(handle<CanvasView> canvas_view)
+       {
+               cellrenderer_time_track->set_adjustment(canvas_view->time_adjustment());
+       }
+
+       TimeTrackView()
+       {
+               int label_index(append_column_editable(_("Name"),model.label));
+               Gtk::TreeView::Column* label_column = get_column(label_index-1);
+       
+               {       // --- T I M E   T R A C K --------------------------------------------
+                       Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+                       
+                       // Set up the value-node cell-renderer
+                       cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
+                       cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+                       cellrenderer_time_track->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &TimeTrackView::on_waypoint_clicked) );
+                       cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &TimeTrackView::on_waypoint_changed) );
+                       column->add_attribute(cellrenderer_time_track->property_value_desc(), model.value_desc);
+                       column->add_attribute(cellrenderer_time_track->property_canvas(), model.canvas);
+                       //column->add_attribute(cellrenderer_time_track->property_visible(), model.is_value_node);
+       
+                       //column->pack_start(*cellrenderer_time_track);
+                                       
+                       // Finish setting up the column
+                       column->set_reorderable();
+                       column->set_resizable();
+                       column->set_min_width(200);
+
+       
+                       append_column(*column);
+               }
+               set_rules_hint();
+       
+               set_expander_column(*label_column);
+               label_column->set_visible(false);
+               set_headers_visible(false);
+               set_size_request(-1,64);
+       }
+
+       bool
+       on_event(GdkEvent *event)
+       {
+               switch(event->type)
+               {
+               case GDK_SCROLL:
+                       if(mimic_tree_view)
+                       {
+                               if(event->scroll.direction==GDK_SCROLL_DOWN)
+                               {
+                                       mimic_tree_view->get_vadjustment()->set_value(
+                                               std::min(
+                                                       mimic_tree_view->get_vadjustment()->get_value()+
+                                                       mimic_tree_view->get_vadjustment()->get_step_increment(),
+                                                       mimic_tree_view->get_vadjustment()->get_upper()-
+                                                       mimic_tree_view->get_vadjustment()->get_page_size()
+                                               )
+                                       );
+                                       mimic_tree_view->get_vadjustment()->value_changed();
+                               }
+                               else if(event->scroll.direction==GDK_SCROLL_UP)
+                               {
+                                       mimic_tree_view->get_vadjustment()->set_value(
+                                               std::max(
+                                                       mimic_tree_view->get_vadjustment()->get_value()-
+                                                       mimic_tree_view->get_vadjustment()->get_step_increment(),
+                                                       mimic_tree_view->get_vadjustment()->get_lower()                                 
+                                               )
+                                       );
+                                       mimic_tree_view->get_vadjustment()->value_changed();
+                               }
+                       }
+                       break;
+               case GDK_BUTTON_PRESS:
+                       {
+                               Gtk::TreeModel::Path path;
+                               Gtk::TreeViewColumn *column;
+                               int cell_x, cell_y;
+                               if(!get_path_at_pos(
+                                       int(event->button.x),int(event->button.y),      // x, y
+                                       path, // TreeModel::Path&
+                                       column, //TreeViewColumn*&
+                                       cell_x,cell_y //int&cell_x,int&cell_y
+                                       )
+                               ) break;
+                               const Gtk::TreeRow row = *(get_model()->get_iter(path));
+                               
+                               if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
+                               {
+                                       Gdk::Rectangle rect;
+                                       get_cell_area(path,*column,rect);
+                                       cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                                       cellrenderer_time_track->property_canvas()=row[model.canvas];
+                                       cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                                       queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                                       return true;
+                                       //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                               }
+/*                             else 
+                               {
+                                       if(event->button.button==3)
+                                       {
+                                               LayerList layer_list(get_selected_layers());
+                                               if(layer_list.size()<=1)
+                                               {
+                                                       sinfgapp::ValueDesc value_desc(row[model.value_desc]);
+                                                       Gtk::Menu* menu(manage(new Gtk::Menu()));                                       
+                                                       App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
+                                                       menu->popup(event->button.button,gtk_get_current_event_time());
+                                                       return true;
+                                               }
+                                               Gtk::Menu* menu(manage(new Gtk::Menu()));                                       
+                                               std::list<sinfgapp::ValueDesc> value_desc_list;
+                                               ParamDesc param_desc(row[model.param_desc]);
+                                               for(;!layer_list.empty();layer_list.pop_back())
+                                                       value_desc_list.push_back(sinfgapp::ValueDesc(layer_list.back(),param_desc.get_name()));
+                                               App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
+                                               menu->popup(event->button.button,gtk_get_current_event_time());
+                                               return true;
+                                       }
+                                       else
+                                       {
+                                               if(column->get_first_cell_renderer()==cellrenderer_value)
+                                                       return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
+                                               else
+                                                       return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
+                                       }
+                               }
+                               */
+                       }
+                       break;
+                       
+               case GDK_MOTION_NOTIFY:
+                       {
+                               Gtk::TreeModel::Path path;
+                               Gtk::TreeViewColumn *column;
+                               int cell_x, cell_y;
+                               if(!get_path_at_pos(
+                                       (int)event->motion.x,(int)event->motion.y,      // x, y
+                                       path, // TreeModel::Path&
+                                       column, //TreeViewColumn*&
+                                       cell_x,cell_y //int&cell_x,int&cell_y
+                                       )
+                               ) break;
+                               
+                               if(!get_model()->get_iter(path))
+                                       break;
+                               
+                               Gtk::TreeRow row = *(get_model()->get_iter(path));
+                               
+                               if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
+                               {
+                                       Gdk::Rectangle rect;
+                                       get_cell_area(path,*column,rect);
+                                       cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                                       cellrenderer_time_track->property_canvas()=row[model.canvas];
+                                       cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                                       queue_draw();
+                                       //queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                                       return true;
+                               }
+/*                             else
+                               if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                               {
+                                       tooltips_.unset_tip(*this);
+                                       Glib::ustring tooltips_string(row[layer_model.tooltip]);
+                                       last_tooltip_path=path;
+                                       if(!tooltips_string.empty())
+                                       {
+                                               tooltips_.set_tip(*this,tooltips_string);
+                                               tooltips_.force_window();
+                                       }
+                               }
+*/
+                               return true;
+                       }
+                       break;
+               case GDK_BUTTON_RELEASE:
+                       {
+                               Gtk::TreeModel::Path path;
+                               Gtk::TreeViewColumn *column;
+                               int cell_x, cell_y;
+                               if(!get_path_at_pos(
+                                       (int)event->button.x,(int)event->button.y,      // x, y
+                                       path, // TreeModel::Path&
+                                       column, //TreeViewColumn*&
+                                       cell_x,cell_y //int&cell_x,int&cell_y
+                                       )
+                               ) break;
+                               
+                               if(!get_model()->get_iter(path))
+                                       break;
+                               
+                               Gtk::TreeRow row = *(get_model()->get_iter(path));
+                               
+                               if(column && cellrenderer_time_track==column->get_first_cell_renderer())
+                               {
+                                       Gdk::Rectangle rect;
+                                       get_cell_area(path,*column,rect);
+                                       cellrenderer_time_track->property_value_desc()=row[model.value_desc];
+                                       cellrenderer_time_track->property_canvas()=row[model.canvas];
+                                       cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                                       queue_draw();
+                                       queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                                       return true;
+                               }
+                       }
+                       break;
+               default:
+                       break;
+               }
+               mimic_resync();
+               return Gtk::TreeView::on_event(event);
+       }
+
+       void
+       queue_draw_msg()
+       {
+               sinfg::info("*************QUEUE_DRAW***************** (time track view)");
+               Widget::queue_draw();
+       }
+       void set_model(Glib::RefPtr<LayerParamTreeStore> store)
+       {
+               Gtk::TreeView::set_model(store);
+               param_tree_store_=store;
+               cellrenderer_time_track->set_canvas_interface(param_tree_store_->canvas_interface());
+               store->signal_changed().connect(sigc::mem_fun(*this, &TimeTrackView::queue_draw));
+       }
+       
+       void
+       on_waypoint_changed( sinfg::Waypoint waypoint , sinfg::ValueNode::Handle value_node)
+       {
+               sinfgapp::Action::ParamList param_list;
+               param_list.add("canvas",param_tree_store_->canvas_interface()->get_canvas());
+               param_list.add("canvas_interface",param_tree_store_->canvas_interface());
+               param_list.add("value_node",value_node);
+               param_list.add("waypoint",waypoint);
+       //      param_list.add("time",canvas_interface()->get_time());
+       
+               etl::handle<studio::Instance>::cast_static(param_tree_store_->canvas_interface()->get_instance())->process_action("waypoint_set_smart", param_list);
+       }
+
+       void mimic(Gtk::TreeView *param_tree_view)
+       {       
+               mimic_tree_view=param_tree_view;
+               param_tree_view->signal_row_expanded().connect(
+                       sigc::hide<0>(
+                       sigc::hide_return(
+                               sigc::bind<-1>(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &Gtk::TreeView::expand_row
+                                       ),
+                                       false
+                               )
+                       ))
+               );
+               param_tree_view->signal_row_collapsed().connect(
+                       sigc::hide<0>(
+                       sigc::hide_return(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &Gtk::TreeView::collapse_row
+                                       )
+                       ))
+               );
+               mimic_resync();
+       }
+       
+       void mimic_resync()
+       {
+               
+               if(mimic_tree_view)
+               {
+                       Gtk::Adjustment &adjustment(*mimic_tree_view->get_vadjustment());
+                       set_vadjustment(adjustment);
+                       
+                       if(adjustment.get_page_size()>get_height())
+                               adjustment.set_page_size(get_height());
+                       
+                       cellrenderer_time_track->set_fixed_size(-1,18);
+               }
+       }
+       
+       void
+       on_waypoint_clicked(const Glib::ustring &path_string, sinfg::Waypoint waypoint,int button)
+       {
+/*
+               Gtk::TreePath path(path_string);
+               
+               const Gtk::TreeRow row = *(get_model()->get_iter(path));
+               if(!row)
+                       return;
+*/
+               
+               ValueNode::Handle value_node(waypoint.get_parent_value_node());
+               assert(value_node);
+
+               Gtk::TreeRow row;
+               if(!param_tree_store_->find_first_value_node(value_node, row))
+               {
+                       sinfg::error(__FILE__":%d: Unable to find the valuenode",__LINE__);
+                       return;
+               }
+               
+               if(!row)
+                       return;
+               
+               sinfgapp::ValueDesc value_desc(static_cast<sinfgapp::ValueDesc>(row[model.value_desc]));
+
+               signal_waypoint_clicked(value_desc,waypoint,button);
+       }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_Timetrack::Dock_Timetrack():
+       Dock_CanvasSpecific("timetrack",_("Timetrack"),Gtk::StockID("sinfg-timetrack"))
+{
+       table_=0;
+       widget_timeslider_= new Widget_Timeslider();
+       widget_timeslider_->set_size_request(-1,22);
+       hscrollbar_=new Gtk::HScrollbar();
+       vscrollbar_=new Gtk::VScrollbar();
+}
+
+Dock_Timetrack::~Dock_Timetrack()
+{
+       if(table_)delete table_;
+       delete hscrollbar_;
+       delete vscrollbar_;
+       delete widget_timeslider_;
+}
+
+void
+Dock_Timetrack::init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       LayerParamTreeStore::Model model;
+       
+       Glib::RefPtr<LayerParamTreeStore> tree_store(
+               Glib::RefPtr<LayerParamTreeStore>::cast_dynamic(
+                       canvas_view->get_tree_model("params")
+               )
+       );
+
+       TimeTrackView* tree_view(new TimeTrackView());
+       tree_view->set_canvas_view(canvas_view);
+       tree_view->set_model(tree_store);
+       Gtk::TreeView* param_tree_view(dynamic_cast<Gtk::TreeView*>(canvas_view->get_ext_widget("params")));
+       tree_view->mimic(param_tree_view);
+
+       tree_view->signal_waypoint_clicked.connect(sigc::mem_fun(*canvas_view, &studio::CanvasView::on_waypoint_clicked));
+
+       
+       canvas_view->time_adjustment().signal_value_changed().connect(sigc::mem_fun(*tree_view,&Gtk::TreeView::queue_draw));
+       canvas_view->time_adjustment().signal_changed().connect(sigc::mem_fun(*tree_view,&Gtk::TreeView::queue_draw));
+
+       canvas_view->set_ext_widget(get_name(),tree_view);
+}
+
+void
+Dock_Timetrack::refresh_selected_param()
+{
+/*     Gtk::TreeView* tree_view(
+               static_cast<Gtk::TreeView*>(get_canvas_view()->get_ext_widget(get_name()))
+       );
+       Gtk::TreeModel::iterator iter(tree_view->get_selection()->get_selected());
+       
+       if(iter)
+       {
+               LayerParamTreeStore::Model model;
+               get_canvas_view()->work_area->set_selected_value_node(
+                       (sinfg::ValueNode::Handle)(*iter)[model.value_node]
+               );
+       }
+       else
+       {
+               get_canvas_view()->work_area->set_selected_value_node(0);
+       }
+*/
+}
+
+void
+Dock_Timetrack::changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view)
+{
+       if(table_)
+       {
+               table_->hide();
+               delete table_;
+               hscrollbar_->unset_adjustment();
+               vscrollbar_->unset_adjustment();
+               //widget_timeslider_->unset_adjustment();
+               table_=0;
+       }
+
+       
+       if(canvas_view)
+       {
+               TimeTrackView* tree_view(dynamic_cast<TimeTrackView*>(canvas_view->get_ext_widget(get_name())));
+       Gtk::TreeView* param_tree_view(dynamic_cast<Gtk::TreeView*>(canvas_view->get_ext_widget("params")));
+       tree_view->set_vadjustment(*param_tree_view->get_vadjustment());
+               
+               assert(tree_view);
+
+               widget_timeslider_->set_time_adjustment(&canvas_view->time_adjustment());
+               widget_timeslider_->set_bounds_adjustment(&canvas_view->time_window_adjustment());
+               widget_timeslider_->set_global_fps(canvas_view->get_canvas()->rend_desc().get_frame_rate());
+
+               vscrollbar_->set_adjustment(*tree_view->get_vadjustment());
+               hscrollbar_->set_adjustment(canvas_view->time_window_adjustment());
+               table_=new Gtk::Table(2,2);
+               table_->attach(*widget_timeslider_, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK);
+               table_->attach(*tree_view, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+               table_->attach(*hscrollbar_, 0, 1, 2, 3, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK);
+               table_->attach(*vscrollbar_, 1, 2, 0, 2, Gtk::FILL|Gtk::SHRINK, Gtk::FILL|Gtk::EXPAND);
+               add(*table_);
+               
+               //add(*last_widget_curves_);
+               table_->show_all();
+               show_all();
+       }
+       else
+       {
+               //clear_previous();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dock_timetrack.h b/synfig-studio/trunk/src/gtkmm/dock_timetrack.h
new file mode 100644 (file)
index 0000000..76e0e23
--- /dev/null
@@ -0,0 +1,67 @@
+/* === S I N F G =========================================================== */
+/*!    \file dock_timetrack.h
+**     \brief Template Header
+**
+**     $Id: dock_timetrack.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_TIMETRACK_H
+#define __SINFG_STUDIO_DOCK_TIMETRACK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "dockable.h"
+#include <gtkmm/treeview.h>
+#include "instance.h"
+#include "dock_canvasspecific.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class Widget_Timeslider;
+
+class Dock_Timetrack : public Dock_CanvasSpecific
+{
+       Gtk::HScrollbar* hscrollbar_;
+       Gtk::VScrollbar* vscrollbar_;
+       Widget_Timeslider* widget_timeslider_;
+       Gtk::Table* table_;
+
+protected:
+       virtual void init_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+       virtual void changed_canvas_view_vfunc(etl::loose_handle<CanvasView> canvas_view);
+
+       void refresh_selected_param();
+
+public:
+
+
+       Dock_Timetrack();
+       ~Dock_Timetrack();
+}; // END of Dock_Keyframes
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dockable.cpp b/synfig-studio/trunk/src/gtkmm/dockable.cpp
new file mode 100644 (file)
index 0000000..b3fb489
--- /dev/null
@@ -0,0 +1,399 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockable.cpp
+**     \brief Template File
+**
+**     $Id: dockable.cpp,v 1.2 2005/01/12 07:24:45 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "app.h"
+#include <sigc++/hide.h>
+
+#include "dockable.h"
+#include "dockmanager.h"
+#include "dockbook.h"
+#include "dockdialog.h"
+#include <sinfg/general.h>
+#include <gtkmm/table.h>
+#include <gtk/gtk.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifdef WIN32
+#      ifdef IMAGE_DIR
+#              undef IMAGE_DIR
+#              define IMAGE_DIR "share\\pixmaps"
+#      endif
+#endif
+
+#ifndef IMAGE_DIR
+#      define IMAGE_DIR "/usr/local/share/pixmaps"
+#endif
+
+#ifndef IMAGE_EXT
+#      define IMAGE_EXT        "png"
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dockable::Dockable(const sinfg::String& name,const sinfg::String& local_name,Gtk::StockID stock_id_):
+//     Gtk::Window(Gtk::WINDOW_TOPLEVEL),
+       name_(name),
+       local_name_(local_name),
+//     dialog_settings(this,name),
+       title_label_(local_name,Gtk::ALIGN_LEFT),
+       stock_id_(stock_id_)
+{
+       parent_=0;
+       scrolled_=0;
+       
+       use_scrolled_=true;
+       
+       //set_title(local_name);
+       //set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+       
+
+       title_label_.show();
+
+       attach_dnd_to(title_label_);
+       
+       //scrolled_.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
+       //scrolled_.show();     
+       //scrolled_.set_shadow_type(Gtk::SHADOW_NONE);
+
+       toolbar_=0;
+       //button_box_.show();
+       
+       Gtk::Table* table(this);
+
+       {
+               title_label_.set_padding(0,0);
+               Gtk::EventBox* event_box(manage(new Gtk::EventBox()));
+               event_box->set_border_width(0);
+               event_box->add(title_label_);
+               //table->attach(*event_box, 0, 1, 0,1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+               
+               header_box_.pack_start(*event_box);
+               
+               attach_dnd_to(*event_box);
+               event_box->show();
+       //      event_box->set_events(Gdk::ALL_EVENTS_MASK); //!< \todo change this to only allow what is necessary for DnD
+
+               
+               Gtk::Button* bttn_close(manage(new Gtk::Button("X")));
+               //table->attach(*bttn_close, 1, 2, 0,1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+               header_box_.pack_end(*bttn_close,false,false);
+               bttn_close->show();
+               bttn_close->set_relief(Gtk::RELIEF_NONE);
+               bttn_close->signal_clicked().connect(sigc::mem_fun(*this,&Dockable::detach));
+               bttn_close->set_border_width(0);
+               dynamic_cast<Gtk::Misc*>(bttn_close->get_child())->set_padding(0,0);
+       }
+
+       prev_widget_=manage(new Gtk::Label(" "));
+       
+       //table->attach(header_box_, 0, 1, 0,1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       table->attach(*prev_widget_, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //table->attach(*toolbar_, 0, 1, 2,3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       set_toolbar(*manage(new Gtk::Toolbar));
+       table->show();
+
+       prev_widget_->show();
+
+       set_size_request(175,120);
+       //scrolled_.set_shadow_type(Gtk::SHADOW_NONE);
+       
+}
+
+Dockable::~Dockable()
+{
+       if(scrolled_)
+       {
+               delete scrolled_;
+               scrolled_=0;
+       }
+
+       /*if(App::dock_manager)try{
+               App::dock_manager->unregister_dockable(*this);
+               std::list<Dockable*>::iterator iter;
+               for(iter=App::dock_manager->dockable_list_.begin();iter!=App::dock_manager->dockable_list_.end();++iter)
+                       if(*iter==this)
+                       {
+                               App::dock_manager->dockable_list_.erase(iter);
+                               return;
+                       }
+       } catch(...) { }
+*/
+       //if(App::dock_manager)
+       //      App::dock_manager->dockable_list_.erase(this);
+}
+
+void
+Dockable::attach_dnd_to(Gtk::Widget& widget)
+{
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("DOCK") );
+
+       widget.drag_source_set(listTargets);
+       widget.drag_source_set_icon(get_stock_id());
+       widget.drag_dest_set(listTargets);
+
+
+       widget.signal_drag_data_get().connect(sigc::mem_fun(*this,&Dockable::on_drag_data_get));
+       widget.signal_drag_end().connect(sigc::mem_fun(*this,&Dockable::on_drag_end));
+       widget.signal_drag_begin().connect(sigc::mem_fun(*this,&Dockable::on_drag_begin));
+       widget.signal_drag_data_received().connect(sigc::mem_fun(*this,&Dockable::on_drag_data_received));      
+}
+
+void
+Dockable::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)
+{
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Dockable& dockable(**reinterpret_cast<Dockable**>(const_cast<guint8*>(selection_data.get_data())));
+               
+               if(dockable.parent_ != parent_)
+                       parent_->add(dockable,parent_->page_num(*this));
+               else
+                       parent_->reorder_child(dockable,parent_->page_num(*this));
+               dockable.present();
+               context->drag_finish(true, false, time);
+               return;
+       }
+       
+       context->drag_finish(false, false, time);
+}
+
+void
+Dockable::on_drag_end(const Glib::RefPtr<Gdk::DragContext>&context)
+{
+       if(!dnd_success_)
+       {
+               detach();
+               present();
+       }
+}
+
+void
+Dockable::on_drag_begin(const Glib::RefPtr<Gdk::DragContext>&context)
+{
+       dnd_success_=false;
+}
+
+void
+Dockable::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       Dockable* tmp(this);
+       dnd_success_=true;
+
+       selection_data.set(8, reinterpret_cast<const guchar*>(&tmp), 4);
+}
+
+void
+Dockable::set_local_name(const sinfg::String& local_name)
+{
+       //set_title(local_name);
+       title_label_.set_text(local_name);
+}
+
+void
+Dockable::clear()
+{
+       //if(!toolbar_->children().empty())
+       //      toolbar_->children().clear();
+       set_toolbar(*manage(new Gtk::Toolbar));
+
+}
+
+void
+Dockable::set_toolbar(Gtk::Toolbar& toolbar)
+{
+       if(toolbar_)remove(*toolbar_);
+       toolbar_=0;
+       toolbar_=&toolbar;
+       if(toolbar_)
+       {
+               attach(*toolbar_, 0, 1, 2,3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+               gtk_toolbar_set_icon_size(toolbar_->gobj(),GtkIconSize(1)/*GTK_ICON_SIZE_MENU*/);
+               toolbar_->show();
+       }
+}
+
+bool
+Dockable::clear_previous()
+{
+       prev_widget_=0;
+       prev_widget_delete_connection.disconnect();
+       return false;
+}
+
+void
+Dockable::add(Gtk::Widget& x)
+{
+       if(prev_widget_)
+       {
+               remove(*prev_widget_);
+               //prev_widget_=0;
+               clear_previous();
+       }
+
+       if(scrolled_)
+       {
+               delete scrolled_;
+               scrolled_=0;
+       }
+       
+       if(use_scrolled_)
+       {
+               scrolled_=new Gtk::ScrolledWindow;
+               
+               scrolled_->add(x);
+
+               attach(*scrolled_, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+               
+               x.show();
+       
+               scrolled_->show();
+               
+               scrolled_->set_shadow_type(Gtk::SHADOW_NONE);
+               scrolled_->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC);
+               prev_widget_=scrolled_;
+       }
+       else
+       {
+               attach(x, 0, 1, 1,2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+               x.show();
+               prev_widget_=&x;
+       }
+       prev_widget_delete_connection=prev_widget_->signal_delete_event().connect(
+               sigc::hide(
+                       sigc::mem_fun(
+                               *this,
+                               &Dockable::clear_previous
+                       )
+               )
+       );
+}
+
+Gtk::ToolButton*
+Dockable::add_button(const Gtk::StockID& stock_id, const sinfg::String& tooltip)
+{
+       if(!toolbar_)
+               set_toolbar(*manage(new Gtk::Toolbar));
+
+       //Gtk::IconSize iconsize(4);
+       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("sinfg-small_icon"));
+
+       Gtk::ToolButton* ret(manage(new Gtk::ToolButton(stock_id)));
+       //Gtk::Image* icon(manage(new Gtk::Image(stock_id,iconsize)));
+       //ret->add(*icon);
+       //ret->set_relief(Gtk::RELIEF_HALF);
+       //ret->set_relief(Gtk::RELIEF_NONE);
+       ret->set_label(tooltip);
+       //toolbar_->get_tooltips_object()->set_tip(*ret,tooltip);
+
+       ret->show();
+       //icon->show();
+       toolbar_->set_tooltips(true);
+       
+       toolbar_->append(*ret);
+       //button_box_.pack_start(*ret,false,false);
+       //get_action_area()->pack_start(*ret,false,false);
+       //add_action_widget(*ret,1);
+       return ret;
+}
+
+
+void
+Dockable::detach()
+{
+       if(parent_)
+               parent_->remove(*this);
+}
+
+void
+Dockable::present()
+{
+       if(parent_)
+       {
+               parent_->set_current_page(parent_->page_num(*this));
+               parent_->present();
+       }
+       else
+       {
+               DockDialog* dock_dialog(new DockDialog());
+               dock_dialog->get_dock_book().add(*this);
+               //if(get_name()=="canvases")
+               //      dock_dialog->set_composition_selector(true);
+               dock_dialog->present();
+       }
+}
+
+Gtk::Widget*
+Dockable::create_tab_label()
+{
+       Gtk::EventBox* event_box(manage(new Gtk::EventBox()));
+       
+       attach_dnd_to(*event_box);
+       
+       {
+               Gtk::StockID stock_id(get_stock_id());
+               Gtk::StockItem item;
+               
+               // Check to make sure the icon is valid
+               if(Gtk::Stock::lookup(stock_id,item))
+               {
+                       Gtk::Image* icon(manage(new Gtk::Image(stock_id,Gtk::IconSize(4))));
+                       event_box->add(*icon);
+                       tooltips_.set_tip(*event_box,get_local_name());
+                       icon->show();
+               }
+               else
+               {
+                       // Bad icon, try to make a label
+                       
+                       Glib::ustring text(get_local_name());
+
+                       Gtk::Label* label(manage(new Gtk::Label(text)));
+                       event_box->add(*label);
+                       label->show();
+               }
+       }
+       
+       return event_box;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dockable.h b/synfig-studio/trunk/src/gtkmm/dockable.h
new file mode 100644 (file)
index 0000000..940fe54
--- /dev/null
@@ -0,0 +1,145 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockable.h
+**     \brief Template Header
+**
+**     $Id: dockable.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCKABLE_H
+#define __SINFG_STUDIO_DOCKABLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/stockid.h>
+#include <gtkmm/button.h>
+#include "dialogsettings.h"
+#include <sinfg/string.h>
+#include <gtkmm/table.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/handlebox.h>
+#include <gtkmm/box.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/toolbar.h>
+#include <gtkmm/toolbutton.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+class DockManager;
+class DockBook;
+       
+class Dockable : public Gtk::Table
+{
+       friend class DockManager;
+       friend class DockBook;
+
+       
+       sigc::signal<void> signal_stock_id_changed_;
+       SigC::Connection prev_widget_delete_connection;
+protected:
+       
+//     DialogSettings dialog_settings;
+
+
+private:
+
+       Gtk::Toolbar *toolbar_;
+
+       sinfg::String name_;
+       sinfg::String local_name_;
+       Gtk::Tooltips tooltips_;
+       Gtk::Frame frame_;
+       Gtk::Label title_label_;
+       //Gtk::HBox button_box_;
+       Gtk::HBox header_box_;
+       //Gtk::VBox vbox_;
+       
+       //Gtk::HandleBox handle_box_;
+       Gtk::ScrolledWindow *scrolled_;
+       Gtk::Widget *prev_widget_;
+
+       bool use_scrolled_;
+       
+       Gtk::StockID stock_id_;
+
+       DockBook* parent_;
+
+       bool dnd_success_;
+
+public:
+       //Gtk::VBox* get_vbox() { return &vbox_; }
+
+       void set_toolbar(Gtk::Toolbar& toolbar);
+
+       void set_use_scrolled(bool x) { use_scrolled_=x; }
+       
+       Dockable(const sinfg::String& name,const sinfg::String& local_name,Gtk::StockID stock_id_=Gtk::StockID(" "));
+       ~Dockable();
+
+       sigc::signal<void>& signal_stock_id_changed() { return signal_stock_id_changed_; }
+
+       const sinfg::String& get_name()const { return name_; }
+       const sinfg::String& get_local_name()const { return local_name_; }
+
+       const Gtk::StockID& get_stock_id()const { return stock_id_; }
+       void set_stock_id(Gtk::StockID x) { stock_id_=x; signal_stock_id_changed()(); }
+       
+       void set_local_name(const sinfg::String&);
+
+       void clear();
+       
+       Gtk::Tooltips& get_tooltips() { return tooltips_; }
+       
+       //DialogSettings& settings() { return dialog_settings; }
+       //const DialogSettings& settings()const { return dialog_settings; }
+       
+       void add(Gtk::Widget& x);
+       
+       Gtk::ToolButton* add_button(const Gtk::StockID& stock_id, const sinfg::String& tooltip=sinfg::String());        
+       
+       void detach();
+
+       void present();
+       
+       void attach_dnd_to(Gtk::Widget& widget);
+
+       bool clear_previous();
+       virtual Gtk::Widget* create_tab_label();
+
+private:
+       
+       void on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&, Gtk::SelectionData& selection_data, guint info, guint time);
+       void on_drag_end(const Glib::RefPtr<Gdk::DragContext>&context);
+       void on_drag_begin(const Glib::RefPtr<Gdk::DragContext>&context);
+       void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time);
+
+}; // END of studio::Dockable
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dockbook.cpp b/synfig-studio/trunk/src/gtkmm/dockbook.cpp
new file mode 100644 (file)
index 0000000..f9660ec
--- /dev/null
@@ -0,0 +1,252 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockbook.cpp
+**     \brief Template File
+**
+**     $Id: dockbook.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dockbook.h"
+#include "dockable.h"
+#include "app.h"
+#include "dockmanager.h"
+
+#include <gtkmm/image.h>
+#include <gtkmm/eventbox.h>
+#include <gtkmm/menu.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+DockBook::DockBook()
+{
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("DOCK") );
+
+       drag_dest_set(listTargets);
+       //set_sensitive(true);
+       set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
+       //add_events(Gdk::ALL_EVENTS_MASK);
+       //set_extension_events(Gdk::EXTENSION_EVENTS_ALL);
+       set_show_tabs(true);
+       deleting_=false;
+}
+
+DockBook::~DockBook()
+{
+       deleting_=true;
+       clear();
+}
+
+void
+DockBook::clear()
+{
+       while(get_n_pages())
+       {
+               remove(static_cast<Dockable&>(*get_nth_page(get_n_pages()-1)));
+       }
+}
+
+void
+DockBook::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)
+{
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Dockable& dockable(**reinterpret_cast<Dockable**>(const_cast<guint8*>(selection_data.get_data())));
+               if(dockable.parent_!=this)
+                       add(dockable);
+               dockable.present();
+               context->drag_finish(true, false, time);
+               return;
+       }
+       
+       context->drag_finish(false, false, time);
+}
+
+void
+DockBook::add(Dockable& dockable, int position)
+{
+       dockable.detach();
+       
+       if(position==-1)
+               append_page(dockable, " ");
+       else
+               insert_page(dockable, " ", position);
+
+       refresh_tab(&dockable);
+
+       dockable.signal_stock_id_changed().connect(
+               sigc::bind(
+                       sigc::mem_fun(
+                               *this,
+                               &DockBook::refresh_tab
+                       ),
+                       &dockable
+               )
+       );
+       
+       dockable.parent_=this;
+
+       dockable.show();
+
+       //set_current_page(get_n_pages()-1);
+               
+       signal_changed_();
+}
+
+void
+DockBook::refresh_tab(Dockable* dockable)
+{
+       Gtk::Widget* label(dockable->create_tab_label());
+       
+       label->signal_button_press_event().connect(
+               sigc::bind(
+                       sigc::mem_fun(
+                               *this,
+                               &DockBook::tab_button_pressed
+                       ),
+                       dockable
+               )
+       );
+
+       set_tab_label(*dockable, *label);
+       label->show();
+}
+
+
+void
+DockBook::remove(Dockable& dockable)
+{
+       dockable.hide();
+       remove_page(dockable);
+       dockable.parent_=0;
+
+       if(!deleting_)
+       {
+               signal_changed_();
+       
+               if(get_n_pages()==0)
+                       signal_empty()();
+       }
+}
+
+void
+DockBook::present()
+{
+       show();
+}
+
+sinfg::String
+DockBook::get_local_contents()const
+{
+       sinfg::String ret;
+       
+       for(int i(0);i!=const_cast<DockBook*>(this)->get_n_pages();i++)
+       {
+               Dockable& dockable(static_cast<Dockable&>(*const_cast<DockBook*>(this)->get_nth_page(i)));
+               
+               if(i)
+                       ret+=", ";
+               ret+=dockable.get_local_name();
+       }
+       
+       return ret;
+}
+
+sinfg::String
+DockBook::get_contents()const
+{
+       sinfg::String ret;
+       
+       for(int i(0);i!=const_cast<DockBook*>(this)->get_n_pages();i++)
+       {
+               Dockable& dockable(static_cast<Dockable&>(*const_cast<DockBook*>(this)->get_nth_page(i)));
+               
+               if(i)
+                       ret+=' ';
+               ret+=dockable.get_name();
+       }
+       
+       return ret;
+}
+
+void
+DockBook::set_contents(const sinfg::String& x)
+{
+       sinfg::String str(x);
+       while(!str.empty())
+       {
+               unsigned int separator=str.find_first_of(' ');
+               sinfg::String dock;
+               if(separator==sinfg::String::npos)
+               {
+                       dock=str;
+                       str.clear();
+               }
+               else
+               {
+                       dock=String(str.begin(),str.begin()+separator);
+                       str=String(str.begin()+separator+1,str.end());
+               }
+               
+               try
+               {
+                       add(App::dock_manager->find_dockable(dock));
+               }catch(...) { }
+       }
+}
+
+bool
+DockBook::tab_button_pressed(GdkEventButton* event, Dockable* dockable)
+{
+       if(event->button!=3)
+               return false;
+       
+       Gtk::Menu *tabmenu=manage(new class Gtk::Menu());
+       
+       tabmenu->items().push_back(
+               Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-close"),
+                       sigc::mem_fun(*dockable,&Dockable::detach)
+               )
+       );
+
+       tabmenu->popup(event->button,gtk_get_current_event_time());
+       
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dockbook.h b/synfig-studio/trunk/src/gtkmm/dockbook.h
new file mode 100644 (file)
index 0000000..6ef7478
--- /dev/null
@@ -0,0 +1,88 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockbook.h
+**     \brief Template Header
+**
+**     $Id: dockbook.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCKBOOK_H
+#define __SINFG_STUDIO_DOCKBOOK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/notebook.h>
+#include <sinfg/string.h>
+#include <gtkmm/tooltips.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+class DockManager;
+class Dockable;
+       
+class DockBook : public Gtk::Notebook
+{
+       friend class DockManager;
+       friend class Dockable;
+
+       sigc::signal<void> signal_empty_;
+       sigc::signal<void> signal_changed_;
+       
+       Gtk::Tooltips tooltips_;        
+       
+       bool deleting_;
+       
+protected:
+public:
+       DockBook();
+       ~DockBook();
+
+       sigc::signal<void>& signal_empty() { return signal_empty_; }
+       sigc::signal<void>& signal_changed() { return signal_changed_; }
+
+       void add(Dockable& dockable, int position=-1);
+       void remove(Dockable& dockable);
+
+       void present();
+
+       void clear();
+
+       sinfg::String get_local_contents()const;
+       
+       sinfg::String get_contents()const;
+       void set_contents(const sinfg::String& x);
+
+       void refresh_tabs_headers();
+       
+       void refresh_tab(Dockable*);
+
+       bool tab_button_pressed(GdkEventButton* event, Dockable* dockable);
+       void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time);
+}; // END of studio::DockBook
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dockdialog.cpp b/synfig-studio/trunk/src/gtkmm/dockdialog.cpp
new file mode 100644 (file)
index 0000000..98034d3
--- /dev/null
@@ -0,0 +1,536 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockdialog.cpp
+**     \brief Template File
+**
+**     $Id: dockdialog.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "app.h"
+#include <sigc++/adaptors/hide.h>
+
+#include "dockdialog.h"
+#include "dockbook.h"
+#include "dockmanager.h"
+#include "widget_compselect.h"
+#include <sinfg/general.h>
+#include <sinfg/uniqueid.h>
+#include <gtkmm/table.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+#include "canvasview.h"
+#include <gtkmm/paned.h>
+#include <gtkmm/box.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define GRAB_HINT_DATA(y)      { \
+               String x; \
+               if(sinfgapp::Main::settings().get_value(String("pref.")+y+"_hints",x)) \
+               { \
+                       set_type_hint((Gdk::WindowTypeHint)atoi(x.c_str()));    \
+               } \
+       }
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+DockDialog::DockDialog():
+       Gtk::Window(Gtk::WINDOW_TOPLEVEL)
+{
+       composition_selector_=false;
+       is_deleting=false;
+       is_horizontal=false;
+       last_dock_book=0;
+       box=0;
+       
+       widget_comp_select=new Widget_CompSelect();
+       
+       // Give ourselves an ID that is most likely unique
+       set_id(sinfg::UniqueID().get_uid()^reinterpret_cast<int>(this));
+       
+       // Set up the window
+       //set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
+       set_title("Dock Dialog");
+       GRAB_HINT_DATA("dock_dialog");
+       
+       // Register with the dock manager
+       App::dock_manager->dock_dialog_list_.push_back(this);
+
+       
+       // connect our signals  
+       signal_delete_event().connect(
+               sigc::hide(
+                       sigc::mem_fun(*this,&DockDialog::close)
+               )
+       );
+       
+/*
+       App::signal_canvas_view_focus().connect(
+               sigc::hide(
+                       sigc::mem_fun(
+                               *this,
+                               &DockDialog::refresh_accel_group
+                       )
+               )
+       );
+*/
+
+       add_accel_group(App::ui_manager()->get_accel_group());
+       App::signal_present_all().connect(sigc::mem_fun(*this,&DockDialog::present));
+}
+
+DockDialog::~DockDialog()
+{
+       empty_sig.disconnect();
+
+       is_deleting=true;
+
+       DEBUGPOINT();
+
+       // Remove all of the dock books
+       for(;!dock_book_list.empty();dock_book_list.pop_front())
+       {
+               dock_book_list.front()->clear();
+
+               // UGLY HACK
+               // The following line really should be uncommented,
+               // but it causes crashes. Without it, a small
+               // memory hole is created--but at least it doesn't crash
+               // delete dock_book_list.front();
+               
+               // Oddly enough, the following line should
+               // theoreticly do the same thing after this
+               // class is destroyed, but it doesn't seem to
+               // caues a crash.
+               manage(dock_book_list.front());
+       }
+
+       // Remove us from the dock manager
+       if(App::dock_manager)try{
+               std::list<DockDialog*>::iterator iter;
+               for(iter=App::dock_manager->dock_dialog_list_.begin();iter!=App::dock_manager->dock_dialog_list_.end();++iter)
+                       if(*iter==this)
+                       {
+                               App::dock_manager->dock_dialog_list_.erase(iter);
+                               break;
+                       }
+       }
+       catch(...)
+       {
+               sinfg::warning("DockDialog::~DockDialog(): Exception thrown when trying to remove from dock manager...?");
+       }
+
+       delete widget_comp_select;
+
+       DEBUGPOINT();
+}
+
+void
+DockDialog::drop_on_prepend(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)
+{
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Dockable& dockable(**reinterpret_cast<Dockable**>(const_cast<guint8*>(selection_data.get_data())));
+               prepend_dock_book()->add(dockable);
+               context->drag_finish(true, false, time);
+               return;
+       }
+       
+       context->drag_finish(false, false, time);
+}
+
+void
+DockDialog::drop_on_append(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time)
+{
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Dockable& dockable(**reinterpret_cast<Dockable**>(const_cast<guint8*>(selection_data.get_data())));
+               append_dock_book()->add(dockable);
+               context->drag_finish(true, false, time);
+               return;
+       }
+       
+       context->drag_finish(false, false, time);
+}
+
+
+void
+DockDialog::on_hide()
+{
+       Gtk::Window::on_hide();
+       close();
+}
+
+DockBook*
+DockDialog::prepend_dock_book()
+{
+       if(is_deleting)return 0;
+               
+       dock_book_list.push_front(new DockBook);
+       last_dock_book=dock_book_list.front();
+
+
+       last_dock_book->signal_empty().connect(
+               sigc::bind(
+                       sigc::mem_fun(*this,&DockDialog::erase_dock_book),
+                       last_dock_book
+               )
+       );
+
+       dock_book_sizes_.insert(dock_book_sizes_.begin(),225);
+       refresh();
+       return last_dock_book;
+}
+
+DockBook*
+DockDialog::append_dock_book()
+{
+       if(is_deleting)return 0;
+               
+       dock_book_list.push_back(new DockBook);
+       last_dock_book=dock_book_list.back();
+       last_dock_book->signal_empty().connect(
+               sigc::bind(
+                       sigc::mem_fun(*this,&DockDialog::erase_dock_book),
+                       last_dock_book
+               )
+       );
+       last_dock_book->signal_changed().connect(
+               sigc::mem_fun(*this,&DockDialog::refresh_title)
+       );
+       last_dock_book->signal_changed().connect(
+               sigc::mem_fun(*this,&DockDialog::refresh_title)
+       );
+       dock_book_sizes_.push_back(225);
+
+       //last_dock_book->show();
+       refresh();
+       return last_dock_book;
+}
+
+void
+DockDialog::erase_dock_book(DockBook* dock_book)
+{
+       if(is_deleting)return;
+
+       std::list<DockBook*>::iterator iter;
+       for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter)
+               if(*iter==dock_book)
+               {
+                       dock_book_list.erase(iter);
+
+                       if(dock_book_list.empty())
+                       {
+                               last_dock_book=0;
+                               close();
+                               return;
+                       }
+                       else
+                       {
+                               if(last_dock_book==dock_book)
+                                       last_dock_book=dock_book_list.front();
+                       }
+                       
+                       refresh();
+                       
+                       return;
+               }
+}
+
+void
+DockDialog::refresh()
+{
+       sinfg::info("dock_book_list.size()=%d",dock_book_list.size());
+       //remove();
+
+       if(dock_book_list.empty())
+               return;
+       
+       if(box)delete box;
+       box=(manage(is_horizontal?(Gtk::Box*)new Gtk::HBox:(Gtk::Box*)new Gtk::VBox));
+       add(*box);
+       
+       box->pack_start(*widget_comp_select,false,true);
+
+       Gtk::Button* append_button(manage(new Gtk::Button));
+       Gtk::Button* prepend_button(manage(new Gtk::Button));
+       
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("DOCK") );
+
+       append_button->drag_dest_set(listTargets);
+       prepend_button->drag_dest_set(listTargets);
+
+       append_button->signal_drag_data_received().connect(
+               sigc::mem_fun(*this,&DockDialog::drop_on_append)
+       );
+
+       prepend_button->signal_drag_data_received().connect(
+               sigc::mem_fun(*this,&DockDialog::drop_on_prepend)
+       );
+       
+       box->pack_start(*prepend_button,false,true);
+       box->pack_end(*append_button,false,true);
+
+       //prepend_button->show();
+       //append_button->show();
+       pannels_.clear();
+       
+       if(dock_book_list.size()==1)
+       {
+               box->pack_start(get_dock_book(),true,true);
+       }
+       else
+       {
+               Gtk::Paned* parent(manage(is_horizontal?(Gtk::Paned*)new Gtk::HPaned:(Gtk::Paned*)new Gtk::VPaned));
+               
+               pannels_.push_back(parent);
+               
+               if(pannels_.size()<=dock_book_sizes_.size())
+                       pannels_.back()->set_position(dock_book_sizes_[pannels_.size()-1]);
+               pannels_.back()->property_position().signal_changed().connect(
+                       sigc::mem_fun(*this,&DockDialog::rebuild_sizes)
+               );
+               //parent->show();
+               parent->add1(*dock_book_list.front());
+               //dock_book_list.front()->show();
+        
+               box->pack_start(*parent,true,true);
+               
+               std::list<DockBook*>::iterator iter,next;
+               for(next=dock_book_list.begin(),next++,iter=next++;next!=dock_book_list.end();iter=next++)
+               {
+                       Gtk::Paned* current(manage(is_horizontal?(Gtk::Paned*)new Gtk::HPaned:(Gtk::Paned*)new Gtk::VPaned));
+                       pannels_.push_back(current);
+                       
+                       if(pannels_.size()<=dock_book_sizes_.size())
+                               pannels_.back()->set_position(dock_book_sizes_[pannels_.size()-1]);
+                       pannels_.back()->property_position().signal_changed().connect(
+                               sigc::mem_fun(*this,&DockDialog::rebuild_sizes)
+                       );
+
+
+                       parent->add2(*current);
+
+                       current->add1(**iter);
+                       //(*iter)->show();
+                       //current->show();
+                       
+                       parent=current;
+               }
+               parent->add2(**iter);
+               //(*iter)->show();
+       }
+       
+       box->show_all();
+       if(!composition_selector_)
+               widget_comp_select->hide();
+       rebuild_sizes();
+}
+
+void
+DockDialog::rebuild_sizes()
+{
+       unsigned int i=0;
+       dock_book_sizes_.clear();
+       for(i=0;i<pannels_.size();i++)
+       {
+               dock_book_sizes_.push_back(pannels_[i]->get_position());
+       }
+}
+
+void
+DockDialog::set_dock_book_sizes(const std::vector<int>& new_sizes)
+{
+       unsigned int i=0;
+       for(i=0;i<pannels_.size() && i<new_sizes.size();i++)
+       {
+               pannels_[i]->set_position(new_sizes[i]);
+       }
+       dock_book_sizes_=new_sizes;
+       //rebuild_sizes();
+}
+
+void
+DockDialog::refresh_accel_group()
+{
+/*
+       if(last_accel_group_)
+       {
+               last_accel_group_->unlock();
+               remove_accel_group(last_accel_group_);
+               last_accel_group_=Glib::RefPtr<Gtk::AccelGroup>();
+       }
+       
+       etl::loose_handle<CanvasView> canvas_view(App::get_selected_canvas_view());
+       if(canvas_view)
+       {
+               last_accel_group_=canvas_view->get_accel_group();
+               last_accel_group_->lock();
+               add_accel_group(last_accel_group_);
+       }
+*/
+       etl::loose_handle<CanvasView> canvas_view(App::get_selected_canvas_view());
+       if(canvas_view)
+       {
+               canvas_view->mainmenu.accelerate(*this);
+       }
+}
+
+bool
+DockDialog::close()
+{
+       sinfg::info("DockDialog::close(): DELETED!");
+       empty_sig.disconnect();
+       //get_dock_book().clear();
+       delete this;    
+       return true;
+}
+
+DockBook&
+DockDialog::get_dock_book()
+{
+       if(!last_dock_book)
+               return *append_dock_book();
+       return *last_dock_book;
+}
+
+const DockBook&
+DockDialog::get_dock_book()const
+{
+       return *last_dock_book;
+}
+
+
+sinfg::String
+DockDialog::get_contents()const
+{
+       sinfg::String ret;
+
+       std::list<DockBook*>::const_iterator iter;
+       for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter)
+       {
+               if(!ret.empty())
+                       ret+=is_horizontal?" | ":" - ";
+               ret+=(*iter)->get_contents();
+       }
+               
+       
+       return ret;
+}
+
+void
+DockDialog::set_contents(const sinfg::String& z)
+{
+       int x,y;
+       get_size(x,y);
+
+       sinfg::String str(z);
+       while(!str.empty())
+       {
+               unsigned int separator=str.find_first_of('-');
+               {
+                       unsigned int sep2=str.find_first_of('|');
+                       if(separator!=sinfg::String::npos || sep2!=sinfg::String::npos)
+                       {
+                               if((separator==sinfg::String::npos || sep2<separator) && sep2!=sinfg::String::npos)
+                               {
+                                       separator=sep2;
+                                       is_horizontal=true;
+                               }
+                               else
+                                       is_horizontal=false;
+                       }
+               }
+               
+               sinfg::String book_contents;
+               if(separator==sinfg::String::npos)
+               {
+                       book_contents=str;
+                       str.clear();
+               }
+               else
+               {
+                       book_contents=String(str.begin(),str.begin()+separator);
+                       str=String(str.begin()+separator+1,str.end());
+               }
+               
+               try
+               {
+                       append_dock_book()->set_contents(book_contents);
+               }catch(...) { }
+       }
+
+       resize(x,y);
+}
+
+void
+DockDialog::set_composition_selector(bool x)
+{
+       if(x==get_composition_selector())
+               return;
+       composition_selector_=x;
+       if(x)
+               widget_comp_select->show();
+       else
+               widget_comp_select->hide();
+}
+
+void
+DockDialog::refresh_title()
+{
+       if(is_deleting)return;
+       if(dock_book_list.size())
+       {
+               sinfg::String title;
+
+               std::list<DockBook*>::const_iterator iter;
+               for(iter=dock_book_list.begin();iter!=dock_book_list.end();++iter)
+               {
+                       if(!title.empty())
+                               title+=", ";
+                       title+=(*iter)->get_local_contents();
+               }
+               set_title(title);
+       }
+       else
+               set_title(_("Empty Dock Dialog"));
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dockdialog.h b/synfig-studio/trunk/src/gtkmm/dockdialog.h
new file mode 100644 (file)
index 0000000..52abc55
--- /dev/null
@@ -0,0 +1,127 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockdialog.h
+**     \brief Template Header
+**
+**     $Id: dockdialog.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_DIALOG_H
+#define __SINFG_STUDIO_DOCK_DIALOG_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/stockid.h>
+#include <gtkmm/button.h>
+#include "dialogsettings.h"
+#include <sinfg/string.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/handlebox.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/accelgroup.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Box; class Paned;  };
+namespace studio {
+       
+class DockManager;
+class DockBook;
+class Dockable;
+class Widget_CompSelect;
+class CanvasView;
+       
+class DockDialog : public Gtk::Window
+{
+       friend class DockManager;
+       friend class DockBook;
+       friend class Dockable;
+       SigC::Connection empty_sig;
+
+       bool composition_selector_;
+       
+       bool is_deleting;
+       
+       bool is_horizontal;
+       
+private:
+       std::list<DockBook*> dock_book_list;
+
+       std::vector<Gtk::Paned*>        pannels_;
+       std::vector<int>                        dock_book_sizes_;
+
+
+       DockBook* last_dock_book;
+
+       Widget_CompSelect* widget_comp_select;
+       Gtk::Box *box;
+
+       int id_;
+
+       void on_hide();
+
+       void refresh();
+
+       void refresh_title();
+
+       void set_id(int x) { id_=x; }
+
+       void refresh_accel_group();
+
+       void drop_on_append(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time);
+       void drop_on_prepend(const Glib::RefPtr<Gdk::DragContext>& context, int, int, const Gtk::SelectionData& selection_data, guint, guint time);
+       
+public:
+
+       const std::vector<int>& get_dock_book_sizes()const { return dock_book_sizes_;}
+       void set_dock_book_sizes(const std::vector<int>&);
+       void rebuild_sizes();
+       
+       bool close();
+       
+       int get_id()const { return id_; }
+       
+       DockBook* append_dock_book();
+       DockBook* prepend_dock_book();
+       void erase_dock_book(DockBook*);
+       
+       void set_composition_selector(bool x);
+       bool get_composition_selector()const { return composition_selector_; }
+       
+       DockDialog();
+       ~DockDialog();
+
+       DockBook& get_dock_book();
+       const DockBook& get_dock_book()const;
+
+       sinfg::String get_contents()const;
+       void set_contents(const sinfg::String& x);
+}; // END of studio::DockDialog
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/dockmanager.cpp b/synfig-studio/trunk/src/gtkmm/dockmanager.cpp
new file mode 100644 (file)
index 0000000..503aba2
--- /dev/null
@@ -0,0 +1,308 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockmanager.cpp
+**     \brief Template File
+**
+**     $Id: dockmanager.cpp,v 1.2 2005/01/12 07:03:42 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dockmanager.h"
+#include <stdexcept>
+#include "dockable.h"
+#include "dockdialog.h"
+#include <sinfgapp/settings.h>
+#include <sinfgapp/main.h>
+#include <gdkmm/general.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+class studio::DockSettings : public sinfgapp::Settings
+{
+       DockManager* dock_manager;
+       
+public:
+       DockSettings(DockManager* dock_manager):dock_manager(dock_manager)
+       {
+               sinfgapp::Main::settings().add_domain(this,"dock");
+       }
+       
+       virtual ~DockSettings()
+       {
+               sinfgapp::Main::settings().remove_domain("dock");
+       }
+#define SCALE_FACTOR   (1280)
+       virtual bool get_value(const sinfg::String& key_, sinfg::String& value)const
+       {
+               int screen_w(Gdk::screen_width());
+               int screen_h(Gdk::screen_height());
+               
+               if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")try
+               {
+                       sinfg::String key(key_.begin()+7,key_.end());
+                       int separator=key.find_first_of('.');
+                       int id(atoi(sinfg::String(key.begin(),key.begin()+separator).c_str()));
+                       key=sinfg::String(key.begin()+separator+1,key.end());
+                       
+                       DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
+                       
+                       if(key=="contents_size")
+                       {
+                               dock_dialog.rebuild_sizes();
+                               vector<int>::const_iterator iter(dock_dialog.get_dock_book_sizes().begin());
+                               vector<int>::const_iterator end(dock_dialog.get_dock_book_sizes().end());
+                               value.clear();
+                               for(;iter!=end;++iter)
+                                       value+=strprintf("%d ",(*iter)*SCALE_FACTOR/screen_h);
+                               return true;
+                       }
+                       if(key=="pos")
+                       {
+                               int x,y; dock_dialog.get_position(x,y);
+                               value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
+                               return true;
+                       }
+                       if(key=="size")
+                       {
+                               int x,y; dock_dialog.get_size(x,y);
+                               value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
+                               return true;
+                       }
+                       if(key=="contents")
+                       {
+                               value=dock_dialog.get_contents();
+                               return true;
+                       }
+                       if(key=="comp_selector")
+                       {
+                               value=dock_dialog.get_composition_selector()?"1":"0";
+                               return true;
+                       }
+               }catch (...) { return false; }
+               return sinfgapp::Settings::get_value(key_,value);
+       }
+
+       virtual bool set_value(const sinfg::String& key_,const sinfg::String& value)
+       {
+               int screen_w(Gdk::screen_width());
+               int screen_h(Gdk::screen_height());
+
+               if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")
+               {
+                       sinfg::String key(key_.begin()+7,key_.end());
+                       int separator=key.find_first_of('.');
+                       int id(atoi(sinfg::String(key.begin(),key.begin()+separator).c_str()));
+                       key=sinfg::String(key.begin()+separator+1,key.end());
+                       
+                       DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
+
+                       if(key=="contents_size")
+                       {
+                               try {
+                                       
+                               vector<int> data;
+                               int n=0;
+                               String value_(value);
+                               while(value_.size() && (signed)value_.size()>n && n>=0){
+                                       value_=String(value_.begin()+n,value_.end());
+                                       int size;
+                                       if(!strscanf(value_,"%d",&size))
+                                               break;
+                                       size=size*screen_h/SCALE_FACTOR;
+                                       data.push_back(size);
+
+                                       n=value_.find(" ");
+                                       if((unsigned)n!=String::npos)
+                                               n++;
+                                               
+                               }
+                               dock_dialog.set_dock_book_sizes(data);
+                               }
+                               catch(...)
+                               {
+                                       sinfg::error("Exception caught!!!");
+                                       return false;
+                               }
+                               return true;
+                       }
+                       if(key=="pos")
+                       {
+                               int x,y;
+                               if(!strscanf(value,"%d %d",&x, &y))
+                                       return false;
+                               x=x*screen_w/SCALE_FACTOR;
+                               y=y*screen_h/SCALE_FACTOR;
+                               dock_dialog.move(x,y);
+                               return true;
+                       }
+                       if(key=="size")
+                       {
+                               int x,y;
+                               if(!strscanf(value,"%d %d",&x, &y))
+                                       return false;
+                               x=x*screen_w/SCALE_FACTOR;
+                               y=y*screen_h/SCALE_FACTOR;
+                               dock_dialog.set_default_size(x,y);
+                               dock_dialog.resize(x,y);
+                               return true;
+                       }
+                       if(key=="contents")
+                       {
+                               dock_dialog.set_contents(value);
+                               return true;
+                       }
+                       if(key=="comp_selector")
+                       {
+                               if(value.empty() || value[0]=='0')
+                                       dock_dialog.set_composition_selector(false);
+                               else
+                                       dock_dialog.set_composition_selector(true);
+                               return true;
+                       }
+               }
+               return sinfgapp::Settings::set_value(key_,value);
+       }
+       
+       virtual KeyList get_key_list()const
+       {
+               sinfgapp::Settings::KeyList ret(sinfgapp::Settings::get_key_list());
+
+               std::list<DockDialog*>::const_iterator iter;
+               for(iter=dock_manager->dock_dialog_list_.begin();iter!=dock_manager->dock_dialog_list_.end();++iter)
+               {
+                       ret.push_back(strprintf("dialog.%d.contents",(*iter)->get_id()));
+                       ret.push_back(strprintf("dialog.%d.comp_selector",(*iter)->get_id()));
+                       ret.push_back(strprintf("dialog.%d.pos",(*iter)->get_id()));
+                       ret.push_back(strprintf("dialog.%d.size",(*iter)->get_id()));
+                       ret.push_back(strprintf("dialog.%d.contents_size",(*iter)->get_id()));
+               }
+               return ret;
+       }
+};
+
+/* === M E T H O D S ======================================================= */
+
+DockManager::DockManager():
+       dock_settings(new DockSettings(this))
+{
+}
+
+DockManager::~DockManager()
+{
+       while(!dock_dialog_list_.empty())
+       {
+               dock_dialog_list_.back()->close();
+       }
+       while(!dockable_list_.empty())
+       {
+               Dockable* dockable(dockable_list_.back());
+               sinfg::info("DockManager::~DockManager(): Deleting dockable \"%s\"",dockable->get_name().c_str());
+               dockable_list_.pop_back();              
+               delete dockable;
+       }
+}
+
+void
+DockManager::register_dockable(Dockable& x)
+{
+       dockable_list_.push_back(&x);
+       sinfg::info("DockManager::register_dockable(): Registered dockable \"%s\"",dockable_list_.back()->get_name().c_str());
+       signal_dockable_registered()(&x);
+}
+
+bool
+DockManager::unregister_dockable(Dockable& x)
+{
+       std::list<Dockable*>::iterator iter;
+       for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
+       {
+               if(&x==*iter)
+               {
+                       x.detach();
+                       dockable_list_.erase(iter);
+                       sinfg::info("DockManager::unregister_dockable(): \"%s\" has been Unregistered",x.get_name().c_str());
+                       return true;
+               }
+       }
+       return false;
+}
+
+Dockable&
+DockManager::find_dockable(const sinfg::String& x)
+{
+       std::list<Dockable*>::iterator iter;
+       for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
+               if((*iter)->get_name()==x)
+                       return **iter;
+       
+       throw std::runtime_error("DockManager::find_dockable(): not found");
+}
+
+void
+DockManager::present(sinfg::String x)
+{
+       try
+       {
+               find_dockable(x).present();
+       }
+       catch(...)
+       {
+       }
+}
+
+DockDialog&
+DockManager::find_dock_dialog(int id)
+{
+       std::list<DockDialog*>::iterator iter;
+       for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
+               if((*iter)->get_id()==id)
+                       return **iter;
+
+       DockDialog* dock_dialog(new DockDialog());
+       dock_dialog->set_id(id);
+       dock_dialog->show();
+       return *dock_dialog;
+}
+
+const DockDialog&
+DockManager::find_dock_dialog(int id)const
+{
+       std::list<DockDialog*>::const_iterator iter;
+       for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
+               if((*iter)->get_id()==id)
+                       return **iter;
+       
+       throw std::runtime_error("DockManager::find_dock_dialog(int id)const: not found");
+}
diff --git a/synfig-studio/trunk/src/gtkmm/dockmanager.h b/synfig-studio/trunk/src/gtkmm/dockmanager.h
new file mode 100644 (file)
index 0000000..6a6765a
--- /dev/null
@@ -0,0 +1,81 @@
+/* === S I N F G =========================================================== */
+/*!    \file dockmanager.h
+**     \brief Template Header
+**
+**     $Id: dockmanager.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DOCKMANAGER_H
+#define __SINFG_DOCKMANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <vector>
+#include <list>
+#include <sinfg/string.h>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <ETL/smart_ptr>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dockable;
+class DockDialog;
+class DockSettings;
+       
+class DockManager : public sigc::trackable
+{
+       friend class Dockable;
+       friend class DockDialog;
+       friend class DockSettings;
+               
+       std::list<Dockable*> dockable_list_;
+       std::list<DockDialog*> dock_dialog_list_;
+
+       sigc::signal<void,Dockable*> signal_dockable_registered_;
+       
+       etl::smart_ptr<DockSettings> dock_settings;
+
+public:
+       DockManager();
+       ~DockManager();
+
+       DockDialog& find_dock_dialog(int id);
+       const DockDialog& find_dock_dialog(int id)const;
+
+       sigc::signal<void,Dockable*>& signal_dockable_registered() { return signal_dockable_registered_; }
+
+       void register_dockable(Dockable& x);
+       bool unregister_dockable(Dockable& x);
+       Dockable& find_dockable(const sinfg::String& x);
+       void present(sinfg::String x);
+       
+}; // END of class DockManager
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/duck.cpp b/synfig-studio/trunk/src/gtkmm/duck.cpp
new file mode 100644 (file)
index 0000000..f540c3d
--- /dev/null
@@ -0,0 +1,193 @@
+/* === S I N F G =========================================================== */
+/*!    \file duck.cpp
+**     \brief Template File
+**
+**     $Id: duck.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "duck.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+int studio::Duck::duck_count(0);
+
+struct _DuckCounter
+{
+       static int counter;
+       ~_DuckCounter()
+       {
+               if(counter)
+                       sinfg::error("%d ducks not yet deleted!",counter);
+       }
+} _duck_counter;
+
+int _DuckCounter::counter(0);
+
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Duck::Duck():
+       origin(0,0),
+       scalar(1),
+       editable(false),
+       radius_(false),
+       tangent_(false)
+{ duck_count++; _DuckCounter::counter++; }
+
+Duck::Duck(const sinfg::Point &point):
+       type_(TYPE_NONE),
+       point(point),
+       origin(0,0),
+       scalar(1),
+       guid_(0),
+       editable(false),
+       radius_(false),
+       tangent_(false)
+{ duck_count++; _DuckCounter::counter++;}
+
+Duck::Duck(const sinfg::Point &point,const sinfg::Point &origin):
+       point(point),
+       origin(origin),
+       scalar(1),
+       guid_(0),
+       editable(false),
+       radius_(true),
+       tangent_(false)
+{ duck_count++; _DuckCounter::counter++;}
+
+Duck::~Duck() { duck_count--; _DuckCounter::counter--;}
+
+sinfg::GUID
+Duck::get_data_guid()const
+{
+       if(value_desc_.is_value_node())
+               return value_desc_.get_value_node()->get_guid();
+       return GUID::hasher(get_name());
+}
+
+void
+Duck::set_name(const sinfg::String &x)
+{
+       name=x;
+       if(guid_==GUID::zero())
+       {
+               guid_=GUID::hasher(name);
+       }
+}
+
+
+bool
+Duck::operator==(const Duck &rhs)const
+{
+       if(this==&rhs)
+               return true;
+       return
+               name==rhs.name &&
+               scalar==rhs.scalar &&
+               type_==rhs.type_ &&
+               transform_stack_.size()==rhs.transform_stack_.size();
+               //true;
+               //(origin_duck?*origin_duck==*rhs.origin_duck:origin==rhs.origin) &&
+               //(shared_point?*shared_point==*rhs.shared_point:point==rhs.point) ;
+}
+
+sinfg::Point
+Duck::get_trans_point()const
+{
+       return transform_stack_.perform(get_sub_trans_point());
+}
+       
+void
+Duck::set_trans_point(const sinfg::Point &x)
+{
+       set_sub_trans_point(transform_stack_.unperform(x));
+}
+
+//! Sets the origin point.
+void
+Duck::set_origin(const sinfg::Point &x)
+{
+       origin=x; origin_duck=0;
+}
+
+//! Sets the origin point as another duck
+void
+Duck::set_origin(const etl::handle<Duck> &x)
+{
+       origin_duck=x;
+}
+
+//! Retrieves the origin location
+sinfg::Point
+Duck::get_origin()const
+{
+       return origin_duck?origin_duck->get_point():origin;
+}
+
+//! Retrieves the origin duck
+const etl::handle<Duck> &
+Duck::get_origin_duck() const
+{
+       return origin_duck;
+}
+
+//! Retrieves the origin location
+sinfg::Point
+Duck::get_trans_origin()const
+{
+       return transform_stack_.perform(get_sub_trans_origin());
+}
+
+sinfg::Point
+Duck::get_sub_trans_point()const
+{
+       return get_point()*get_scalar()+get_sub_trans_origin();
+}
+
+void
+Duck::set_sub_trans_point(const sinfg::Point &x)
+{
+       set_point((x-get_sub_trans_origin())/get_scalar());
+}
+
+sinfg::Point
+Duck::get_sub_trans_origin()const
+{
+       return origin_duck?origin_duck->get_sub_trans_point():origin;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/duck.h b/synfig-studio/trunk/src/gtkmm/duck.h
new file mode 100644 (file)
index 0000000..a8fb4fa
--- /dev/null
@@ -0,0 +1,266 @@
+/* === S I N F G =========================================================== */
+/*!    \file duck.h
+**     \brief Template Header
+**
+**     $Id: duck.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_DUCKMATIC_DUCK_H
+#define __SINFG_DUCKMATIC_DUCK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+
+#include <ETL/smart_ptr>
+#include <ETL/handle>
+
+#include <sinfg/vector.h>
+#include <sinfg/string.h>
+#include <sinfg/real.h>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <sinfg/time.h>
+#include <ETL/smart_ptr>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/transform.h>
+
+/* === M A C R O S ========================================================= */
+
+#define HASH_MAP_H <ext/hash_map>
+#define HASH_SET_H <ext/hash_set>
+
+#ifdef HASH_MAP_H
+#include HASH_MAP_H
+#ifndef __STRING_HASH__
+#define __STRING_HASH__
+class StringHash
+{
+       __gnu_cxx::hash<const char*> hasher_;
+public:
+       size_t operator()(const sinfg::String& x)const
+       {
+               return hasher_(x.c_str());
+       }
+};
+#endif
+#else
+#include <map>
+#endif
+
+#include <set>
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class Duckmatic;
+       
+/*! \class Duck
+**     \writeme */
+class Duck : public etl::shared_object
+{
+       friend class Duckmatic;
+               
+public:
+       enum Type
+       {
+               TYPE_NONE               =       (0),
+               TYPE_POSITION   =       (1<<0),
+               TYPE_TANGENT    =       (1<<1),
+               TYPE_RADIUS             =       (1<<2),
+               TYPE_WIDTH              =       (1<<3),
+               TYPE_ANGLE              =       (1<<4),
+               TYPE_VERTEX             =       (1<<5),
+
+               TYPE_ALL                =       (~0),
+
+               TYPE_DEFAULT    =       0xdefadefa
+       };
+
+       typedef etl::handle<Duck> Handle;
+       typedef etl::loose_handle<Duck> LooseHandle;
+       
+private:
+
+       sigc::signal<bool,const sinfg::Point &> signal_edited_;
+       sigc::signal<void> signal_user_click_[5];
+       
+       Type type_;
+
+       sinfg::Point point;
+
+       etl::smart_ptr<sinfg::Point> shared_point;
+       
+       sinfg::Point origin;
+       sinfg::String name;
+       sinfg::Real scalar;
+
+       etl::handle<Duck> origin_duck;
+
+       etl::handle<Duck> connect_duck;
+       etl::handle<Duck> box_duck;
+
+       sinfg::GUID guid_;      
+
+       // Flags
+       bool editable;
+       bool radius_;
+       bool tangent_;
+       
+       sinfg::TransformStack transform_stack_;
+
+       sinfgapp::ValueDesc value_desc_;
+
+       static int duck_count;
+public:
+       Duck();
+       Duck(const sinfg::Point &point);
+       Duck(const sinfg::Point &point,const sinfg::Point &origin);
+       ~Duck();
+               
+       sigc::signal<bool,const sinfg::Point &> &signal_edited() { return signal_edited_; }
+       sigc::signal<void> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
+
+       void set_guid(const sinfg::GUID& x) { guid_=x; }
+       const sinfg::GUID& get_guid()const { return guid_; }
+
+       sinfg::GUID get_data_guid()const;
+
+       //! Changes the editable flag. If set, the duck will not be able to be moved.
+       void set_editable(bool x) { editable=x; }
+
+       //! Retrieves the status of the editable flag
+       bool get_editable()const { return editable; }
+
+       //! \writeme
+       void set_tangent(bool x) { tangent_=x; type_=TYPE_TANGENT; }
+
+       //! \writeme
+       bool get_tangent()const { return tangent_; }
+
+       void set_connect_duck(const etl::handle<Duck>& x) { connect_duck=x; }
+       void set_box_duck(const etl::handle<Duck>& x) { box_duck=x; }
+
+       const etl::handle<Duck>& get_connect_duck()const { return connect_duck; }
+       const etl::handle<Duck>& get_box_duck()const { return box_duck; }
+
+       void set_value_desc(sinfgapp::ValueDesc x) { value_desc_=x; }
+
+       sinfgapp::ValueDesc& get_value_desc() { return value_desc_; }
+
+       void set_transform_stack(const sinfg::TransformStack& x) { transform_stack_=x; }
+
+       const sinfg::TransformStack& get_transform_stack()const { return transform_stack_; }
+       
+       //! \writeme
+       void set_type(Type x) { type_=x; }
+
+       //! \writeme
+       Type get_type()const { return type_; }
+
+       //! Sets the scalar multiplier for the duck with respect to the origin
+       void set_scalar(sinfg::Vector::value_type n) { scalar=n; }
+
+       //! Retrieves the scalar value
+       sinfg::Vector::value_type get_scalar()const { return scalar; }
+
+       void set_shared_point(const etl::smart_ptr<sinfg::Point>&x) { shared_point=x; }
+
+       //! Sets the location of the duck with respect to the origin
+       void set_point(const sinfg::Point &x) { (shared_point?*shared_point:point)=x; }
+               
+       //! Returns the location of the duck
+       sinfg::Point get_point()const { return shared_point?*shared_point:point; }
+       
+       sinfg::Point get_trans_point()const;
+       
+       void set_trans_point(const sinfg::Point &x);
+
+       sinfg::Point get_sub_trans_point()const;
+       void set_sub_trans_point(const sinfg::Point &x);
+       sinfg::Point get_sub_trans_origin()const;
+
+       //! Sets the origin point.
+       void set_origin(const sinfg::Point &x);
+
+       //! Sets the origin point as another duck
+       void set_origin(const etl::handle<Duck> &x);
+
+       //! Retrieves the origin location
+       sinfg::Point get_origin()const;
+       
+       //! Retrieves the origin duck
+       const etl::handle<Duck> & get_origin_duck() const;      
+
+       //! Retrieves the origin location
+       sinfg::Point get_trans_origin()const;
+
+       void set_radius(bool r) { radius_=r; }
+       bool is_radius()const { return radius_; }
+       
+       //! Sets the name of the duck
+       void set_name(const sinfg::String &x);
+
+       //! Retrieves the name of the duck
+       sinfg::String get_name()const { return name; }
+       
+       bool operator==(const Duck &rhs)const;
+}; // END of class Duck
+
+//! Combine Flags
+inline Duck::Type
+operator|(Duck::Type lhs, const Duck::Type rhs)
+{ return static_cast<Duck::Type>(int(lhs)|int(rhs)); }
+
+//! Exclude Flags
+inline Duck::Type
+operator-(Duck::Type lhs, const Duck::Type rhs)
+{ return static_cast<Duck::Type>(int(lhs)&~int(rhs)); }
+
+inline Duck::Type&
+operator|=(Duck::Type& lhs, const Duck::Type rhs)
+{ *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
+
+inline Duck::Type
+operator&(const Duck::Type lhs, const Duck::Type rhs)
+{ return static_cast<Duck::Type>(int(lhs)&int(rhs)); }
+
+class DuckMap : public
+#ifdef HASH_MAP_H
+__gnu_cxx::hash_map<sinfg::GUID,etl::handle<studio::Duck>,sinfg::GUIDHash>
+{
+       typedef __gnu_cxx::hash_map<sinfg::GUID,etl::handle<studio::Duck>,sinfg::GUIDHash> PARENT_TYPE;
+#else
+std::map<sinfg::GUID,etl::handle<studio::Duck> >
+{
+       typedef std::map<sinfg::GUID,etl::handle<studio::Duck> > PARENT_TYPE;
+#endif
+public:
+       void insert(const Duck::Handle& x) { operator[](x->get_guid())=x;  }
+}; // END of class DuckMap
+
+typedef std::list<Duck::Handle> DuckList;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/duckmatic.cpp b/synfig-studio/trunk/src/gtkmm/duckmatic.cpp
new file mode 100644 (file)
index 0000000..a8b2751
--- /dev/null
@@ -0,0 +1,1801 @@
+/* === S I N F G =========================================================== */
+/*!    \file duckmatic.cpp
+**     \brief Template File
+**
+**     $Id: duckmatic.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+
+#include <ETL/hermite>
+
+#include "duckmatic.h"
+#include <sinfgapp/value_desc.h>
+#include <sinfg/general.h>
+#include <sinfg/paramdesc.h>
+#include <sinfg/valuenode_timedswap.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_composite.h>
+#include <sinfg/valuenode_scale.h>
+#include <sinfg/valuenode_bline.h>
+
+#include <sinfg/curve_helper.h>
+
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+#include <sigc++/hide.h>
+#include <sigc++/bind.h>
+
+#include "canvasview.h"
+
+#include "onemoment.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+Duckmatic::Duckmatic():
+       type_mask(Duck::TYPE_ALL-Duck::TYPE_WIDTH),
+       grid_snap(false),
+       guide_snap(false),
+       grid_size(1.0/4.0,1.0/4.0),
+       show_persistant_strokes(true)
+{
+       axis_lock=false;
+       drag_offset_=Point(0,0);
+       clear_duck_dragger();
+}
+
+Duckmatic::~Duckmatic()
+{
+       clear_ducks();
+       //sinfg::info("Duckmatic::~Duckmatic(): Deleted. Duck Count=%d",Duck::duck_count);
+}
+
+void
+Duckmatic::clear_ducks()
+{
+       duck_data_share_map.clear();
+       duck_map.clear();
+
+       //duck_list_.clear();
+       bezier_list_.clear();
+       stroke_list_.clear();
+
+       if(show_persistant_strokes)
+               stroke_list_=persistant_stroke_list_;
+}
+
+//! Returns \a true if the given duck is currently selected
+bool
+Duckmatic::duck_is_selected(const etl::handle<Duck> &duck)const
+{
+       return duck && selected_ducks.count(duck->get_guid());
+}
+
+void
+Duckmatic::set_grid_size(const sinfg::Vector &s)
+{
+       if(grid_size!=s)
+       {
+               grid_size=s;
+               signal_grid_changed();
+       }
+}
+
+void
+Duckmatic::set_grid_snap(bool x)
+{
+       if(grid_snap!=x)
+       {
+               grid_snap=x;
+               signal_grid_changed();
+       }
+}
+
+void
+Duckmatic::set_guide_snap(bool x)
+{
+       if(guide_snap!=x)
+       {
+               guide_snap=x;
+               signal_grid_changed();
+       }
+}
+
+
+
+Duckmatic::GuideList::iterator
+Duckmatic::find_guide_x(sinfg::Point pos, float radius)
+{
+       GuideList::iterator iter,best(guide_list_x_.end());
+       float dist(radius);
+       for(iter=guide_list_x_.begin();iter!=guide_list_x_.end();++iter)
+       {
+               float amount(abs(*iter-pos[0]));
+               if(amount<dist)
+               {
+                       dist=amount;
+                       best=iter;
+               }
+       }
+       return best;
+}
+
+Duckmatic::GuideList::iterator
+Duckmatic::find_guide_y(sinfg::Point pos, float radius)
+{
+       GuideList::iterator iter,best(guide_list_y_.end());
+       float dist(radius);
+       for(iter=guide_list_y_.begin();iter!=guide_list_y_.end();++iter)
+       {
+               float amount(abs(*iter-pos[1]));
+               if(amount<=dist)
+               {
+                       dist=amount;
+                       best=iter;
+               }
+       }
+       return best;
+}
+
+void
+Duckmatic::clear_selected_ducks()
+{
+       selected_ducks.clear();
+       signal_duck_selection_changed_();
+}
+
+etl::handle<Duckmatic::Duck>
+Duckmatic::get_selected_duck()const
+{
+       if(selected_ducks.empty() || duck_map.empty())
+               return 0;
+       return duck_map.find(*selected_ducks.begin())->second;
+}
+
+void
+Duckmatic::refresh_selected_ducks()
+{
+/*
+       std::set<etl::handle<Duck> >::iterator iter;
+       std::set<etl::handle<Duck> > new_set;
+       if(duck_list().empty())
+       {
+               selected_duck_list.clear();
+               signal_duck_selection_changed_();
+               return;
+       }
+       
+       for(iter=selected_duck_list.begin();iter!=selected_duck_list.end();++iter)
+       {
+               etl::handle<Duck> similar(find_similar_duck(*iter));
+               if(similar)
+               {
+                       new_set.insert(similar);
+               }
+       }
+       selected_duck_list=new_set;
+*/
+       GUIDSet old_set(selected_ducks);
+       GUIDSet::const_iterator iter;
+       
+       for(iter=old_set.begin();iter!=old_set.end();++iter)
+       {
+               if(duck_map.count(*iter)==0)
+                       selected_ducks.erase(*iter);
+       }
+
+       signal_duck_selection_changed_();
+}
+
+bool
+Duckmatic::is_duck_group_selectable(const etl::handle<Duck>& x)const
+{
+       const Type type(get_type_mask());
+
+       if(( x->get_type() && (!(type & x->get_type())) ) )
+       {
+               return false;
+       }
+       if(x->get_value_desc().parent_is_layer_param() && type & Duck::TYPE_POSITION)
+       {
+               Layer::Handle layer(x->get_value_desc().get_layer());
+               String layer_name(layer->get_name());
+               if(
+                       layer_name=="outline" ||
+                       layer_name=="region" ||
+                       layer_name=="polygon" ||
+                       layer_name=="curve_gradient"
+               )
+                       return false;
+               if(
+                       (layer_name=="PasteCanvas"||
+                       layer_name=="paste_canvas")
+                       && !layer->get_param("children_lock").get(bool())
+               )
+                       return false;
+       }
+       return true;
+}
+
+void
+Duckmatic::select_all_ducks()
+{
+       DuckMap::const_iterator iter;   
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter)
+               if(is_duck_group_selectable(iter->second))
+                       select_duck(iter->second);
+}
+
+void
+Duckmatic::select_ducks_in_box(const sinfg::Vector& tl,const sinfg::Vector& br)
+{
+       Vector vmin, vmax;
+       vmin[0]=std::min(tl[0],br[0]);
+       vmin[1]=std::min(tl[1],br[1]);
+       vmax[0]=std::max(tl[0],br[0]);
+       vmax[1]=std::max(tl[1],br[1]);
+
+//     Type type(get_type_mask());
+       
+       DuckMap::const_iterator iter;   
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter)
+       {
+               Point p(iter->second->get_trans_point());
+               if(p[0]<=vmax[0] && p[0]>=vmin[0] && p[1]<=vmax[1] && p[1]>=vmin[1])
+               {
+                       if(is_duck_group_selectable(iter->second))
+                               select_duck(iter->second);
+               }
+       }
+}
+
+int
+Duckmatic::count_selected_ducks()const
+{
+       return selected_ducks.size();
+}
+
+void
+Duckmatic::select_duck(const etl::handle<Duck> &duck)
+{
+       if(duck)
+       {
+               selected_ducks.insert(duck->get_guid());
+               signal_duck_selection_changed_();
+       }
+}
+
+DuckList
+Duckmatic::get_selected_ducks()const
+{
+       DuckList ret;
+       GUIDSet::const_iterator iter;
+       const Type type(get_type_mask());
+       
+       for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
+       {
+               const DuckMap::const_iterator d_iter(duck_map.find(*iter));
+               
+               if(d_iter==duck_map.end())
+                       continue;
+       
+               if(( d_iter->second->get_type() && (!(type & d_iter->second->get_type())) ) )
+                       continue;
+
+               ret.push_back(d_iter->second);
+       }
+       return ret;
+}
+
+DuckList
+Duckmatic::get_duck_list()const
+{
+       DuckList ret;
+       DuckMap::const_iterator iter;
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter)
+               ret.push_back(iter->second);
+       return ret;
+}
+
+void
+Duckmatic::unselect_duck(const etl::handle<Duck> &duck)
+{
+       if(duck && selected_ducks.count(duck->get_guid()))
+       {
+               selected_ducks.erase(duck->get_guid());
+               signal_duck_selection_changed_();
+       }
+}
+
+void
+Duckmatic::toggle_select_duck(const etl::handle<Duck> &duck)
+{
+       if(duck_is_selected(duck))
+               unselect_duck(duck);
+       else
+               select_duck(duck);
+}
+
+
+void
+Duckmatic::translate_selected_ducks(const sinfg::Vector& vector)
+{
+       if(duck_dragger_)
+               duck_dragger_->duck_drag(this,vector);
+}
+
+void
+Duckmatic::start_duck_drag(const sinfg::Vector& offset)
+{
+       if(duck_dragger_)
+               duck_dragger_->begin_duck_drag(this,offset);
+
+       //drag_offset_=offset;
+       drag_offset_=find_duck(offset)->get_trans_point();
+}
+
+bool
+Duckmatic::end_duck_drag()
+{
+       if(duck_dragger_)
+               return duck_dragger_->end_duck_drag(this);
+       return false;
+}
+
+Point
+Duckmatic::snap_point_to_grid(const Point& x, float radius)const
+{
+       Point ret(x);
+
+       GuideList::const_iterator guide_x,guide_y;
+       bool has_guide_x(false), has_guide_y(false);
+       
+       guide_x=find_guide_x(ret,radius);
+       if(guide_x!=guide_list_x_.end())
+               has_guide_x=true;
+
+       guide_y=find_guide_y(ret,radius);
+       if(guide_y!=guide_list_y_.end())
+               has_guide_y=true;
+
+       if(get_grid_snap())
+       {
+               Point snap(
+                       floor(ret[0]/get_grid_size()[0]+0.5)*get_grid_size()[0],
+                       floor(ret[1]/get_grid_size()[1]+0.5)*get_grid_size()[1]
+               );
+
+               if(abs(snap[0]-ret[0])<=radius && (!has_guide_x || abs(snap[0]-ret[0])<=abs(*guide_x-ret[0])))
+                       ret[0]=snap[0],has_guide_x=false;
+               if(abs(snap[1]-ret[1])<=radius && (!has_guide_y || abs(snap[1]-ret[1])<=abs(*guide_y-ret[1])))
+                       ret[1]=snap[1],has_guide_y=false;
+       }
+
+       if(guide_snap)
+       {
+               if(has_guide_x)
+                       ret[0]=*guide_x;
+               if(has_guide_y)
+                       ret[1]=*guide_y;
+       }
+       
+       if(axis_lock)
+       {
+               ret-=drag_offset_;
+               if(abs(ret[0])<abs(ret[1]))
+                       ret[0]=0;
+               else
+                       ret[1]=0;
+               ret+=drag_offset_;
+       }
+       
+       return ret;
+}
+
+void
+DuckDrag_Translate::begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& offset)
+{
+       last_translate_=Vector(0,0);
+       {
+               drag_offset_=duckmatic->find_duck(offset)->get_trans_point();
+
+               snap=Vector(0,0);
+       }
+       
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+       
+       positions.clear();
+       for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
+       {
+               Point p((*iter)->get_trans_point());
+               positions.push_back(p);
+       }
+}
+
+bool
+DuckDrag_Translate::end_duck_drag(Duckmatic* duckmatic)
+{
+       if(last_translate_.mag()>0.0001)
+       {
+               duckmatic->signal_edited_selected_ducks();
+               return true;
+       }
+       else
+       {
+               duckmatic->signal_user_click_selected_ducks(0);
+               return false;
+       }
+}
+
+void
+DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)
+{
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       sinfg::Vector vect(duckmatic->snap_point_to_grid(vector)-drag_offset_);
+       int i;
+       
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue;
+               (*iter)->set_trans_point(positions[i]+vect);
+       }
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if((*iter)->get_type()==Duck::TYPE_VERTEX||(*iter)->get_type()==Duck::TYPE_POSITION)continue;
+               (*iter)->set_trans_point(positions[i]+vect);
+       }
+       last_translate_=vect;
+}
+
+
+
+
+
+
+
+
+
+
+void
+Duckmatic::signal_edited_selected_ducks()
+{
+       const DuckList ducks(get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       sinfg::GUIDSet old_set(selected_ducks);
+       
+       // If we have more than 20 things to move, then display
+       // something to explain that it may take a moment
+       smart_ptr<OneMoment> wait; if(ducks.size()>20)wait.spawn();
+               
+       // Go ahead and call everyone's signals
+       for(iter=ducks.begin();iter!=ducks.end();++iter)
+       {
+               if(!(*iter)->signal_edited()((*iter)->get_point()))
+               {
+                       selected_ducks=old_set;
+                       throw String("Bad edit");
+               }
+       }
+       selected_ducks=old_set;
+}
+
+void
+Duckmatic::signal_user_click_selected_ducks(int button)
+{
+       const DuckList ducks(get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       for(iter=ducks.begin();iter!=ducks.end();++iter)
+       {
+               (*iter)->signal_user_click(button)();
+       }
+}
+
+
+
+
+
+void
+Duckmatic::add_duck(const etl::handle<Duck> &duck)
+{
+       //if(!duck_map.count(duck->get_guid()))
+       {
+               if(duck_data_share_map.count(duck->get_data_guid()))
+               {
+                       duck->set_shared_point(duck_data_share_map[duck->get_data_guid()]);
+               }
+               else
+               {
+                       etl::smart_ptr<sinfg::Point> point(new Point(duck->get_point()));
+                       duck->set_shared_point(point);
+                       duck_data_share_map[duck->get_data_guid()]=point;
+               }
+               
+               duck_map.insert(duck);
+       }
+
+       last_duck_guid=duck->get_guid();
+}
+
+void
+Duckmatic::add_bezier(const etl::handle<Bezier> &bezier)
+{
+       bezier_list_.push_back(bezier);
+}
+
+void
+Duckmatic::add_stroke(etl::smart_ptr<std::list<sinfg::Point> > stroke_point_list, const sinfg::Color& color)
+{
+       assert(stroke_point_list);
+
+       std::list<etl::handle<Stroke> >::iterator iter;
+
+       for(iter=stroke_list_.begin();iter!=stroke_list_.end();++iter)
+       {
+               if((*iter)->stroke_data==stroke_point_list)
+                       return;
+       }
+
+       etl::handle<Stroke> stroke(new Stroke());
+
+       stroke->stroke_data=stroke_point_list;
+       stroke->color=color;
+
+       stroke_list_.push_back(stroke); 
+}
+
+void
+Duckmatic::add_persistant_stroke(etl::smart_ptr<std::list<sinfg::Point> > stroke_point_list, const sinfg::Color& color)
+{
+       add_stroke(stroke_point_list,color);
+       persistant_stroke_list_.push_back(stroke_list_.back());
+}
+
+void
+Duckmatic::clear_persistant_strokes()
+{
+       persistant_stroke_list_.clear();
+}
+
+void
+Duckmatic::set_show_persistant_strokes(bool x)
+{
+       if(x!=show_persistant_strokes)
+       {
+               show_persistant_strokes=x;
+               if(x)
+                       stroke_list_=persistant_stroke_list_;
+               else
+                       stroke_list_.clear();
+       }
+}
+
+void
+Duckmatic::erase_duck(const etl::handle<Duck> &duck)
+{
+       duck_map.erase(duck->get_guid());       
+}
+
+etl::handle<Duckmatic::Duck>
+Duckmatic::find_similar_duck(etl::handle<Duck> duck)
+{
+       DuckMap::const_iterator iter(duck_map.find(duck->get_guid()));
+       if(iter!=duck_map.end())
+               return iter->second;
+       return 0;
+               
+/*     std::list<handle<Duck> >::reverse_iterator iter;
+
+       for(iter=duck_list_.rbegin();iter!=duck_list_.rend();++iter)
+       {
+               if(*iter!=duck && **iter==*duck)
+               {
+                       //sinfg::info("Found similar duck! (iter:%08x vs. duck:%08x)",iter->get(), duck.get());
+                       return *iter;
+               }
+       }
+       return 0;
+*/
+}
+
+etl::handle<Duckmatic::Duck>
+Duckmatic::add_similar_duck(etl::handle<Duck> duck)
+{
+       etl::handle<Duck> similar(find_similar_duck(duck));
+       if(!similar)
+       {
+               add_duck(duck);
+               return duck;
+       }
+       return similar;
+}
+
+void
+Duckmatic::erase_bezier(const etl::handle<Bezier> &bezier)
+{
+       std::list<handle<Bezier> >::iterator iter;
+
+       for(iter=bezier_list_.begin();iter!=bezier_list_.end();++iter)
+       {
+               if(*iter==bezier)
+               {
+                       bezier_list_.erase(iter);
+                       return;
+               }
+       }
+       sinfg::warning("Unable to find bezier to erase!");
+}
+
+etl::handle<Duckmatic::Duck>
+Duckmatic::last_duck()const
+{
+       DuckMap::const_iterator iter(duck_map.find(last_duck_guid));
+       if(iter!=duck_map.end())
+               return iter->second;
+       return 0;
+}
+
+etl::handle<Duckmatic::Bezier>
+Duckmatic::last_bezier()const
+{
+       return bezier_list_.back();
+}
+
+
+etl::handle<Duckmatic::Duck>
+Duckmatic::find_duck(sinfg::Point point, sinfg::Real radius, Duck::Type type)
+{
+       if(radius==0)radius=10000000;
+       
+       if(type==Duck::TYPE_DEFAULT)
+               type=get_type_mask();
+       
+       Real closest(10000000);
+       etl::handle<Duck> ret;
+
+       DuckMap::const_iterator iter;
+
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter)
+       {
+               const Duck::Handle& duck(iter->second);
+               
+               if(!duck->get_editable())
+                       continue;
+               Real dist((duck->get_trans_point()-point).mag_squared());
+
+               if(duck->get_type()&Duck::TYPE_VERTEX)
+                       dist*=1.0001;
+
+               if(dist<=closest && !( duck->get_type() && (!(type & duck->get_type())) ) )
+               {
+                       {
+                               closest=dist;
+                               ret=duck;
+                       }
+               }
+       }
+
+       if(radius==0 || closest<radius*radius)
+               return ret;
+
+       return 0;
+}
+
+etl::handle<Duckmatic::Bezier>
+Duckmatic::find_bezier(sinfg::Point point, sinfg::Real radius,float* location)
+{
+       return find_bezier(point,radius,radius,location);       
+}
+
+etl::handle<Duckmatic::Bezier> 
+Duckmatic::find_bezier(sinfg::Point pos, sinfg::Real scale, sinfg::Real radius, float* location)
+{
+       if(radius==0)radius=10000000;
+       Real closest(10000000);
+       etl::handle<Bezier> ret;
+       
+       bezier<Point>   curve;
+       
+       Real    d,step;
+       float   time = 0;
+       float   best_time = 0;
+       
+       for(std::list<handle<Bezier> >::const_iterator iter=bezier_list().begin();iter!=bezier_list().end();++iter)
+       {
+               curve[0] = (*iter)->p1->get_trans_point();
+               curve[1] = (*iter)->c1->get_trans_point();
+               curve[2] = (*iter)->c2->get_trans_point();
+               curve[3] = (*iter)->p2->get_trans_point();
+               curve.sync();
+               
+#if 0
+               // I don't know why this doesn't work
+               time=curve.find_closest(pos,6);
+               d=((curve(time)-pos).mag_squared());
+
+#else          
+               //set the step size based on the size of the picture
+               d = (curve[1] - curve[0]).mag() + (curve[2]-curve[1]).mag()     + (curve[3]-curve[2]).mag();
+               
+               step = d/(2*scale); //want to make the distance between lines happy
+               
+               step = max(step,0.01); //100 samples should be plenty
+               step = min(step,0.1); //10 is minimum           
+               
+               d = find_closest(curve,pos,step,&closest,&time);
+#endif
+
+               if(d < closest)
+               {
+                       closest = d;
+                       ret = *iter;
+                       best_time=time;
+               }               
+       }
+
+       if(closest < radius*radius)
+       {
+               if(location)
+                       *location = best_time;  // We need to square-root this because we were dealing with squared distances
+               
+               return ret;
+       }
+       
+       return 0;       
+}
+
+
+
+bool
+Duckmatic::save_sketch(const sinfg::String& filename)const
+{
+       std::ofstream file(filename.c_str());
+
+       if(!file)return false;
+
+       file<<"SKETCH"<<endl;
+       
+       std::list<etl::handle<Stroke> >::const_iterator iter;
+       
+       for(iter=persistant_stroke_list_.begin();iter!=persistant_stroke_list_.end();++iter)
+       {
+               file<<"C "
+                       <<(*iter)->color.get_r()<<' '
+                       <<(*iter)->color.get_g()<<' '
+                       <<(*iter)->color.get_b()
+               <<endl;
+               std::list<sinfg::Point>::const_iterator viter;
+               for(viter=(*iter)->stroke_data->begin();viter!=(*iter)->stroke_data->end();++viter)
+               {
+                       file<<"V "
+                               <<(*viter)[0]<<' '
+                               <<(*viter)[1]
+                       <<endl;
+               }
+       }
+       if(!file)return false;
+       sketch_filename_=filename;
+       signal_sketch_saved_();
+       return true;
+}
+
+bool
+Duckmatic::load_sketch(const sinfg::String& filename)
+{
+       std::ifstream file(filename.c_str());
+                       
+       if(!file)
+               return false;
+
+       std::string line;
+       getline(file,line);
+
+       if(line!="SKETCH")
+       {
+               sinfg::error("Not a sketch");
+               return false;
+       }
+
+
+       etl::smart_ptr<std::list<sinfg::Point> > stroke_data;
+       
+       while(file)
+       {
+               getline(file,line);
+
+               if(line.empty())
+                       continue;
+               
+               switch(line[0])
+               {
+               case 'C':
+               case 'c':
+                       {
+                               stroke_data.spawn();
+                               float r,g,b;
+                               if(!strscanf(line,"C %f %f %f",&r, &g, &b))
+                               {
+                                       sinfg::warning("Bad color line \"%s\"",line.c_str());
+                                       r=0;g=0;b=0;
+                               }
+                               add_persistant_stroke(stroke_data, sinfg::Color(r,g,b));
+                       }
+                       break;
+               case 'V':
+               case 'v':
+                       if(!stroke_data)
+                       {
+                               stroke_data.spawn();
+                               add_persistant_stroke(stroke_data, sinfg::Color(0,0,0));
+                       }
+                       float x,y;
+                       if(!strscanf(line,"V %f %f",&x, &y))
+                               sinfg::warning("Bad vertex \"%s\"",line.c_str());
+                       else
+                               stroke_data->push_back(sinfg::Vector(x,y));
+                       break;
+               default:
+                       sinfg::warning("Unexpected sketch token '%c'",line[0]);
+                       break;
+               }
+       }
+       
+       sketch_filename_=filename;
+       return true;
+}
+
+
+
+
+
+
+
+
+Duckmatic::Push::Push(Duckmatic *duckmatic_):
+       duckmatic_(duckmatic_)
+{
+       duck_map=duckmatic_->duck_map;  
+       bezier_list_=duckmatic_->bezier_list_;  
+       duck_data_share_map=duckmatic_->duck_data_share_map;
+       stroke_list_=duckmatic_->stroke_list_;
+       duck_dragger_=duckmatic_->duck_dragger_;
+       needs_restore=true;
+}
+
+Duckmatic::Push::~Push()
+{
+       if(needs_restore)
+               restore();
+}
+
+void
+Duckmatic::Push::restore()
+{
+       duckmatic_->duck_map=duck_map;  
+       duckmatic_->bezier_list_=bezier_list_;  
+       duckmatic_->duck_data_share_map=duck_data_share_map;
+       duckmatic_->stroke_list_=stroke_list_;
+       duckmatic_->duck_dragger_=duck_dragger_;
+       needs_restore=false;
+}
+
+
+
+
+
+
+
+
+
+inline String guid_string(const sinfgapp::ValueDesc& x)
+{
+       if(x.parent_is_layer_param())
+               return strprintf("%s",x.get_layer()->get_guid().get_string().c_str())+x.get_param_name();               
+       //if(x.is_value_node())
+               return strprintf("%s",x.get_value_node()->get_guid().get_string().c_str());
+}
+
+inline GUID calc_duck_guid(const sinfgapp::ValueDesc& x,const sinfg::TransformStack& transform_stack)
+{
+       GUID ret(0);
+       
+       if(x.parent_is_layer_param())
+       {
+               ret=x.get_layer()->get_guid()^GUID::hasher(x.get_param_name());
+       }
+       else
+       {
+               ret=x.get_value_node()->get_guid();
+       }
+
+       ret^=transform_stack.get_guid();
+       return ret;     
+}
+
+/*
+Duck::Handle
+Duckmatic::create_duck_from(const sinfgapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const sinfg::TransformStack& transform_stack, int modifier, sinfg::ParamDesc *param_desc)
+{
+       GUID duck_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(modifier));
+       etl::handle<Duck> duck=new Duck();
+       
+       return duck;
+}
+*/
+
+bool
+Duckmatic::add_to_ducks(const sinfgapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const sinfg::TransformStack& transform_stack, sinfg::ParamDesc *param_desc, int multiple)
+{
+       ValueBase::Type type=value_desc.get_value_type();
+#define REAL_COOKIE            reinterpret_cast<sinfg::ParamDesc*>(28)         
+       switch(type)
+       {
+       case ValueBase::TYPE_REAL:
+               
+               if(!param_desc || param_desc==REAL_COOKIE || !param_desc->get_origin().empty())
+               {
+                       etl::handle<Duck> duck=new Duck();
+                       duck->set_transform_stack(transform_stack);
+                       duck->set_radius(true);
+                       duck->set_type(Duck::TYPE_RADIUS);
+
+                       duck->set_point(Point(value_desc.get_value(get_time()).get(Real()),0));
+                       duck->set_name(guid_string(value_desc));
+                       if(value_desc.is_value_node())
+                       {
+                               // If the ValueNode can be directly manipulated,
+                               // then set it as so.
+                               duck->set_editable(sinfgapp::is_editable(value_desc.get_value_node()));
+                       }
+                       else
+                       {
+                               duck->set_editable(true);
+                       }
+                       
+                       if(param_desc && param_desc!=REAL_COOKIE)
+                       {
+                               if(!param_desc->get_origin().empty())
+                               {
+                                       sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                       /*
+                                       duck->set_origin(value_desc_origin.get_value(get_time()).get(sinfg::Point()));
+                                       */
+                                       add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                       duck->set_origin(last_duck());
+                               }
+                               duck->set_scalar(param_desc->get_scalar());
+                       }
+
+                       duck->signal_edited().clear();
+                       duck->signal_edited().connect(
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               *canvas_view,
+                                               &studio::CanvasView::on_duck_changed
+                                       ),
+                                       value_desc
+                               )
+                       );
+                       duck->set_value_desc(value_desc);
+
+                       duck->signal_user_click(2).connect(
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_view,
+                                                       &studio::CanvasView::popup_param_menu
+                                               ),
+                                               0.0f
+                                       ),
+                                       value_desc
+                               )       
+                       );
+
+                       duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
+                       
+                       add_duck(duck);
+
+                       return true;
+               }
+               break;
+
+       case ValueBase::TYPE_ANGLE:
+               
+               if(!param_desc || param_desc==REAL_COOKIE || !param_desc->get_origin().empty())
+               {
+                       etl::handle<Duck> duck=new Duck();
+                       duck->set_type(Duck::TYPE_ANGLE);
+                       duck->set_transform_stack(transform_stack);
+                       sinfg::Angle angle;
+                       
+                       angle=value_desc.get_value(get_time()).get(Angle());
+                       duck->set_point(Point(Angle::cos(angle).get(),Angle::sin(angle).get()));
+                       duck->set_name(guid_string(value_desc));
+                       if(value_desc.is_value_node())
+                       {
+                               ValueNode::Handle value_node=value_desc.get_value_node();
+                               //duck->set_name(strprintf("%x",value_node.get()));
+                               
+                               // If the ValueNode can be directly manipulated,
+                               // then set it as so.
+                               duck->set_editable(sinfgapp::is_editable(value_desc.get_value_node()));
+                       }
+                       else
+                       {
+                               //angle=(value_desc.get_value().get(Angle()));
+                               //duck->set_point(Point(Angle::cos(angle).get(),Angle::sin(angle).get()));
+                               //duck->set_name(strprintf("%x",value_desc.get_layer().get())+value_desc.get_param_name());
+                               duck->set_editable(true);
+                       }
+                       
+                       if(param_desc && param_desc!=REAL_COOKIE)
+                       {
+                               if(!param_desc->get_origin().empty())
+                               {
+                                       sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                       /*
+                                       duck->set_origin(value_desc_origin.get_value(get_time()).get(sinfg::Point()));
+                                       */
+                                       add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                       duck->set_origin(last_duck());
+                               }
+                               duck->set_scalar(param_desc->get_scalar());
+                       }
+
+                       duck->signal_edited().clear();
+                       duck->signal_edited().connect(
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               *canvas_view,
+                                               &studio::CanvasView::on_duck_changed
+                                       ),
+                                       value_desc
+                               )
+                       );
+                       duck->set_value_desc(value_desc);
+
+                       duck->signal_user_click(2).connect(
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_view,
+                                                       &studio::CanvasView::popup_param_menu
+                                               ),
+                                               0.0f
+                                       ),
+                                       value_desc
+                               )       
+                       );
+                       duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
+
+                       add_duck(duck);
+
+                       return true;
+               }
+               break;
+               
+       case ValueBase::TYPE_VECTOR:
+               {
+                       etl::handle<Duck> duck=new Duck();
+                       duck->set_transform_stack(transform_stack);
+                       
+                       duck->set_point(value_desc.get_value(get_time()).get(Point()));
+                       duck->set_name(guid_string(value_desc));
+                       if(value_desc.is_value_node())
+                       {
+                               //duck->set_name(strprintf("%x",value_desc.get_value_node().get()));
+                               
+                               // If the ValueNode can be directly manipulated,
+                               // then set it as so.
+                               duck->set_editable(sinfgapp::is_editable(value_desc.get_value_node()));
+                       }
+                       else
+                       {
+                               //duck->set_point(value_desc.get_value().get(Point()));
+                               //duck->set_name(strprintf("%x",value_desc.get_layer().get())+value_desc.get_param_name());
+                               duck->set_editable(true);
+                       }
+                       
+                       // If we were passed a parameter description
+                       if(param_desc)
+                       {
+                               if(!param_desc->get_connect().empty())
+                               {
+                                       sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_connect());
+                                       Duck::Handle connect_duck;
+                                       if(duck_map.find(calc_duck_guid(value_desc_origin,transform_stack)^GUID::hasher(0))!=duck_map.end())
+                                       {
+                                               connect_duck=duck_map[calc_duck_guid(value_desc_origin,transform_stack)^GUID::hasher(0)];
+                                       }
+                                       else
+                                       {
+                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                               connect_duck=last_duck();
+                                       }
+                                       duck->set_connect_duck(connect_duck);
+                               }
+                               if(!param_desc->get_box().empty())
+                               {
+                                       sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_box());
+                                       add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                       duck->set_box_duck(last_duck());
+                               }
+                               
+                               // If we have an origin
+                               if(!param_desc->get_origin().empty())
+                               {
+                                       sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                       /*
+                                       duck->set_origin(value_desc_origin.get_value(get_time()).get(sinfg::Point()));
+                                       */
+                                       add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                       duck->set_origin(last_duck());
+                                       duck->set_type(Duck::TYPE_VERTEX);
+                               }
+                               else
+                                       duck->set_type(Duck::TYPE_POSITION);
+                                       
+                               duck->set_scalar(param_desc->get_scalar());
+                       }
+                       else
+                               duck->set_type(Duck::TYPE_POSITION);
+
+
+                       duck->signal_edited().clear();
+                       duck->signal_edited().connect(
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               *canvas_view,
+                                               &studio::CanvasView::on_duck_changed
+                                       ),
+                                       value_desc
+                               )
+                       );
+                       duck->set_value_desc(value_desc);
+
+                       duck->signal_user_click(2).connect(
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_view,
+                                                       &studio::CanvasView::popup_param_menu
+                                               ),
+                                               1.0f
+                                       ),
+                                       value_desc
+                               )
+                       );
+                       duck->set_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple));
+                       add_duck(duck);
+
+                       return true;
+               }
+               break;
+/*     case ValueBase::TYPE_SEGMENT:
+               {
+                       etl::handle<Bezier> bezier(new Bezier());
+                       ValueNode_Composite::Handle value_node;
+                       
+                       if(value_desc.is_value_node() &&
+                               (value_node=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
+                       )
+                       {
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,0),canvas_view,transform_stack))
+                                       return false;
+                               bezier->p1=last_duck();
+                               bezier->p1->set_type(Duck::TYPE_VERTEX);
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,1),canvas_view,transform_stack))
+                                       return false;
+                               bezier->c1=last_duck();                         
+                               bezier->c1->set_type(Duck::TYPE_TANGENT);
+                               bezier->c1->set_origin(bezier->p1);
+                               bezier->c1->set_scalar(0.33333333333333333);
+                               bezier->c1->set_tangent(true);
+
+                               
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,2),canvas_view,transform_stack))
+                                       return false;
+                               bezier->p2=last_duck();
+                               bezier->p2->set_type(Duck::TYPE_VERTEX);
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,3),canvas_view,transform_stack))
+                                       return false;
+                               bezier->c2=last_duck();                         
+                               bezier->c2->set_type(Duck::TYPE_TANGENT);
+                               bezier->c2->set_origin(bezier->p2);
+                               bezier->c2->set_scalar(-0.33333333333333333);
+                               bezier->c2->set_tangent(true);
+
+                               bezier->signal_user_click(2).connect(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *canvas_view,
+                                                       &studio::CanvasView::popup_param_menu_bezier
+                                               ),
+                                               value_desc
+                                       )
+                               );
+                               
+                               add_bezier(bezier);
+                       }
+                       else if(value_desc.get_value().is_valid())
+                       {
+                               Segment segment=value_desc.get_value();
+                               etl::handle<Duck> duck_p,duck_c;
+                               sinfg::String name;
+                               if(param_desc)
+                               {
+                                       name=param_desc->get_local_name();
+                               }
+                               else
+                               {
+                                       name=guid_string(value_desc);
+                               }
+
+                               duck_p=new class Duck(segment.p1);              
+                               duck_p->set_name(name+".P1");                                   
+                               duck_p->set_type(Duck::TYPE_VERTEX);
+                               add_duck(duck_p);                                               
+
+                               duck_c=new class Duck(segment.t1);              
+                               duck_c->set_name(name+".T1");                                   
+                               duck_c->set_type(Duck::TYPE_TANGENT);
+                               add_duck(duck_c);                                               
+                               duck_c->set_origin(duck_p);
+                               duck_c->set_scalar(0.33333333333333333);
+                               duck_c->set_tangent(true);
+
+                               bezier->p1=duck_p;
+                               bezier->c1=duck_c;
+
+                               duck_p=new class Duck(segment.p2);              
+                               duck_p->set_name(name+".P2");                                   
+                               duck_p->set_type(Duck::TYPE_VERTEX);
+                               add_duck(duck_p);                                               
+
+                               duck_c=new class Duck(segment.t2);              
+                               duck_c->set_type(Duck::TYPE_TANGENT);
+                               duck_c->set_name(name+".T2");                                   
+                               add_duck(duck_c);                                               
+                               duck_c->set_origin(duck_p);
+                               duck_c->set_scalar(-0.33333333333333333);
+                               duck_c->set_tangent(true);
+
+                               bezier->p2=duck_p;
+                               bezier->c2=duck_c;
+                               add_bezier(bezier);
+                       }
+                       
+                       return true;
+               }
+               break;
+*/
+       case ValueBase::TYPE_BLINEPOINT:
+       {
+                       
+               if(value_desc.is_value_node() &&
+                       ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
+               )
+               {
+                       ValueNode_Composite::Handle value_node;
+                       value_node=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node());
+
+                       
+                       if(!add_to_ducks(sinfgapp::ValueDesc(value_node,0),canvas_view,transform_stack))
+                               return false;
+                       etl::handle<Duck> vertex_duck(last_duck());
+                       vertex_duck->set_type(Duck::TYPE_VERTEX);
+                       if(!add_to_ducks(sinfgapp::ValueDesc(value_node,4),canvas_view,transform_stack))
+                               return false;
+                       etl::handle<Duck> t1_duck(last_duck());
+                       
+                       t1_duck->set_origin(vertex_duck);
+                       t1_duck->set_scalar(-0.33333333333333333);
+                       t1_duck->set_tangent(true);
+                       
+                       etl::handle<Duck> t2_duck;
+                       
+                       // If the tangents are split
+                       if((*value_node->get_link("split"))(get_time()).get(bool()))
+                       {
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,5),canvas_view,transform_stack))
+                                       return false;
+                               t2_duck=last_duck();
+                               t2_duck->set_origin(vertex_duck);
+                               t2_duck->set_scalar(0.33333333333333333);
+                               t2_duck->set_tangent(true);
+                       }
+                       else
+                       {
+                               if(!add_to_ducks(sinfgapp::ValueDesc(value_node,4),canvas_view,transform_stack))
+                                       return false;
+                               t2_duck=last_duck();
+                               t2_duck->set_origin(vertex_duck);
+                               t2_duck->set_scalar(0.33333333333333333);
+                               t2_duck->set_tangent(true);
+                       }
+                       return true;
+               }
+               
+       }
+       break;
+       case ValueBase::TYPE_LIST:
+       {
+               // Check for BLine
+               if(value_desc.is_value_node() &&
+                       ValueNode_BLine::Handle::cast_dynamic(value_desc.get_value_node())
+               )
+               {
+                       ValueNode_BLine::Handle value_node;
+                       value_node=ValueNode_BLine::Handle::cast_dynamic(value_desc.get_value_node());
+                       
+                       int i,first=-1;
+
+                       etl::handle<Bezier> bezier;
+                       etl::handle<Duck> first_duck;
+                       etl::handle<Duck> duck, tduck;
+                       
+                       for(i=0;i<value_node->link_count();i++)
+                       {
+                               float amount(value_node->list[i].amount_at_time(get_time()));
+                               if(amount<0.9999f)
+                                       continue;
+                               if(first==-1)first=i;
+                                       
+                               BLinePoint bline_point((*value_node->get_link(i))(get_time()));
+                               
+                               ValueNode_Composite::Handle vertex_value_node(
+                                       ValueNode_Composite::Handle::cast_dynamic(
+                                               value_node->get_link(i)
+                                       )
+                               );
+                                                               
+                               // Add the vertex duck
+                               if(vertex_value_node)
+                               {
+                                       if(add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack))
+                                       {
+                                               duck=last_duck();
+                                               if(i==first)
+                                                       first_duck=duck;
+                                               duck->set_type(Duck::TYPE_VERTEX);
+
+                                               duck->signal_user_click(2).clear();
+                                               duck->signal_user_click(2).connect(
+                                                       sigc::bind(
+                                                               sigc::bind(
+                                                                       sigc::mem_fun(
+                                                                               *canvas_view,
+                                                                               &studio::CanvasView::popup_param_menu
+                                                                       ),
+                                                                       1.0f
+                                                               ),
+                                                               sinfgapp::ValueDesc(value_node,i)
+                                                       )
+                                               );
+                                               duck->set_value_desc(sinfgapp::ValueDesc(value_node,i));
+                       
+                                               if(param_desc)
+                                               {
+                                                       if(!param_desc->get_origin().empty())
+                                                       {
+                                                               sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                                               duck->set_origin(last_duck());
+/*
+                                                               ValueBase value(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                                               if(value.same_as(sinfg::Point()))
+                                                                       duck->set_origin(value.get(sinfg::Point()));
+*/
+                                                       }
+                                               }
+                                       }
+                                       else
+                                               return false;
+                               }
+                               else
+                               {
+                                       duck=new Duck(bline_point.get_vertex());
+                                       if(i==first)
+                                               first_duck=duck;
+                                       duck->set_transform_stack(transform_stack);
+                                       duck->set_editable(false);
+                                       //duck->set_name(strprintf("%x-vertex",value_node->get_link(i).get()));                 
+                                       duck->set_name(guid_string(sinfgapp::ValueDesc(value_node,i))+".v");
+
+                                       duck->set_type(Duck::TYPE_VERTEX);
+                                       if(param_desc)
+                                       {
+                                               if(!param_desc->get_origin().empty())
+                                               {
+                                                               sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                                               duck->set_origin(last_duck());
+/*
+                                                               ValueBase value(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                                               if(value.same_as(sinfg::Point()))
+                                                                       duck->set_origin(value.get(sinfg::Point()));
+*/
+                                               }
+                                       }
+                                       duck->set_guid(calc_duck_guid(sinfgapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".v"));
+                                       duck=add_similar_duck(duck);
+//                                     add_duck(duck);                 
+                               }
+
+                               // Add the width duck only if we have a hint of scale
+                               if(param_desc && !param_desc->get_hint().empty())
+                               {
+                                       etl::handle<Duck> width;
+                                       if(add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,1),canvas_view,transform_stack,REAL_COOKIE))
+                                       {
+                                               width=last_duck();
+                                               width->set_origin(duck);
+                                               width->set_type(Duck::TYPE_WIDTH);
+                                               width->set_name(guid_string(sinfgapp::ValueDesc(value_node,i))+".w");
+                                               {
+                                                       ValueBase value(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_hint()).get_value(get_time()));
+                                                       if(value.same_as(sinfg::Real()))
+                                                               width->set_scalar(value.get(sinfg::Real())*0.5f);
+                                               }
+                                       }
+                                       else
+                                               sinfg::error("Unable to add width duck!");
+                               }
+                               
+                               if(bezier)
+                               {
+                                       // Add the tangent1 duck
+                                       if(vertex_value_node)
+                                       {
+                                               if(!add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack))
+                                                       return false;
+                                               tduck=last_duck();
+                                       }
+                                       else
+                                       {
+                                               tduck=new Duck(bline_point.get_tangent1());
+                                               tduck->set_transform_stack(transform_stack);
+                                               tduck->set_editable(false);
+                                               tduck->set_name(guid_string(sinfgapp::ValueDesc(value_node,i))+".t1");
+//                                             tduck->set_name(strprintf("%x-tangent1",value_node->get_link(i).get()));                        
+                                               tduck->set_guid(calc_duck_guid(sinfgapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
+                                               tduck=add_similar_duck(tduck);
+//                                             add_duck(duck);
+                                       }
+
+                                       tduck->set_origin(duck);
+                                       tduck->set_scalar(-0.33333333333333333);
+                                       tduck->set_tangent(true);
+                                       
+                                       bezier->p2=duck;
+                                       bezier->c2=tduck;
+
+                                       bezier->signal_user_click(2).connect(
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *canvas_view,
+                                                               &studio::CanvasView::popup_param_menu_bezier
+                                                       ),
+                                                       sinfgapp::ValueDesc(value_node,i)
+                                               )
+                                       );
+
+                                       duck->signal_user_click(2).clear();
+                                       duck->signal_user_click(2).connect(
+                                               sigc::bind(
+                                                       sigc::bind(
+                                                               sigc::mem_fun(
+                                                                       *canvas_view,
+                                                                       &studio::CanvasView::popup_param_menu
+                                                               ),
+                                                               1.0f
+                                                       ),
+                                                       sinfgapp::ValueDesc(value_node,i)
+                                               )
+                                       );
+                                       duck->set_value_desc(sinfgapp::ValueDesc(value_node,i));
+
+                                       add_bezier(bezier);
+                                       bezier=0;
+                               }
+                               
+                               if(i+1>=value_node->link_count() && !value_node->get_loop())
+                                       continue;
+                               
+                               bezier=new Bezier();
+                               
+                               // Add the tangent2 duck
+                               if(vertex_value_node)
+                               {
+                                       int i=bline_point.get_split_tangent_flag()?5:4;
+                                       if(!add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,i),canvas_view,transform_stack,0,2))
+                                               return false;
+                                       tduck=last_duck();
+                               }
+                               else
+                               {
+                                       if(bline_point.get_split_tangent_flag())
+                                       {
+                                               tduck=new Duck(bline_point.get_tangent2());
+                                               tduck->set_transform_stack(transform_stack);
+                                               //tduck->set_name(strprintf("%x-tangent2",value_node->get_link(i).get()));                      
+                                               tduck->set_name(guid_string(sinfgapp::ValueDesc(value_node,i))+".t2");
+                                               tduck->set_guid(calc_duck_guid(sinfgapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t2"));
+                                       }
+                                       else
+                                       {
+                                               tduck=new Duck(bline_point.get_tangent1());
+                                               tduck->set_transform_stack(transform_stack);
+                                               //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(i).get()));                      
+                                               tduck->set_name(guid_string(sinfgapp::ValueDesc(value_node,i))+".t1");
+                                               tduck->set_guid(calc_duck_guid(sinfgapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
+                                       }
+                                       tduck->set_editable(false);
+                                       tduck=add_similar_duck(tduck);
+//                                     add_duck(duck);
+                                       if(param_desc)
+                                       {
+                                                               sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                                               duck->set_origin(last_duck());
+/*
+                                                               ValueBase value(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                                               if(value.same_as(sinfg::Point()))
+                                                                       duck->set_origin(value.get(sinfg::Point()));
+*/
+//                                             if(!param_desc->get_origin().empty())
+//                                                     duck->set_origin(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(sinfg::Point()));
+                                       }
+                                       duck->signal_user_click(2).clear();
+                                       duck->signal_user_click(2).connect(
+                                               sigc::bind(
+                                                       sigc::bind(
+                                                               sigc::mem_fun(
+                                                                       *canvas_view,
+                                                                       &studio::CanvasView::popup_param_menu
+                                                               ),
+                                                               1.0f
+                                                       ),
+                                                       sinfgapp::ValueDesc(value_node,0)
+                                               )
+                                       );
+                                       duck->set_value_desc(sinfgapp::ValueDesc(value_node,0));
+
+                               }
+
+                               tduck->set_origin(duck);
+                               tduck->set_scalar(0.33333333333333333);
+                               tduck->set_tangent(true);
+                               
+                               bezier->p1=duck;
+                               bezier->c1=tduck;
+                               
+                       }
+                       // Loop if necessary
+                       if(bezier && value_node->get_loop())
+                       {
+                               BLinePoint bline_point((*value_node->get_link(first))(get_time()));
+                               
+                               ValueNode_Composite::Handle vertex_value_node(
+                                       ValueNode_Composite::Handle::cast_dynamic(
+                                               value_node->get_link(first)
+                                       )
+                               );
+                               
+                               // Add the vertex duck
+                               duck=first_duck;
+                               /*
+                               if(vertex_value_node)
+                               {
+                                       if(!add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack))
+                                               return false;
+                                       duck=last_duck();
+                                       if(param_desc)
+                                       {
+                                               if(!param_desc->get_origin().empty())
+                                                       duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(sinfg::Point()));
+                                       }
+                                       duck->set_type(Duck::TYPE_VERTEX);
+                               }
+                               else
+                               {
+                                       duck=new Duck(bline_point.get_vertex());
+                                       duck->set_transform_stack(transform_stack);
+                                       if(param_desc)
+                                       {
+                                               if(!param_desc->get_origin().empty())
+                                                       duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(sinfg::Point()));
+                                       }
+                                       duck->set_editable(false);
+                                       duck->set_name(strprintf("%x-vertex",value_node->get_link(first).get()));                       
+                                       duck->set_type(Duck::TYPE_VERTEX);
+                                       duck=add_similar_duck(duck);
+                               }
+                               */
+                               
+                                       // Add the tangent1 duck
+                                       if(vertex_value_node)
+                                       {
+                                               if(!add_to_ducks(sinfgapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack))
+                                                       return false;
+                                               tduck=last_duck();
+                                       }
+                                       else
+                                       {
+                                               tduck=new Duck(bline_point.get_tangent1());
+                                               tduck->set_transform_stack(transform_stack);
+                                               tduck->set_editable(false);
+                                               tduck->set_name(guid_string(sinfgapp::ValueDesc(value_node,first))+".t1");
+                                               //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(first).get()));                  
+                                               tduck=add_similar_duck(tduck);
+                                               tduck->set_guid(calc_duck_guid(sinfgapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1"));
+                                               //add_duck(duck);
+                                       }
+
+                                       tduck->set_origin(duck);
+                                       tduck->set_scalar(-0.33333333333333333);
+                                       tduck->set_tangent(true);
+                                       
+                                       bezier->p2=duck;
+                                       bezier->c2=tduck;
+                                       bezier->signal_user_click(2).connect(
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *canvas_view,
+                                                               &studio::CanvasView::popup_param_menu_bezier
+                                                       ),
+                                                       sinfgapp::ValueDesc(value_node,first)
+                                               )
+                                       );
+                                       duck->signal_user_click(2).clear();
+                                       duck->signal_user_click(2).connect(
+                                               sigc::bind(
+                                                       sigc::bind(
+                                                               sigc::mem_fun(
+                                                                       *canvas_view,
+                                                                       &studio::CanvasView::popup_param_menu
+                                                               ),
+                                                               1.0f
+                                                       ),
+                                                       sinfgapp::ValueDesc(value_node,first)
+                                               )
+                                       );
+                                       duck->set_value_desc(sinfgapp::ValueDesc(value_node,first));
+
+                                       add_bezier(bezier);
+                                       bezier=0;
+                               
+                       }
+                       return true;
+               }
+               else // Check for DynamicList           
+               if(value_desc.is_value_node() &&
+                       ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
+               )
+               {
+                       ValueNode_DynamicList::Handle value_node;
+                       value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node());
+                       int i;
+                       
+                       if(value_node->get_contained_type()==ValueBase::TYPE_VECTOR)
+                       {
+                               Bezier bezier;
+                               for(i=0;i<value_node->link_count();i++)
+                               {                                       
+                                       if(!value_node->list[i].status_at_time(get_time()))
+                                               continue;
+                                       if(!add_to_ducks(sinfgapp::ValueDesc(value_node,i),canvas_view,transform_stack))
+                                               return false;
+                                       etl::handle<Duck> duck(last_duck());
+                                       
+                                       if(param_desc)
+                                       {
+                                                               sinfgapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                                               duck->set_origin(last_duck());
+/*
+                                                               ValueBase value(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                                               if(value.same_as(sinfg::Point()))
+                                                                       duck->set_origin(value.get(sinfg::Point()));
+*/
+//                                             if(!param_desc->get_origin().empty())
+//                                                     last_duck()->set_origin(sinfgapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(sinfg::Point()));
+                                       }
+                                       duck->set_type(Duck::TYPE_VERTEX);
+                                       bezier.p1=bezier.p2;bezier.c1=bezier.c2;
+                                       bezier.p2=bezier.c2=duck;
+
+                                       if(i>0)
+                                       {
+                                               handle<Bezier> bezier_(new Bezier());
+                                               bezier_->p1=bezier.p1;
+                                               bezier_->c1=bezier.c1;
+                                               bezier_->p2=bezier.p2;
+                                               bezier_->c2=bezier.c2;
+                                               add_bezier(bezier_);
+                                               last_bezier()->signal_user_click(2).connect(
+                                                       sigc::bind(
+                                                               sigc::mem_fun(
+                                                                       *canvas_view,
+                                                                       &studio::CanvasView::popup_param_menu_bezier
+                                                               ),
+                                                               sinfgapp::ValueDesc(value_node,i)
+                                                       )
+                                               );
+                                       }
+                               }
+                       }
+                       /*else if(value_node->get_contained_type()==ValueBase::TYPE_SEGMENT)
+                       {
+                               for(i=0;i<value_node->link_count();i++)
+                               {
+                                       if(!value_node->list[i].status_at_time(get_time()))
+                                               continue;
+                                       if(!add_to_ducks(sinfgapp::ValueDesc(value_node,i),canvas_view,transform_stack))
+                                               return false;
+                               }
+                       }
+                       */
+                       else
+                               return false;
+               }
+               else
+               {
+                       // WRITEME
+               }
+               
+               return true;
+       }
+
+
+       break;
+       default:
+               break;
+       }
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/duckmatic.h b/synfig-studio/trunk/src/gtkmm/duckmatic.h
new file mode 100644 (file)
index 0000000..3ed164e
--- /dev/null
@@ -0,0 +1,439 @@
+/* === S I N F G =========================================================== */
+/*!    \file duckmatic.h
+**     \brief Template Header
+**
+**     $Id: duckmatic.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DUCKMATIC_H
+#define __SINFG_STUDIO_DUCKMATIC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+#include <map>
+#include <set>
+
+#include <ETL/smart_ptr>
+#include <ETL/handle>
+
+#include <sinfg/vector.h>
+#include <sinfg/string.h>
+#include <sinfg/real.h>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <sinfg/time.h>
+#include <sinfg/color.h>
+#include <ETL/smart_ptr>
+
+#include "duck.h"
+#include <sinfg/color.h>
+#include <sinfg/guidset.h>
+
+/* === M A C R O S ========================================================= */
+
+#define HASH_MAP_H <ext/hash_map>
+
+#ifdef HASH_MAP_H
+#include HASH_MAP_H
+#ifndef __STRING_HASH__
+#define __STRING_HASH__
+class StringHash
+{
+       __gnu_cxx::hash<const char*> hasher_;
+public:
+       size_t operator()(const sinfg::String& x)const
+       {
+               return hasher_(x.c_str());
+       }
+};
+#endif
+#else
+#include <map>
+#endif
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp { class ValueDesc; }
+namespace sinfg { class ParamDesc; }
+
+namespace studio
+{
+
+class CanvasView;
+class Duckmatic;
+       
+class DuckDrag_Base : public etl::shared_object
+{
+public:
+       virtual void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin)=0;
+       virtual bool end_duck_drag(Duckmatic* duckmatic)=0;
+       virtual void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)=0;
+};
+
+class DuckDrag_Translate : public DuckDrag_Base
+{
+       sinfg::Vector last_translate_;
+       sinfg::Vector drag_offset_;
+       sinfg::Vector snap;
+       std::vector<sinfg::Vector> positions;
+
+public:
+       void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin);
+       bool end_duck_drag(Duckmatic* duckmatic);
+       void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector);
+};
+
+/*! \class Duckmatic
+**
+**     This class helps organize any of the devices displayed in
+**     the work area that the user may want to interact with.
+**     This includes ducks, beziers, and strokes
+**
+**     \note At some point I'll probably rename this class to "DuckOMatic".
+*/
+class Duckmatic
+{
+       friend class DuckDrag_Base;
+       friend class DuckDrag_Translate;
+       
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+       
+public:
+
+#ifdef HASH_MAP_H
+typedef __gnu_cxx::hash_map<sinfg::GUID,etl::smart_ptr<sinfg::Point>,sinfg::GUIDHash> DuckDataMap;
+#else
+typedef std::map<sinfg::GUID,etl::smart_ptr<sinfg::Point> > DuckDataMap;
+#endif
+
+       typedef studio::DuckMap DuckMap;
+
+       typedef studio::Duck Duck;
+
+       struct Stroke;
+
+       struct Bezier;
+
+       class Push;
+       
+       friend class Push;
+               
+       typedef Duck::Type Type;
+       
+       typedef std::list<float> GuideList;
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Type type_mask;
+
+       DuckMap duck_map;
+
+       DuckDataMap duck_data_share_map;
+
+       std::list<etl::handle<Stroke> > stroke_list_;
+
+       std::list<etl::handle<Stroke> > persistant_stroke_list_;
+
+       sinfg::GUIDSet selected_ducks;
+
+       sinfg::GUID last_duck_guid;
+
+       std::list<etl::handle<Bezier> > bezier_list_;   
+
+       //! I cannot recall what this is for
+       //sinfg::Vector snap;
+
+       etl::handle<DuckDrag_Base> duck_dragger_;
+
+       sigc::signal<void> signal_duck_selection_changed_;
+
+       sigc::signal<void> signal_strokes_changed_;
+
+       sigc::signal<void> signal_grid_changed_;
+
+       mutable sigc::signal<void> signal_sketch_saved_;
+       
+       GuideList guide_list_x_;
+       GuideList guide_list_y_;
+
+       mutable sinfg::String sketch_filename_;
+       
+       /*
+ -- ** -- P R O T E C T E D   D A T A -----------------------------------------
+       */
+
+protected:
+
+       etl::handle<Bezier> selected_bezier;
+
+       sinfg::Time cur_time;
+
+       //! This flag is set if operations should snap to the grid
+       /*! \todo perhaps there should be two of these flags, one for each axis?
+       **      \see show_grid, grid_size */
+       bool grid_snap;
+
+       bool guide_snap;
+
+       //! This vector describes the grid size.
+       /*! \see grid_snap, show_grid */
+       sinfg::Vector grid_size;
+
+       bool show_persistant_strokes;
+
+       bool axis_lock;
+       
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       sinfg::Vector last_translate_;
+       sinfg::Vector drag_offset_;
+       
+       //etl::handle<Duck> selected_duck;
+
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       Duckmatic();
+       virtual ~Duckmatic();
+
+       sigc::signal<void>& signal_duck_selection_changed() { return signal_duck_selection_changed_; }
+       sigc::signal<void>& signal_strokes_changed() { return signal_strokes_changed_; }
+       sigc::signal<void>& signal_grid_changed() { return signal_grid_changed_; }
+       sigc::signal<void>& signal_sketch_saved() { return signal_sketch_saved_; }
+
+       GuideList& get_guide_list_x() { return guide_list_x_; }
+       GuideList& get_guide_list_y() { return guide_list_y_; }
+       const GuideList& get_guide_list_x()const { return guide_list_x_; }
+       const GuideList& get_guide_list_y()const { return guide_list_y_; }
+
+       void set_guide_snap(bool x=true);
+       bool get_guide_snap()const { return guide_snap; }
+       void toggle_guide_snap() { set_guide_snap(!get_guide_snap()); }
+       
+       //! Sets the state of the grid snap flag
+       void set_grid_snap(bool x=true);
+       
+       //! Gets the state of the grid snap flag
+       bool get_grid_snap()const { return grid_snap; }
+       
+       void enable_grid_snap() { set_grid_snap(true); }
+
+       void disable_grid_snap() { set_grid_snap(false); }
+
+       void toggle_grid_snap() { set_grid_snap(!grid_snap); }
+
+       sinfg::Point snap_point_to_grid(const sinfg::Point& x, float radius=0.1)const;
+       
+       bool get_show_persistant_strokes()const { return show_persistant_strokes; }
+       void set_show_persistant_strokes(bool x);
+
+       //! Sets the size of the grid
+       void set_grid_size(const sinfg::Vector &s);
+       
+       //! Returns the size of the grid
+       const sinfg::Vector &get_grid_size()const { return grid_size; }
+       
+       
+       const sinfg::Time &get_time()const { return cur_time; }
+
+       bool get_axis_lock()const { return axis_lock; }
+       void set_axis_lock(bool x) { axis_lock=x; }
+       
+       void set_time(sinfg::Time x) { cur_time=x; }
+
+       bool is_duck_group_selectable(const etl::handle<Duck>& x)const;
+       
+       //const DuckMap& duck_map()const { return duck_map; }   
+       DuckList get_duck_list()const;
+       
+       const std::list<etl::handle<Bezier> >& bezier_list()const { return bezier_list_; }      
+
+       const std::list<etl::handle<Stroke> >& stroke_list()const { return stroke_list_; }
+
+       const std::list<etl::handle<Stroke> >& persistant_stroke_list()const { return persistant_stroke_list_; }
+
+       std::list<etl::handle<Stroke> >& persistant_stroke_list() { return persistant_stroke_list_; }
+
+       //! \todo We should modify this to support multiple selections
+       etl::handle<Duck> get_selected_duck()const;
+
+       DuckList get_selected_ducks()const;
+       
+       //! Returns \a true if the given duck is currently selected
+       bool duck_is_selected(const etl::handle<Duck> &duck)const;
+
+
+       void refresh_selected_ducks();
+       
+       void clear_selected_ducks();
+
+       int count_selected_ducks()const;
+
+       void toggle_select_duck(const etl::handle<Duck> &duck);
+
+       void select_duck(const etl::handle<Duck> &duck);
+       
+       void select_ducks_in_box(const sinfg::Vector& tl,const sinfg::Vector& br);
+
+       void unselect_duck(const etl::handle<Duck> &duck);
+
+       void start_duck_drag(const sinfg::Vector& offset);
+       void translate_selected_ducks(const sinfg::Vector& vector);     
+       bool end_duck_drag();
+
+       void signal_edited_selected_ducks();    
+
+       void signal_user_click_selected_ducks(int button);      
+
+       
+       etl::handle<Duck> find_similar_duck(etl::handle<Duck> duck);
+       etl::handle<Duck> add_similar_duck(etl::handle<Duck> duck);
+       
+       void add_stroke(etl::smart_ptr<std::list<sinfg::Point> > stroke_point_list, const sinfg::Color& color=sinfg::Color(0,0,0));
+
+       void add_persistant_stroke(etl::smart_ptr<std::list<sinfg::Point> > stroke_point_list, const sinfg::Color& color=sinfg::Color(0,0,0));
+
+       void clear_persistant_strokes();
+
+       void add_duck(const etl::handle<Duck> &duck);
+
+       void add_bezier(const etl::handle<Bezier> &bezier);
+
+       void erase_duck(const etl::handle<Duck> &duck);
+
+       void erase_bezier(const etl::handle<Bezier> &bezier);
+
+       //! Returns the last duck added
+       etl::handle<Duck> last_duck()const;
+
+       etl::handle<Bezier> last_bezier()const;
+       
+       //! \note parameter is in canvas coordinates
+       /*!     A radius of "zero" will have an unlimited radius */
+       etl::handle<Duck> find_duck(sinfg::Point pos, sinfg::Real radius=0, Duck::Type type=Duck::TYPE_DEFAULT);
+
+       GuideList::iterator find_guide_x(sinfg::Point pos, float radius=0.1);
+       GuideList::iterator find_guide_y(sinfg::Point pos, float radius=0.1);
+       GuideList::const_iterator find_guide_x(sinfg::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_x(pos,radius); }
+       GuideList::const_iterator find_guide_y(sinfg::Point pos, float radius=0.1)const { return const_cast<Duckmatic*>(this)->find_guide_y(pos,radius); }
+       
+       //! \note parameter is in canvas coordinates
+       /*!     A radius of "zero" will have an unlimited radius */
+       //etl::handle<Bezier> find_bezier(sinfg::Point pos, sinfg::Real radius=0);
+
+       //! \note parameter is in canvas coordinates
+       /*!     A radius of "zero" will have an unlimited radius */
+       etl::handle<Bezier> find_bezier(sinfg::Point pos, sinfg::Real radius=0, float* location=0);
+       
+       etl::handle<Bezier> find_bezier(sinfg::Point pos, sinfg::Real scale, sinfg::Real radius, float* location=0);
+       
+       bool add_to_ducks(const sinfgapp::ValueDesc& value_desc,etl::handle<CanvasView> canvas_view, const sinfg::TransformStack& transform_stack_, sinfg::ParamDesc *param_desc=0, int multiple=0);
+
+       //! \writeme
+       void set_type_mask(Type x) { type_mask=x; }
+
+       //! \writeme
+       Type get_type_mask()const { return type_mask; }
+
+       void select_all_ducks();
+
+       void clear_ducks();
+       
+       bool save_sketch(const sinfg::String& filename)const;
+       bool load_sketch(const sinfg::String& filename);
+       const sinfg::String& get_sketch_filename()const { return sketch_filename_; }
+
+       void set_duck_dragger(etl::handle<DuckDrag_Base> x) { duck_dragger_=x; }
+       etl::handle<DuckDrag_Base> get_duck_dragger()const { return duck_dragger_; }
+       void clear_duck_dragger() { duck_dragger_=new DuckDrag_Translate(); }
+}; // END of class Duckmatic
+
+
+/*! \class Duckmatic::Push
+**     \writeme */
+class Duckmatic::Push
+{
+       Duckmatic *duckmatic_;
+       DuckMap duck_map;       
+       std::list<etl::handle<Bezier> > bezier_list_;
+       std::list<etl::handle<Stroke> > stroke_list_;
+       DuckDataMap duck_data_share_map;
+       etl::handle<DuckDrag_Base> duck_dragger_;
+       
+       bool needs_restore;
+       
+public:
+       Push(Duckmatic *duckmatic_);
+       ~Push();
+       void restore();
+}; // END of class Duckmatic::Push
+
+/*! \struct Duckmatic::Bezier
+**     \writeme */
+struct Duckmatic::Bezier : public etl::shared_object
+{
+private:
+       sigc::signal<void,float> signal_user_click_[5];
+public:
+       
+       etl::handle<Duck> p1,p2,c1,c2;
+       bool is_valid()const { return p1 && p2 && c1 && c2; }
+
+       sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
+}; // END of struct Duckmatic::Bezier
+
+/*! \struct Duckmatic::Stroke
+**     \writeme */
+struct Duckmatic::Stroke : public etl::shared_object
+{
+private:
+       sigc::signal<void,float> signal_user_click_[5];
+public:
+       
+       etl::smart_ptr<std::list<sinfg::Point> > stroke_data;
+
+       sinfg::Color color;
+
+       bool is_valid()const { return (bool)stroke_data; }
+
+       sigc::signal<void,float> &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; }
+}; // END of struct Duckmatic::Bezier
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/ducktransform_rotate.h b/synfig-studio/trunk/src/gtkmm/ducktransform_rotate.h
new file mode 100644 (file)
index 0000000..8821c82
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: ducktransform_rotate.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DUCK_TRANSFORM_ROTATE_H
+#define __SINFG_STUDIO_DUCK_TRANSFORM_ROTATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "duckmatic.h"
+#include <sinfg/angle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Transform_Rotate : public sinfg::Transform
+{
+private:
+       sinfg::Angle angle;
+       sinfg::Vector origin;
+       sinfg::Real sin_val;
+       sinfg::Real cos_val;
+
+public:
+       Transform_Rotate(const sinfg::Angle& angle,const sinfg::Vector& origin=sinfg::Vector(0,0)):
+               angle(angle),
+               origin(origin),
+               sin_val(sinfg::Angle::sin(angle).get()),
+               cos_val(sinfg::Angle::cos(angle).get())
+       {
+       }
+       
+       sinfg::Vector perform(const sinfg::Vector& x)const
+       {
+               sinfg::Point pos(x-origin);
+               return sinfg::Point(cos_val*pos[0]-sin_val*pos[1],sin_val*pos[0]+cos_val*pos[1])+origin;
+       }
+       sinfg::Vector unperform(const sinfg::Vector& x)const
+       {
+               sinfg::Point pos(x-origin);
+               return sinfg::Point(cos_val*pos[0]+sin_val*pos[1],-sin_val*pos[0]+cos_val*pos[1])+origin;
+       }
+};
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/ducktransform_scale.h b/synfig-studio/trunk/src/gtkmm/ducktransform_scale.h
new file mode 100644 (file)
index 0000000..c91f99d
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: ducktransform_scale.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DUCK_TRANSFORM_SCALE_H
+#define __SINFG_STUDIO_DUCK_TRANSFORM_SCALE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "duckmatic.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Transform_Scale : public sinfg::Transform
+{
+private:
+       sinfg::Vector scale;
+       sinfg::Vector origin;
+public:
+       Transform_Scale(const sinfg::Vector& scale,const sinfg::Vector& origin=sinfg::Vector(0,0)):scale(scale),origin(origin) { }
+       sinfg::Vector perform(const sinfg::Vector& x)const { return sinfg::Vector((x[0]-origin[0])*scale[0]+origin[0],(x[1]-origin[1])*scale[1]+origin[1]); }
+       sinfg::Vector unperform(const sinfg::Vector& x)const { return sinfg::Vector((x[0]-origin[0])/scale[0]+origin[0],(x[1]-origin[1])/scale[1]+origin[1]); }
+};
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/ducktransform_translate.h b/synfig-studio/trunk/src/gtkmm/ducktransform_translate.h
new file mode 100644 (file)
index 0000000..0f17e99
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: ducktransform_translate.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DUCK_TRANSFORM_TRANSLATE_H
+#define __SINFG_STUDIO_DUCK_TRANSFORM_TRANSLATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "duckmatic.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+class Transform_Translate : public sinfg::Transform
+{
+private:
+       sinfg::Vector origin;
+       std::vector<sinfg::Vector> positions;
+
+public:
+       Transform_Translate(const sinfg::Vector& origin): origin(origin) { }
+       sinfg::Vector perform(const sinfg::Vector& x)const { return x+origin; }
+       sinfg::Vector unperform(const sinfg::Vector& x)const { return x-origin; }
+}; // END of class sinfg::Transform_Translate
+
+}; // END of namespace studio
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/event_layerclick.h b/synfig-studio/trunk/src/gtkmm/event_layerclick.h
new file mode 100644 (file)
index 0000000..55b7f83
--- /dev/null
@@ -0,0 +1,63 @@
+/* === S I N F G =========================================================== */
+/*!    \file event_layerclick.h
+**     \brief Template Header
+**
+**     $Id: event_layerclick.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_EVENT_LAYERCLICK_H
+#define __SINFG_EVENT_LAYERCLICK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/vector.h>
+#include "event_mouse.h"
+#include <sinfg/layer.h>
+#include "smach.h"
+#include <gdkmm/types.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+struct EventLayerClick : public Smach::event
+{
+       sinfg::Point pos;
+       MouseButton button;
+       etl::loose_handle<sinfg::Layer> layer;
+       Gdk::ModifierType modifier;
+       
+       EventLayerClick(etl::loose_handle<sinfg::Layer> layer, MouseButton button, const sinfg::Point& pos, Gdk::ModifierType modifier=Gdk::ModifierType(0)):
+               Smach::event(EVENT_WORKAREA_LAYER_CLICKED),
+               pos(pos),
+               button(button),
+               layer(layer),
+               modifier(modifier)
+       { }
+}; // END of EventLayerClick
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/event_mouse.h b/synfig-studio/trunk/src/gtkmm/event_mouse.h
new file mode 100644 (file)
index 0000000..ac35d30
--- /dev/null
@@ -0,0 +1,105 @@
+/* === S I N F G =========================================================== */
+/*!    \file event_mouse.h
+**     \brief Template Header
+**
+**     $Id: event_mouse.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_EVENT_MOUSE_H
+#define __SINFG_EVENT_MOUSE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/vector.h>
+#include "smach.h"
+#include <gdkmm/types.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+enum MouseButton
+{
+       BUTTON_NONE,
+       BUTTON_LEFT,
+       BUTTON_MIDDLE,
+       BUTTON_RIGHT,
+       BUTTON_UP,
+       BUTTON_DOWN,
+       
+       BUTTON_END
+};
+
+struct EventMouse : public Smach::event
+{
+       sinfg::Point pos;
+       MouseButton button;
+       float pressure;
+       Gdk::ModifierType modifier;
+       
+       EventMouse(EventKey id, MouseButton button, const sinfg::Point& pos, Gdk::ModifierType modifier=Gdk::ModifierType(0)):
+               Smach::event(id),
+               pos(pos),
+               button(button),
+               pressure(button==BUTTON_NONE?0.0f:1.0f),
+               modifier(modifier)
+       { }
+
+       EventMouse(EventKey id, MouseButton button, const sinfg::Point& pos, float pressure, Gdk::ModifierType modifier=Gdk::ModifierType(0)):
+               Smach::event(id),
+               pos(pos),
+               button(button),
+               pressure(pressure),
+               modifier(modifier)
+       { }
+}; // END of EventMouse
+
+struct EventBox : public Smach::event
+{
+       sinfg::Point p1,p2;
+       MouseButton button;
+       Gdk::ModifierType modifier;
+       
+       EventBox(EventKey id, const sinfg::Point& p1,const sinfg::Point& p2,MouseButton button=BUTTON_NONE, Gdk::ModifierType modifier=Gdk::ModifierType(0)):
+               Smach::event(id),
+               p1(p1),
+               p2(p2),
+               button(button),
+               modifier(modifier)
+       { }
+
+       EventBox(const sinfg::Point& p1,const sinfg::Point& p2,MouseButton button=BUTTON_NONE, Gdk::ModifierType modifier=Gdk::ModifierType(0)):
+               Smach::event(EVENT_WORKAREA_BOX),
+               p1(p1),
+               p2(p2),
+               button(button),
+               modifier(modifier)
+       { }
+}; // END of EventBox
+
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/eventkey.h b/synfig-studio/trunk/src/gtkmm/eventkey.h
new file mode 100644 (file)
index 0000000..2e8f69e
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file eventkey.h
+**     \brief Template Header
+**
+**     $Id: eventkey.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_EVENTKEY_H
+#define __SINFG_STUDIO_EVENTKEY_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+enum EventKey
+{
+       EVENT_NIL,
+       EVENT_REFRESH,
+       EVENT_DIRTY,
+       EVENT_STOP,
+       EVENT_UNDO,
+       EVENT_REDO,
+       EVENT_REFRESH_DUCKS,
+       EVENT_REFRESH_TOOL_OPTIONS,
+       EVENT_YIELD_TOOL_OPTIONS,
+       EVENT_INPUT_DEVICE_CHANGED,
+       EVENT_TABLES_HIDE,
+       EVENT_LAYER_SELECTION_CHANGED,
+       EVENT_TABLES_SHOW,
+       
+       
+       EVENT_WORKAREA_START=1000,              //!< Not a valid event
+       EVENT_WORKAREA_LAYER_CLICKED,
+       EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,
+       EVENT_WORKAREA_MOUSE_MOTION,
+       EVENT_WORKAREA_MOUSE_BUTTON_DOWN,
+       EVENT_WORKAREA_MOUSE_BUTTON_DRAG,
+       EVENT_WORKAREA_MOUSE_BUTTON_UP,
+       EVENT_WORKAREA_BOX,
+       EVENT_WORKAREA_END,             //!< Not a valid event
+
+       EVENT_WORKAREA_STROKE,
+
+       EVENT_END               //!< Not a valid event  
+};
+
+};
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/groupactionmanager.cpp b/synfig-studio/trunk/src/gtkmm/groupactionmanager.cpp
new file mode 100644 (file)
index 0000000..ab2727c
--- /dev/null
@@ -0,0 +1,272 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: groupactionmanager.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "groupactionmanager.h"
+#include "layergrouptree.h"
+#include <sinfgapp/action_param.h>
+#include "instance.h"
+#include <gtkmm/stock.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+static const guint no_prev_popup((guint)-1);
+
+/* === M A C R O S ========================================================= */
+
+//#define ONE_ACTION_GROUP 1
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+GroupActionManager::GroupActionManager():
+       action_group_(Gtk::ActionGroup::create()),
+       popup_id_(no_prev_popup),
+       queued(false)
+{
+}
+
+GroupActionManager::~GroupActionManager()
+{
+}
+
+void
+GroupActionManager::set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x)
+{
+       clear();
+
+#ifdef ONE_ACTION_GROUP
+       if(ui_manager_) get_ui_manager()->remove_action_group(action_group_);
+       ui_manager_=x;
+       if(ui_manager_) get_ui_manager()->insert_action_group(action_group_);
+#else
+       ui_manager_=x;
+#endif
+}
+
+void
+GroupActionManager::set_group_tree(LayerGroupTree* x)
+{
+       selection_changed_connection.disconnect();
+       group_tree_=x;
+       if(group_tree_)
+       {
+               selection_changed_connection=group_tree_->get_selection()->signal_changed().connect(
+                       sigc::mem_fun(*this,&GroupActionManager::queue_refresh)
+               );
+       }
+}
+
+void
+GroupActionManager::set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x)
+{
+       canvas_interface_=x;
+}
+
+void
+GroupActionManager::clear()
+{
+       if(ui_manager_)
+       {
+               // Clear out old stuff
+               if(popup_id_!=no_prev_popup)
+               {
+                       get_ui_manager()->remove_ui(popup_id_);
+                       popup_id_=no_prev_popup;
+                       action_group_->set_sensitive(false);
+#ifdef ONE_ACTION_GROUP
+                       while(!action_group_->get_actions().empty())action_group_->remove(*action_group_->get_actions().begin());
+                       action_group_->set_sensitive(true);
+#else
+                       get_ui_manager()->remove_action_group(action_group_);
+                       action_group_=Gtk::ActionGroup::create();
+#endif
+               }
+       }
+}
+
+void
+GroupActionManager::queue_refresh()
+{
+       if(queued)
+               return;
+       
+       //queue_refresh_connection.disconnect();
+       queue_refresh_connection=Glib::signal_idle().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&GroupActionManager::refresh),
+                       false
+               )
+       );
+       
+       queued=true;
+}
+
+void
+GroupActionManager::refresh()
+{
+       DEBUGPOINT();
+       if(queued)
+       {
+               queued=false;
+               //queue_refresh_connection.disconnect();
+       }
+
+
+       clear();
+       
+       // Make sure we are ready
+       if(!ui_manager_ || !group_tree_ || !canvas_interface_)
+       {
+               sinfg::error("GroupActionManager::refresh(): Not ready!");
+               return;
+       }
+       
+       if(group_tree_->get_selection()->count_selected_rows()==0)
+               return;
+       
+       String ui_info;
+       
+       {
+               {
+                       action_group_->add(
+                               Gtk::Action::create(
+                                       "action-group_add",
+                                       Gtk::Stock::ADD,
+                                       _("Add a New Group"),
+                                       _("Add a New Group")
+                               ),
+                               sigc::mem_fun(
+                                       *this,
+                                       &GroupActionManager::on_action_add
+                               )
+                       );
+               }
+
+
+//             bool multiple_selected(group_tree_->get_selection()->count_selected_rows()>1);
+               LayerGroupTree::LayerList selected_layers(group_tree_->get_selected_layers());
+               std::list<sinfg::String> selected_groups(group_tree_->get_selected_groups());
+               
+               sinfg::info("selected_layers.size()=%d",selected_layers.size());
+               sinfg::info("selected_groups.size()=%d",selected_groups.size());
+               
+               {
+                       bool canvas_set(false);
+                       sinfgapp::Action::ParamList param_list;
+                       param_list.add("time",get_canvas_interface()->get_time());
+                       param_list.add("canvas_interface",get_canvas_interface());
+                       
+                       {
+                               LayerGroupTree::LayerList::iterator iter;
+                       
+                               for(iter=selected_layers.begin();iter!=selected_layers.end();++iter)
+                               {
+                                       if(!canvas_set)
+                                       {
+                                               param_list.add("canvas",Canvas::Handle(Layer::Handle(*iter)->get_canvas()));
+                                               canvas_set=true;
+                                       }
+                                       param_list.add("layer",Layer::Handle(*iter));
+                               }
+                       }
+
+                       {
+                               std::list<sinfg::String>::iterator iter;
+                       
+                               for(iter=selected_groups.begin();iter!=selected_groups.end();++iter)
+                               {
+                                       param_list.add("group",(sinfg::String)*iter);
+                               }
+                       }
+
+                       if(!canvas_set)
+                       {
+                               param_list.add("canvas",Canvas::Handle(get_canvas_interface()->get_canvas()));
+                               canvas_set=true;
+                       }
+                       
+                       handle<studio::Instance>::cast_static(get_canvas_interface()->get_instance())->
+                               add_actions_to_group(action_group_, ui_info,   param_list, sinfgapp::Action::CATEGORY_GROUP);
+                       }
+       }
+       
+       if(true)
+       {
+               ui_info="<ui><menubar action='menu-main'><menu action='menu-group'>"+ui_info+"</menu></menubar></ui>";
+               popup_id_=get_ui_manager()->add_ui_from_string(ui_info);
+       }
+       else
+       {
+               get_ui_manager()->ensure_update();
+       }
+
+#ifdef ONE_ACTION_GROUP
+#else
+       get_ui_manager()->insert_action_group(action_group_);
+#endif
+}
+
+void
+GroupActionManager::on_action_add()
+{
+       LayerGroupTreeStore::Model model;
+
+       String group_name;
+       
+       Gtk::TreeIter selected_iter;
+       
+       if(group_tree_->get_selection()->count_selected_rows())
+       {
+               selected_iter=(
+                       group_tree_->get_model()->get_iter(
+                               (*group_tree_->get_selection()->get_selected_rows().begin())
+                       )
+               );
+               if(selected_iter && selected_iter->parent())
+                       group_name=(Glib::ustring)(*selected_iter->parent())[model.group_name]+'.';
+       }
+       
+       group_name+=_("UnnamedGroup");
+       
+       Gtk::TreePath path(group_tree_->get_model()->on_group_added(group_name));
+       
+       group_tree_->expand_to_path(path);
+       group_tree_->set_cursor(path,true);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/groupactionmanager.h b/synfig-studio/trunk/src/gtkmm/groupactionmanager.h
new file mode 100644 (file)
index 0000000..f7c368b
--- /dev/null
@@ -0,0 +1,84 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: groupactionmanager.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GROUP_ACTION_MANAGER_H
+#define __SINFG_GROUP_ACTION_MANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/uimanager.h>
+#include <gtkmm/treeview.h>
+#include <sinfgapp/canvasinterface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerGroupTree;
+
+class GroupActionManager
+{
+       Glib::RefPtr<Gtk::UIManager> ui_manager_;
+       LayerGroupTree* group_tree_;
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gtk::ActionGroup>  action_group_;
+       Gtk::UIManager::ui_merge_id     popup_id_;
+       
+       sigc::connection selection_changed_connection;
+
+       bool queued;
+       sigc::connection queue_refresh_connection;
+
+private:
+       
+       void on_action_add();
+
+public:
+       void queue_refresh();
+
+       GroupActionManager();
+       ~GroupActionManager();
+
+       void set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x);
+       Glib::RefPtr<Gtk::UIManager> get_ui_manager()const { return ui_manager_; }
+
+       void set_group_tree(LayerGroupTree* x);
+       LayerGroupTree* get_group_tree()const { return group_tree_; }
+
+       void set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x);
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       void refresh();
+       void clear();
+}; // END of GroupActionManager
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/historytreestore.cpp b/synfig-studio/trunk/src/gtkmm/historytreestore.cpp
new file mode 100644 (file)
index 0000000..a0e0844
--- /dev/null
@@ -0,0 +1,214 @@
+/* === S I N F G =========================================================== */
+/*!    \file historytreestore.cpp
+**     \brief Template File
+**
+**     $Id: historytreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "historytreestore.h"
+#include <sinfg/valuenode.h>
+#include "iconcontroler.h"
+#include <sinfg/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <sinfgapp/action.h>
+#include "instance.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static HistoryTreeStore::Model& ModelHack()
+{
+       static HistoryTreeStore::Model* model(0);
+       if(!model)model=new HistoryTreeStore::Model;
+       return *model;
+}
+
+HistoryTreeStore::HistoryTreeStore(etl::loose_handle<studio::Instance> instance_):
+       Gtk::TreeStore  (ModelHack()),
+       instance_               (instance_)
+{
+       instance_->signal_undo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo));
+       instance_->signal_redo().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo));
+       instance_->signal_undo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_undo_stack_cleared));
+       instance_->signal_redo_stack_cleared().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_redo_stack_cleared));
+       instance_->signal_new_action().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_new_action));
+       instance_->signal_action_status_changed().connect(sigc::mem_fun(*this,&studio::HistoryTreeStore::on_action_status_changed));
+}
+
+HistoryTreeStore::~HistoryTreeStore()
+{
+       sinfg::info("HistoryTreeStore::~HistoryTreeStore(): Deleted");
+}
+
+Glib::RefPtr<HistoryTreeStore>
+HistoryTreeStore::create(etl::loose_handle<studio::Instance> instance_)
+{
+       return Glib::RefPtr<HistoryTreeStore>(new HistoryTreeStore(instance_));
+}
+
+void
+HistoryTreeStore::rebuild()
+{
+       sinfgapp::Action::Stack::const_iterator iter;
+       
+       clear();
+       
+       for(iter=instance()->undo_action_stack().begin();iter!=instance()->undo_action_stack().end();++iter)
+       {
+               insert_action(*(prepend()),*iter,true,true,false);      
+       }
+       curr_row=*children().end();
+       for(iter=instance()->redo_action_stack().begin();iter!=instance()->redo_action_stack().end();++iter)
+       {
+               insert_action(*(append()),*iter,true,false,true);       
+       }               
+}
+
+void
+HistoryTreeStore::insert_action(Gtk::TreeRow row,etl::handle<sinfgapp::Action::Undoable> action, bool is_active, bool is_undo, bool is_redo)
+{
+       assert(action);
+
+       row[model.action] = action;
+       row[model.name] = static_cast<Glib::ustring>(action->get_local_name());
+       row[model.is_active] = action->is_active();
+       row[model.is_undo] = is_undo;
+       row[model.is_redo] = is_redo;
+       
+       sinfgapp::Action::CanvasSpecific *specific_action;
+       specific_action=dynamic_cast<sinfgapp::Action::CanvasSpecific*>(action.get());
+       if(specific_action)
+       {
+               row[model.canvas] = specific_action->get_canvas();
+               row[model.canvas_id] = specific_action->get_canvas()->get_id();         
+       }
+
+       etl::handle<sinfgapp::Action::Group> group;
+       group=etl::handle<sinfgapp::Action::Group>::cast_dynamic(action);
+       if(group)
+       {
+               sinfgapp::Action::ActionList::const_iterator iter;
+               for(iter=group->action_list().begin();iter!=group->action_list().end();++iter)
+               {
+                       Gtk::TreeRow child_row = *(append(row.children()));
+                       insert_action(child_row,*iter,true,is_undo,is_redo);
+               }
+       }
+       
+       //row[model.icon] = Gtk::Button().render_icon(Gtk::StockID("sinfg-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);       
+}
+
+
+void
+HistoryTreeStore::on_undo()
+{
+       refresh();
+}
+
+void
+HistoryTreeStore::on_redo()
+{
+       refresh();
+}
+
+void
+HistoryTreeStore::on_undo_stack_cleared()
+{
+       Gtk::TreeModel::Children::iterator iter,next;
+       Gtk::TreeModel::Children children_(children());
+       
+       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_undo])
+                       erase(iter);
+       }
+}
+
+void
+HistoryTreeStore::on_redo_stack_cleared()
+{
+       Gtk::TreeModel::Children::iterator iter,next;
+       Gtk::TreeModel::Children children_(children());
+       
+       for(next=children_.begin(),iter=next++; iter != children_.end(); iter=(next!=children_.end())?next++:next)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_redo])
+                       erase(iter);
+       }
+}
+
+void
+HistoryTreeStore::on_new_action(etl::handle<sinfgapp::Action::Undoable> action)
+{
+//     Gtk::TreeRow row = *(append());
+       Gtk::TreeRow row;
+       Gtk::TreeModel::Children::iterator iter;
+       for(iter=children().begin(); iter != children().end(); ++iter)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(row[model.is_redo])
+               {
+                       break;
+               }
+       }
+
+       row=*insert(iter);
+
+       insert_action(row,action);
+}
+
+void
+HistoryTreeStore::on_action_status_changed(etl::handle<sinfgapp::Action::Undoable> action)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       Gtk::TreeModel::Children children_(children());
+       
+       for(iter=children_.begin(); iter != children_.end(); ++iter)
+       {
+               Gtk::TreeModel::Row row = *iter;
+               if(action == (etl::handle<sinfgapp::Action::Undoable>)row[model.action])
+               {
+                       row[model.is_active]=action->is_active();
+                       return;
+               }
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/historytreestore.h b/synfig-studio/trunk/src/gtkmm/historytreestore.h
new file mode 100644 (file)
index 0000000..46fb28d
--- /dev/null
@@ -0,0 +1,152 @@
+/* === S I N F G =========================================================== */
+/*!    \file historytreestore.h
+**     \brief Template Header
+**
+**     $Id: historytreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_HISTORYTREESTORE_H
+#define __SINFG_STUDIO_HISTORYTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Instance;
+       
+class HistoryTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+       public:
+               Gtk::TreeModelColumn<etl::handle<sinfgapp::Action::Undoable> > action;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<bool> is_active;
+               Gtk::TreeModelColumn<bool> is_undo;
+               Gtk::TreeModelColumn<bool> is_redo;
+
+               Gtk::TreeModelColumn<Glib::ustring> canvas_id;
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle> canvas;
+
+               Model()
+               {
+                       add(action);
+                       add(name);
+                       add(icon);
+                       add(is_active);
+                       add(is_undo);
+                       add(is_redo);
+                       add(canvas_id);
+                       add(canvas);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<studio::Instance> instance_;
+       Gtk::TreeIter curr_row; 
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_undo();
+       
+       void on_redo();
+       
+       void on_undo_stack_cleared();
+       
+       void on_redo_stack_cleared();
+       
+       void on_new_action(etl::handle<sinfgapp::Action::Undoable> action);
+
+       void on_action_status_changed(etl::handle<sinfgapp::Action::Undoable> action);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       HistoryTreeStore(etl::loose_handle<studio::Instance> instance_);
+       ~HistoryTreeStore();
+
+       etl::loose_handle<studio::Instance> instance() { return instance_; }
+       etl::loose_handle<const studio::Instance> instance()const { return instance_; }
+
+       void rebuild();
+
+       void refresh() { rebuild(); }
+
+       void insert_action(Gtk::TreeRow row,etl::handle<sinfgapp::Action::Undoable> action, bool is_active=true, bool is_undo=true, bool is_redo=false);
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<HistoryTreeStore> create(etl::loose_handle<studio::Instance> instance);
+       
+}; // END of class HistoryTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/iconcontroler.cpp b/synfig-studio/trunk/src/gtkmm/iconcontroler.cpp
new file mode 100644 (file)
index 0000000..cae7756
--- /dev/null
@@ -0,0 +1,374 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: iconcontroler.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "iconcontroler.h"
+#include <sinfg/valuenode_const.h>
+#include <gtkmm/button.h>
+#include <gtkmm/window.h>
+#include <sinfgapp/action.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace etl;
+using namespace std;
+using namespace studio;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+// Quick hack to keep stuff working until gettext support is added
+#ifndef _
+#define _(x)   (x)
+#define N_(x)  (x)
+#endif
+
+#ifdef WIN32
+#      ifdef IMAGE_DIR
+#              undef IMAGE_DIR
+#              define IMAGE_DIR "share\\pixmaps"
+#      endif
+#endif
+
+#ifndef IMAGE_DIR
+#      define IMAGE_DIR "/usr/local/share/pixmaps"
+#endif
+
+
+#ifndef IMAGE_EXT
+#      define IMAGE_EXT        "png"
+#endif
+
+/* === M E T H O D S ======================================================= */
+
+static Glib::RefPtr<Gdk::Pixbuf> _tree_pixbuf_table_value_type[(int)sinfg::ValueBase::TYPE_END];
+
+IconControler::IconControler(const sinfg::String& basepath)
+{
+       Gtk::IconSource icon_source;
+       icon_source.set_direction_wildcarded();
+       icon_source.set_state_wildcarded();
+       icon_source.set_size_wildcarded();
+       icon_factory=Gtk::IconFactory::create();
+
+       std::string path_to_icons;
+#ifdef WIN32
+       path_to_icons=basepath+"/../"+IMAGE_DIR;
+#else
+       path_to_icons=IMAGE_DIR;
+#endif
+       path_to_icons+=ETL_DIRECTORY_SEPERATOR;
+
+       try{
+       Gtk::Window::set_default_icon_from_file(path_to_icons+"sinfg_icon."+IMAGE_EXT);
+       } catch(...)
+       {
+               sinfg::warning("Unable to open "+path_to_icons+"sinfg_icon."+IMAGE_EXT);
+       }
+       
+/*
+#define INIT_STOCK_ICON(name,iconfile,desc)                                                    \
+       stock_##name=Gtk::StockItem(Gtk::StockID("sinfg-" #name),desc);                         \
+       Gtk::Stock::add(stock_##name);                                                          \
+       icon_source.set_filename(path_to_icons+iconfile);                                                       \
+       icon_##name.add_source(icon_source);                                            \
+       icon_factory->add(stock_##name.get_stock_id(),icon_##name)
+*/
+#define INIT_STOCK_ICON(name,iconfile,desc){                                                   \
+       Gtk::StockItem stockitem(Gtk::StockID("sinfg-" #name),desc); \
+       Gtk::Stock::add(stockitem);                                                             \
+       Gtk::IconSet icon_set;                                                                  \
+       icon_source.set_filename(path_to_icons+iconfile);                                                       \
+       icon_set.add_source(icon_source);                                               \
+       icon_factory->add(stockitem.get_stock_id(),icon_set); \
+       }
+
+#define INIT_STOCK_ICON_CLONE(name,stockid,desc){                                                      \
+       Gtk::StockItem stockitem(Gtk::StockID("sinfg-" #name),desc); \
+       Gtk::Stock::add(stockitem);                                                             \
+       Gtk::IconSet icon_set;                                                                  \
+       if(Gtk::Stock::lookup(stockitem.get_stock_id(),icon_set))       \
+       icon_factory->add(stockitem.get_stock_id(),icon_set); \
+       }
+
+#define INIT_STOCK_ITEM(name,desc)                                                     \
+       stock_##name=Gtk::StockItem(Gtk::StockID("sinfg-" #name),desc);                         \
+       Gtk::Stock::add(stock_##name);                                                          
+
+       INIT_STOCK_ICON(swap_colors,"swap_colors_icon."IMAGE_EXT,_("Swap Colors"));
+       INIT_STOCK_ICON(canvas,"canvas_icon."IMAGE_EXT,_("Canvas"));
+       INIT_STOCK_ICON(value_node,"valuenode_icon."IMAGE_EXT,_("ValueNode"));
+       INIT_STOCK_ICON(real,"real_icon."IMAGE_EXT,_("Real"));
+       INIT_STOCK_ICON(integer,"integer_icon."IMAGE_EXT,_("Integer"));
+       INIT_STOCK_ICON(vector,"vector_icon."IMAGE_EXT,_("Vector"));
+       INIT_STOCK_ICON(color,"color_icon."IMAGE_EXT,_("Color"));
+       INIT_STOCK_ICON(angle,"angle_icon."IMAGE_EXT,_("Angle"));
+       INIT_STOCK_ICON(segment,"segment_icon."IMAGE_EXT,_("Segment"));
+       INIT_STOCK_ICON(about,"about_icon."IMAGE_EXT,_("About"));
+       INIT_STOCK_ICON(rename,"rename_icon."IMAGE_EXT,_("Rename"));
+       INIT_STOCK_ICON(list,"list_icon."IMAGE_EXT,_("Rename"));
+       INIT_STOCK_ICON(canvas_pointer,"canvas_pointer_icon."IMAGE_EXT,_("Rename"));
+       INIT_STOCK_ICON(string,"string_icon."IMAGE_EXT,_("Rename"));
+       INIT_STOCK_ICON(canvas_new,"canvas_icon."IMAGE_EXT,_("New Canvas"));
+       INIT_STOCK_ICON(saveall,"saveall_icon."IMAGE_EXT,_("Save All"));
+       INIT_STOCK_ICON(bool,"bool_icon."IMAGE_EXT,_("Bool"));
+       INIT_STOCK_ICON(layer,"layer_icon."IMAGE_EXT,_("Layer"));
+       INIT_STOCK_ICON(layer_pastecanvas,"pastecanvas_icon."IMAGE_EXT,_("PasteCanvas"));
+       INIT_STOCK_ICON(group,"group_icon."IMAGE_EXT,_("Group"));
+       INIT_STOCK_ICON(grid_enable,"grid_enable_icon."IMAGE_EXT,_("Show Grid"));
+       INIT_STOCK_ICON(grid_disable,"grid_disable_icon."IMAGE_EXT,_("Hide Grid"));
+       INIT_STOCK_ICON(grid_snap_enable,"grid_snap_enable_icon."IMAGE_EXT,_("Enable Grid Snap"));
+       INIT_STOCK_ICON(grid_snap_disable,"grid_snap_disable_icon."IMAGE_EXT,_("Disable Grid Snap"));
+       INIT_STOCK_ICON(duplicate,"duplicate_icon."IMAGE_EXT,_("Duplicate"));
+       INIT_STOCK_ICON(gradient,"gradient_icon."IMAGE_EXT,_("Gradient"));
+       INIT_STOCK_ICON(blinepoint,"blinepoint_icon."IMAGE_EXT,_("BLine Point"));
+
+       INIT_STOCK_ICON(clear_undo,"clear_undo_icon."IMAGE_EXT,_("Clear Undo Stack"));
+       INIT_STOCK_ICON(clear_redo,"clear_redo_icon."IMAGE_EXT,_("Clear Redo Stack"));
+
+       INIT_STOCK_ICON(children,"children_icon."IMAGE_EXT,_("Children"));
+       INIT_STOCK_ICON(keyframes,"keyframe_icon."IMAGE_EXT,_("Keyframes"));
+       INIT_STOCK_ICON(meta_data,"meta_data_icon."IMAGE_EXT,_("MetaData"));
+       INIT_STOCK_ICON(navigator,"navigator_icon."IMAGE_EXT,_("Navigator"));
+       INIT_STOCK_ICON(timetrack,"time_track_icon."IMAGE_EXT,_("Time Track"));
+
+       INIT_STOCK_ICON(keyframe_lock_all,"keyframe_lock_all."IMAGE_EXT,_("All Keyframes Locked"));
+       INIT_STOCK_ICON(keyframe_lock_past,"keyframe_lock_past."IMAGE_EXT,_("Past Keyframes Locked"));
+       INIT_STOCK_ICON(keyframe_lock_future,"keyframe_lock_future."IMAGE_EXT,_("Future Keyframes Locked"));
+       INIT_STOCK_ICON(keyframe_lock_none,"keyframe_lock_none."IMAGE_EXT,_("No Keyframes Locked"));
+
+       INIT_STOCK_ICON_CLONE(cvs_add,"gtk-add",_("CVS Add"));
+       INIT_STOCK_ICON_CLONE(cvs_update,"gtk-open",_("CVS Update"));
+       INIT_STOCK_ICON_CLONE(cvs_commit,"gtk-save",_("CVS Commit"));
+       INIT_STOCK_ICON_CLONE(cvs_revert,"gtk-revert",_("CVS Revert"));
+
+       // Tools
+       INIT_STOCK_ICON(normal,"normal_icon."IMAGE_EXT,_("Normal Tool"));
+       INIT_STOCK_ICON(polygon,"polygon_icon."IMAGE_EXT,_("Polygon Tool"));
+       INIT_STOCK_ICON(bline,"bline_icon."IMAGE_EXT,_("BLine Tool"));
+       INIT_STOCK_ICON(eyedrop,"eyedrop_icon."IMAGE_EXT,_("Eyedrop Tool"));
+       INIT_STOCK_ICON(fill,"fill_icon."IMAGE_EXT,_("Fill Tool"));
+       INIT_STOCK_ICON(draw,"draw_icon."IMAGE_EXT,_("Draw Tool"));
+       INIT_STOCK_ICON(sketch,"sketch_icon."IMAGE_EXT,_("Sketch Tool"));
+       INIT_STOCK_ICON(circle,"circle_icon."IMAGE_EXT,_("Circle Tool"));
+       INIT_STOCK_ICON(rectangle,"rectangle_icon."IMAGE_EXT,_("Rectangle Tool"));
+       INIT_STOCK_ICON(smooth_move,"smooth_move_icon."IMAGE_EXT,_("SmoothMove Tool"));
+       INIT_STOCK_ICON(scale,"scale_icon."IMAGE_EXT,_("Scale Tool"));
+       INIT_STOCK_ICON(width,"width_icon."IMAGE_EXT,_("Width Tool"));
+       INIT_STOCK_ICON(rotate,"rotate_icon."IMAGE_EXT,_("Rotate Tool"));
+       INIT_STOCK_ICON(zoom,"zoom_icon."IMAGE_EXT,_("Zoom Tool"));
+       INIT_STOCK_ICON(info,"info_icon."IMAGE_EXT,_("Info Tool"));
+       INIT_STOCK_ICON(mirror,"mirror_icon."IMAGE_EXT,_("Mirror Tool"));
+
+       icon_factory->add_default();
+       
+       Gtk::IconSize::register_new("sinfg-small_icon",12,12);
+       for(int i(0);i<(int)ValueBase::TYPE_END;i++)
+               _tree_pixbuf_table_value_type[i]=Gtk::Button().render_icon(value_icon(ValueBase::Type(i)),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+}
+
+IconControler::~IconControler()
+{
+       for(int i(0);i<(int)ValueBase::TYPE_END;i++)
+               _tree_pixbuf_table_value_type[i]=Glib::RefPtr<Gdk::Pixbuf>();
+
+       icon_factory->remove_default();
+}
+
+Gdk::Cursor
+IconControler::get_normal_cursor()
+{
+       return Gdk::Cursor(Gdk::TOP_LEFT_ARROW);
+}
+
+Gdk::Cursor
+IconControler::get_tool_cursor(const Glib::ustring& name,const Glib::RefPtr<Gdk::Window>& window)
+{
+       Glib::RefPtr<Gdk::Pixmap> pixmap;
+       DEBUGPOINT();
+       pixmap=Gdk::Pixmap::create(window, 64, 64, 8);
+       DEBUGPOINT();
+       pixmap->set_colormap(window->get_colormap());
+       //pixmap->set_colormap(Gdk::Colormap::create(pixmap->get_visual(),false));
+       DEBUGPOINT();
+       Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+       DEBUGPOINT();
+       pixbuf=Gtk::Button().render_icon(Gtk::StockID("sinfg-"+name),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       DEBUGPOINT();
+
+       pixbuf->render_to_drawable_alpha(
+               pixmap,
+               0,0,    // SOURCE X,Y
+               0,0,    // DEST X Y
+               -1,-1,  // WIDTH HEIGHT
+               Gdk::PIXBUF_ALPHA_FULL, // (ignored)
+               64,             //int alpha_threshold,
+               Gdk::RGB_DITHER_MAX,            //RgbDither dither,
+               2,2     //int x_dither, int y_dither
+       );
+/*
+       pixmap->draw_pixbuf(
+               Glib::RefPtr<const Gdk::GC>(0), // GC
+               pixbuf,
+               0, 0, // Source X,Y
+               0, 0, // Dest X,Y
+               -1, -1, // Width, Height
+               Gdk::RGB_DITHER_MAX, // Dither
+               0,0 // Dither X,Y
+       );
+*/
+       DEBUGPOINT();
+       
+       Gdk::Color FG("#000000");
+       Gdk::Color BG("#FF00FF");
+       
+       DEBUGPOINT();
+       return Gdk::Cursor(pixmap, pixmap, FG, BG, 0, 0);
+}
+
+Gtk::StockID
+studio::value_icon(sinfg::ValueBase::Type type)
+{
+               switch(type)
+               {
+               case ValueBase::TYPE_REAL:
+                       return Gtk::StockID("sinfg-real");
+                       break;
+               case ValueBase::TYPE_INTEGER:
+                       return Gtk::StockID("sinfg-integer");
+                       break;
+               case ValueBase::TYPE_BOOL:
+                       return Gtk::StockID("sinfg-bool");
+                       break;
+               case ValueBase::TYPE_ANGLE:
+                       return Gtk::StockID("sinfg-angle");
+                       break;
+               case ValueBase::TYPE_VECTOR:
+                       return Gtk::StockID("sinfg-vector");
+                       break;
+               case ValueBase::TYPE_COLOR:
+                       return Gtk::StockID("sinfg-color");
+                       break;
+               case ValueBase::TYPE_STRING:
+                       return Gtk::StockID("sinfg-string");
+                       break;
+               case ValueBase::TYPE_CANVAS:
+                       return Gtk::StockID("sinfg-canvas_pointer");
+                       break;
+               case ValueBase::TYPE_LIST:
+                       return Gtk::StockID("sinfg-list");
+                       break;
+               case ValueBase::TYPE_SEGMENT:
+                       return Gtk::StockID("sinfg-segment");
+                       break;
+               case ValueBase::TYPE_GRADIENT:
+                       return Gtk::StockID("sinfg-gradient");
+                       break;
+               case ValueBase::TYPE_BLINEPOINT:
+                       return Gtk::StockID("sinfg-blinepoint");
+                       break;
+               case ValueBase::TYPE_NIL:
+               default:
+                       return Gtk::StockID("sinfg-unknown");
+                       break;
+               }
+}
+
+Gtk::StockID
+studio::valuenode_icon(etl::handle<sinfg::ValueNode> value_node)
+{
+       if(handle<ValueNode_Const>::cast_dynamic(value_node))
+       {
+               return value_icon(value_node->get_type());
+       }
+       else
+       {
+               return Gtk::StockID("sinfg-value_node");                
+       }
+}
+
+Glib::RefPtr<Gdk::Pixbuf>
+studio::get_tree_pixbuf(sinfg::ValueBase::Type type)
+{
+       //return Gtk::Button().render_icon(value_icon(type),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       return _tree_pixbuf_table_value_type[int(type)];
+}
+
+Gtk::StockID
+studio::get_action_stock_id(const sinfgapp::Action::BookEntry& action)
+{
+       Gtk::StockID stock_id;
+       if(action.task=="raise")                        stock_id=Gtk::Stock::GO_UP;
+       else if(action.task=="lower")           stock_id=Gtk::Stock::GO_DOWN;
+       else if(action.task=="add")                     stock_id=Gtk::Stock::ADD;
+       else if(action.task=="insert")          stock_id=Gtk::Stock::ADD;
+       else if(action.task=="move_top")        stock_id=Gtk::Stock::GOTO_TOP;
+       else if(action.task=="move_bottom")     stock_id=Gtk::Stock::GOTO_BOTTOM;
+       else if(action.task=="remove")          stock_id=Gtk::Stock::DELETE;
+       else if(action.task=="set_on")          stock_id=Gtk::Stock::YES;
+       else if(action.task=="set_off")         stock_id=Gtk::Stock::NO;
+       else if(action.task=="remove")          stock_id=Gtk::Stock::DELETE;
+       else                                                            stock_id=Gtk::StockID("sinfg-"+action.task);
+       
+       return stock_id;
+}
+
+Gtk::StockID
+studio::layer_icon(const sinfg::String &layer)
+{
+       if(layer=="PasteCanvas" || layer=="pastecanvas")
+               return Gtk::StockID("sinfg-layer_pastecanvas");
+       else if(layer=="rotate")
+               return Gtk::StockID("sinfg-rotate");
+       else if(layer=="zoom")
+               return Gtk::StockID("sinfg-zoom");
+       else if(layer=="region")
+               return Gtk::StockID("sinfg-bline");
+       else if(layer=="polygon")
+               return Gtk::StockID("sinfg-polygon");
+       else if(layer=="outline")
+               return Gtk::StockID("sinfg-width");
+       else if(layer=="circle")
+               return Gtk::StockID("sinfg-circle");
+       else if(layer=="rectangle")
+               return Gtk::StockID("sinfg-rectangle");
+       else if(layer.find("gradient")!=String::npos)
+               return Gtk::StockID("sinfg-gradient");
+       else
+               return Gtk::StockID("sinfg-layer");
+}
+
+Glib::RefPtr<Gdk::Pixbuf>
+studio::get_tree_pixbuf_layer(const sinfg::String &layer)
+{
+       return Gtk::Button().render_icon(layer_icon(layer),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/iconcontroler.h b/synfig-studio/trunk/src/gtkmm/iconcontroler.h
new file mode 100644 (file)
index 0000000..ff578df
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: iconcontroler.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_ICONCONTROLER_H
+#define __SINFG_STUDIO_ICONCONTROLER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/stock.h>
+#include <gtkmm/iconfactory.h>
+#include <gtkmm/iconset.h>
+#include <gdkmm/cursor.h>
+
+#include <sinfg/value.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class ValueNode; class Layer; }
+
+namespace sinfgapp { namespace Action { class BookEntry; };};
+
+namespace studio {
+
+
+class IconControler
+{
+       Glib::RefPtr<Gtk::IconFactory> icon_factory;
+public:
+       IconControler(const sinfg::String& basepath);
+       ~IconControler();
+
+       static Gdk::Cursor get_normal_cursor();
+       static Gdk::Cursor get_tool_cursor(const Glib::ustring& name,const Glib::RefPtr<Gdk::Window>& window);
+};
+
+Gtk::StockID layer_icon(const sinfg::String &layer);
+Glib::RefPtr<Gdk::Pixbuf> get_tree_pixbuf_layer(const sinfg::String &layer);
+
+Gtk::StockID value_icon(sinfg::ValueBase::Type type);
+Gtk::StockID valuenode_icon(etl::handle<sinfg::ValueNode> value_node);
+Glib::RefPtr<Gdk::Pixbuf> get_tree_pixbuf(sinfg::ValueBase::Type type);
+Gtk::StockID get_action_stock_id(const sinfgapp::Action::BookEntry& action);
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/instance.cpp b/synfig-studio/trunk/src/gtkmm/instance.cpp
new file mode 100644 (file)
index 0000000..a70d474
--- /dev/null
@@ -0,0 +1,1167 @@
+/* === S I N F G =========================================================== */
+/*!    \file instance.cpp
+**     \brief writeme
+**
+**     $Id: instance.cpp,v 1.2 2005/01/13 18:37:30 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "instance.h"
+#include <cassert>
+#include <gtkmm/stock.h>
+#include <gtkmm/image.h>
+#include <iostream>
+#include <gtkmm/button.h>
+#include "canvasview.h"
+#include "app.h"
+#include <sigc++/signal.h>
+#include <sigc++/adaptors/hide.h>
+#include "toolbox.h"
+#include "onemoment.h"
+
+#include "autorecover.h"
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+//#include <sigc++/hide.h>
+#include <sinfg/valuenode_composite.h>
+#include "widget_waypointmodel.h"
+#include <gtkmm/actiongroup.h>
+#include "iconcontroler.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+using namespace SigC;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+int studio::Instance::instance_count_=0;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Instance::Instance(Canvas::Handle canvas):
+       sinfgapp::Instance              (canvas),
+//     canvas_tree_store_              (Gtk::TreeStore::create(CanvasTreeModel())),
+//     canvas_tree_store_              (Gtk::TreeStore::create()),
+       history_tree_store_             (HistoryTreeStore::create(this)),
+       undo_status_(false),
+       redo_status_(false)
+{
+       CanvasTreeModel model;
+       canvas_tree_store_=Gtk::TreeStore::create(model);
+
+       id_=instance_count_++;
+       
+       // Connect up all the signals
+       signal_filename_changed().connect(sigc::mem_fun(*this,&studio::Instance::update_all_titles));
+       signal_unsaved_status_changed().connect(sigc::hide(sigc::mem_fun(*this,&studio::Instance::update_all_titles)));
+       signal_undo_status().connect(sigc::mem_fun(*this,&studio::Instance::set_undo_status));
+       signal_redo_status().connect(sigc::mem_fun(*this,&studio::Instance::set_redo_status));
+
+       signal_saved().connect(
+               sigc::hide_return(
+                       sigc::ptr_fun(
+                               studio::AutoRecover::auto_backup
+                       )
+               )
+       );
+       
+       canvas_tree_store_=Gtk::TreeStore::create(canvas_tree_model);
+       
+       refresh_canvas_tree();
+}
+
+Instance::~Instance()
+{
+}
+
+int
+Instance::get_visible_canvases()const
+{
+       int count(0);
+       CanvasViewList::const_iterator iter;
+       for(iter=canvas_view_list_.begin();iter!=canvas_view_list_.end();++iter)
+               if((*iter)->is_visible())
+                       count++;
+       return count;
+}
+
+handle<Instance>
+Instance::create(Canvas::Handle canvas)
+{
+       // Construct a new instance
+       handle<Instance> instance(new Instance(canvas));
+
+       // Add the new instance to the application's instance list
+       App::instance_list.push_back(instance);
+       
+       // Set up the instance with the default UI manager
+       instance->sinfgapp::Instance::set_ui_interface(App::get_ui_interface());
+       
+       // Signal the new instance
+       App::signal_instance_created()(instance);
+       
+       // And then make sure that is has been selected
+       App::set_selected_instance(instance);
+       
+       // Create the initial window for the root canvas
+       instance->focus(canvas);
+       
+       return instance;        
+}
+
+handle<CanvasView>
+Instance::find_canvas_view(Canvas::Handle canvas)
+{
+       if(!canvas)
+               return 0;
+
+       while(canvas->is_inline())
+               canvas=canvas->parent();
+
+       CanvasViewList::iterator iter;
+       
+       for(iter=canvas_view_list().begin();iter!=canvas_view_list().end();iter++)
+               if((*iter)->get_canvas()==canvas)
+                       return *iter;
+       
+       return CanvasView::create(this,canvas);
+}
+
+void
+Instance::focus(Canvas::Handle canvas)
+{
+       handle<CanvasView> canvas_view=find_canvas_view(canvas);
+       assert(canvas_view);
+       canvas_view->present();
+}
+
+void
+Instance::set_undo_status(bool x)
+{
+       undo_status_=x;
+       App::toolbox->update_undo_redo();
+       signal_undo_redo_status_changed()();
+}
+
+void
+Instance::set_redo_status(bool x)
+{
+       redo_status_=x;
+       App::toolbox->update_undo_redo();
+       signal_undo_redo_status_changed()();
+}
+
+bool
+studio::Instance::save_as(const sinfg::String &file_name)const
+{
+       if(sinfgapp::Instance::save_as(file_name))
+       {
+               App::add_recent_file(file_name);
+               return true;
+       }
+       return false;
+}
+
+bool
+studio::Instance::save_as(const sinfg::String &file_name)
+{
+       if(sinfgapp::Instance::save_as(file_name))
+       {
+               App::add_recent_file(file_name);
+               return true;
+       }
+       return false;
+}
+
+bool
+studio::Instance::save()
+{
+       if(basename(get_file_name()).find("untitled")==0)
+       {
+               dialog_save_as();
+               return true;
+       }
+
+       return sinfgapp::Instance::save();
+       
+}
+
+void
+studio::Instance::dialog_save_as()
+{
+       string filename="*.sif";
+       
+       Canvas::Handle canvas(get_canvas());
+       
+       {
+               OneMoment one_moment;
+               std::set<Node*>::iterator iter;
+               for(iter=canvas->parent_set.begin();iter!=canvas->parent_set.end();++iter)
+               {
+                       sinfg::Node* node(*iter);
+                       for(;!node->parent_set.empty();node=*node->parent_set.begin())
+                       {
+                               Layer::Handle parent_layer(dynamic_cast<Layer*>(node));
+                               if(parent_layer && parent_layer->get_canvas()->get_root()!=get_canvas())
+                               {
+                                       App::dialog_error_blocking("SaveAs - Error",
+                                               "There is currently a bug when using \"SaveAs\"\n"
+                                               "on a composition that is being referenced by other\n"
+                                               "files that are currently open. Close these\n"
+                                               "other files first before trying to use \"SaveAs\"."
+                                       );
+                                       
+                                       return;
+                               }
+                               if(parent_layer)
+                                       break;
+                       }
+               }
+       }
+       
+       while(App::dialog_saveas_file("SaveAs", filename))
+       {
+               // If the filename still has wildcards, then we should
+               // continue looking for the file we want
+               if(find(filename.begin(),filename.end(),'*')!=filename.end())
+                       continue;
+
+               if(find(filename.begin(),filename.end(),'.')==filename.end())
+                       filename+=".sif";
+
+               try
+               {
+                       String ext(String(filename.begin()+filename.find_last_of('.')+1,filename.end()));
+                       if(ext!="sif" && ext!="sifz" && !App::dialog_yes_no(_("Unknown extension"),
+                               _("You have given the file name an extension\nwhich I do not recognise. Are you sure this is what you want?")))
+                       {
+                               continue;
+                       }
+               }
+               catch(...)
+               {
+                       continue;
+               }
+                       
+               if(save_as(filename))
+                       break;
+               
+               App::dialog_error_blocking("SaveAs - Error","Unable to save file");
+       }
+}
+       
+void
+Instance::update_all_titles()
+{
+       list<handle<CanvasView> >::iterator iter;
+       for(iter=canvas_view_list().begin();iter!=canvas_view_list().end();iter++)
+               (*iter)->update_title();
+}
+
+void
+Instance::close()
+{
+       // This will increase the reference count so we don't get DELETED
+       // until we are ready
+       handle<Instance> me(this);
+
+       // Make sure we aren't selected as the current instance
+       if(studio::App::get_selected_instance()==this)
+               studio::App::set_selected_instance(0);
+
+       // Turn-off/clean-up auto recovery
+       studio::App::auto_recover->clear_backup(get_canvas());
+
+       // Remove us from the active instance list
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+       for(iter=studio::App::instance_list.begin();iter!=studio::App::instance_list.end();iter++)
+               if(*iter==this)
+                       break;
+       assert(iter!=studio::App::instance_list.end());
+       if(iter!=studio::App::instance_list.end())
+               studio::App::instance_list.erase(iter);
+
+       // Send out a signal that we are being deleted
+       studio::App::signal_instance_deleted()(this);
+
+       // Hide all of the canvas views
+       for(std::list<etl::handle<CanvasView> >::iterator iter=canvas_view_list().begin();iter!=canvas_view_list().end();iter++)
+               (*iter)->hide();
+
+       // Delete all of the canvas views
+       canvas_view_list().clear();
+
+       // If there is another open instance to select,
+       // go ahead and do so. If not, never mind.
+       if(studio::App::instance_list.empty())
+       {
+               studio::App::set_selected_canvas_view(0);
+               studio::App::set_selected_instance(0);
+       }
+       else
+       {
+               studio::App::set_selected_canvas_view(studio::App::instance_list.front()->canvas_view_list().front());
+               //studio::App::set_selected_instance(studio::App::instance_list.front());
+       }
+}
+
+       
+void
+Instance::insert_canvas(Gtk::TreeRow row,Canvas::Handle canvas)
+{
+       CanvasTreeModel canvas_tree_model;
+       assert(canvas);
+
+       row[canvas_tree_model.icon] = Gtk::Button().render_icon(Gtk::StockID("sinfg-canvas"),Gtk::ICON_SIZE_SMALL_TOOLBAR);     
+       row[canvas_tree_model.id] = canvas->get_id();
+       row[canvas_tree_model.name] = canvas->get_name();
+       if(canvas->is_root())
+               row[canvas_tree_model.label] = basename(canvas->get_file_name());
+       else
+       if(!canvas->get_id().empty())
+               row[canvas_tree_model.label] = canvas->get_id();
+       else
+       if(!canvas->get_name().empty())
+               row[canvas_tree_model.label] = canvas->get_name();              
+       else
+               row[canvas_tree_model.label] = _("[Unnamed]");          
+               
+       row[canvas_tree_model.canvas] = canvas;
+       row[canvas_tree_model.is_canvas] = true;
+       row[canvas_tree_model.is_value_node] = false;
+
+       {
+               sinfg::Canvas::Children::iterator iter;
+               sinfg::Canvas::Children &children(canvas->children());
+       
+               for(iter=children.begin();iter!=children.end();iter++)
+                       insert_canvas(*(canvas_tree_store()->append(row.children())),*iter);
+       }
+
+       /*
+       if(!canvas->value_node_list().empty())
+       {
+               Gtk::TreeRow valuenode_row = *(canvas_tree_store()->append(row.children()));
+
+               valuenode_row[canvas_tree_model.label] = "<defs>";
+               valuenode_row[canvas_tree_model.canvas] = canvas;
+               valuenode_row[canvas_tree_model.is_canvas] = false;
+               valuenode_row[canvas_tree_model.is_value_node] = false;
+
+               sinfg::ValueNodeList::iterator iter;
+               sinfg::ValueNodeList &value_node_list(canvas->value_node_list());
+
+               for(iter=value_node_list.begin();iter!=value_node_list.end();iter++)
+                       insert_value_node(*(canvas_tree_store()->append(valuenode_row.children())),canvas,*iter);
+       }
+       */
+}
+
+
+/*
+void
+Instance::insert_value_node(Gtk::TreeRow row,Canvas::Handle canvas,etl::handle<sinfg::ValueNode> value_node)
+{
+       CanvasTreeModel canvas_tree_model;
+       assert(value_node);
+       assert(canvas);
+
+       row[canvas_tree_model.id] = value_node->get_id();
+       row[canvas_tree_model.name] = value_node->get_id();
+       row[canvas_tree_model.label] = value_node->get_id();
+       row[canvas_tree_model.canvas] = canvas;
+       row[canvas_tree_model.value_node] = value_node;
+       row[canvas_tree_model.is_canvas] = false;
+       row[canvas_tree_model.is_value_node] = true;
+       row[canvas_tree_model.icon] = Gtk::Button().render_icon(valuenode_icon(value_node),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+}
+*/
+
+void
+Instance::refresh_canvas_tree()
+{
+       canvas_tree_store()->clear();
+       Gtk::TreeRow row = *(canvas_tree_store()->prepend());
+       insert_canvas(row,get_canvas());
+}
+
+void
+Instance::dialog_cvs_commit()
+{
+       calc_repository_info();
+       if(!in_repository())
+       {
+               App::dialog_error_blocking(_("Error"),_("You must first add this composition to the repository"));
+               return;
+       }
+       try
+       {
+               string message;
+
+               if(sinfgapp::Instance::get_action_count())
+               {
+                       if(!App::dialog_yes_no(_("CVS Commit"), _("This will save any changes you have made. Are you sure?")))
+                               return;
+                       save();
+               }
+
+               if(!is_modified())
+               {
+                       App::dialog_error_blocking(_("Error"),_("The local copy of the file hasn't been changed since the last update.\nNothing to commit!"));
+                       return;
+               }
+
+               if(!App::dialog_entry(_("CVS Commit"),_("Enter a log message describing the changes you have made"), message))
+                       return;
+               
+               OneMoment one_moment;
+               cvs_commit(message);
+       }
+       catch(...)
+       {
+               App::dialog_error_blocking(_("Error"),_("An error has occured when trying to COMMIT"));
+       }
+       update_all_titles();
+}
+
+void
+Instance::dialog_cvs_add()
+{
+       calc_repository_info();
+       if(in_repository())
+       {
+               App::dialog_error_blocking(_("Error"),_("This composition has already been added to the repository"));
+               return;
+       }
+       try
+       {
+               string message;
+               
+               //if(!App::dialog_entry(_("CVS Add"),_("Enter a log message describing the file"), message))
+               //      return;
+               OneMoment one_moment;
+               cvs_add();
+       }
+       catch(...)
+       {
+               App::dialog_error_blocking(_("Error"),_("An error has occured when trying to ADD"));
+       }
+       update_all_titles();
+}
+
+void
+Instance::dialog_cvs_update()
+{
+       calc_repository_info();
+       if(!in_repository())
+       {
+               App::dialog_error_blocking(_("Error"),_("This file is not under version control, so there is nothing to update from!"));
+               return;
+       }
+       if(!is_updated())
+       {
+               App::dialog_error_blocking(_("Info"),_("This file is up-to-date"));
+               return;
+       }
+       
+       try
+       {
+               String filename(get_file_name());
+               if(sinfgapp::Instance::get_action_count())
+               {
+                       if(!App::dialog_yes_no(_("CVS Update"), _("This will save any changes you have made. Are you sure?")))
+                               return;
+                       save();
+               }
+               OneMoment one_moment;
+               time_t oldtime=get_original_timestamp();
+               cvs_update();
+               calc_repository_info();         
+               // If something has been updated...
+               if(oldtime!=get_original_timestamp())
+               {
+                       revert();
+               }
+       }
+       catch(...)
+       {
+               App::dialog_error_blocking(_("Error"),_("An error has occured when trying to UPDATE"));
+       }
+       //update_all_titles();
+}
+
+void
+Instance::dialog_cvs_revert()
+{
+       calc_repository_info();
+       if(!in_repository())
+       {
+               App::dialog_error_blocking(_("Error"),_("This file is not under version control, so there is nothing to revert to!"));
+               return;
+       }
+       try
+       {
+               String filename(get_file_name());
+               if(!App::dialog_yes_no(_("CVS Revert"),
+                       _("This will abandon all changes you have made\nsince the last time you performed a commit\noperation. This cannot be undone! Are you sure\nyou want to do this?")
+               ))
+                       return;
+
+               OneMoment one_moment;
+
+               // Remove the old file
+               if(remove(get_file_name().c_str())!=0)
+               {
+                       App::dialog_error_blocking(_("Error"),_("Unable to remove previous version"));
+                       return;
+               }
+
+               cvs_update();
+               revert();
+       }
+       catch(...)
+       {
+               App::dialog_error_blocking(_("Error"),_("An error has occured when trying to UPDATE"));
+       }
+       //update_all_titles();
+}
+
+void
+Instance::_revert(Instance *instance)
+{
+       OneMoment one_moment;
+
+       String filename(instance->get_file_name());
+
+       Canvas::Handle canvas(instance->get_canvas());
+       
+       instance->close();
+
+       if(canvas->count()!=1)
+       {
+               one_moment.hide();
+               App::dialog_error_blocking(_("Error: Revert Failed"),_("The revert operation has failed. This can be due to it being\nreferenced by another composition that is already open, or\nbecause of an internal error in SINFG Studio. Try closing any\ncompositions that might reference this composition and try\nagain, or restart SINFG studio."));
+               one_moment.show();
+       }
+       canvas=0;
+       
+       App::open(filename);
+}
+
+void
+Instance::revert()
+{
+       // Schedule a revert to occur in a few moments
+       Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::bind(
+                               sigc::ptr_fun(&Instance::_revert),
+                               this
+                       ),
+                       false
+               )
+               ,500
+       );
+}
+
+bool
+Instance::safe_revert()
+{
+       if(sinfgapp::Instance::get_action_count())
+               if(!App::dialog_yes_no(_("Revert to saved"), _("You will loose any changes you have made since your last save.\nAre you sure?")))
+                       return false;
+       revert();
+       return true;
+}
+
+bool
+Instance::safe_close()
+{
+       handle<sinfgapp::UIInterface> uim;
+       uim=find_canvas_view(get_canvas())->get_ui_interface();
+
+       if(get_action_count())
+       {
+               string str=strprintf(_("Would you like to save your changes to %s?"),basename(get_file_name()).c_str() );
+               int answer=uim->yes_no_cancel(get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES);
+               if(answer==sinfgapp::UIInterface::RESPONSE_YES)
+                       save();
+               if(answer==sinfgapp::UIInterface::RESPONSE_CANCEL)
+                       return false;
+       }
+
+       if(is_modified())
+       {
+               string str=strprintf(_("%s has changes not yet on the CVS repository.\nWould you like to commit these changes?"),basename(get_file_name()).c_str());
+               int answer=uim->yes_no_cancel(get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES);
+
+               if(answer==sinfgapp::UIInterface::RESPONSE_YES)
+                       dialog_cvs_commit();
+               if(answer==sinfgapp::UIInterface::RESPONSE_CANCEL)
+                       return false;
+       }
+       
+       close();
+
+       while(studio::App::events_pending())studio::App::iteration(false);
+
+       return true;
+}
+
+
+void
+Instance::add_actions_to_group(const Glib::RefPtr<Gtk::ActionGroup>& action_group, sinfg::String& ui_info,   const sinfgapp::Action::ParamList &param_list, sinfgapp::Action::Category category)const
+{
+       sinfgapp::Action::CanidateList canidate_list;
+       sinfgapp::Action::CanidateList::iterator iter;
+       
+       canidate_list=compile_canidate_list(param_list,category);
+       
+       canidate_list.sort();
+
+       if(canidate_list.empty())
+               sinfg::warning("Action CanidateList is empty!");
+       
+       for(iter=canidate_list.begin();iter!=canidate_list.end();++iter)
+       {
+               Gtk::StockID stock_id(get_action_stock_id(*iter));
+               
+               if(!(iter->category&sinfgapp::Action::CATEGORY_HIDDEN))
+               {
+                       action_group->add(Gtk::Action::create(
+                               "action-"+iter->name,
+                               stock_id,
+                               iter->local_name,iter->local_name
+                       ),
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *const_cast<studio::Instance*>(this),
+                                                       &studio::Instance::process_action
+                                               ),
+                                               param_list
+                                       ),
+                                       iter->name
+                               )
+                       );
+                       ui_info+=strprintf("<menuitem action='action-%s' />",iter->name.c_str());
+               }
+       }
+}
+
+void
+Instance::add_actions_to_menu(Gtk::Menu *menu, const sinfgapp::Action::ParamList &param_list,sinfgapp::Action::Category category)const
+{
+       sinfgapp::Action::CanidateList canidate_list;
+       sinfgapp::Action::CanidateList::iterator iter;
+       
+       canidate_list=compile_canidate_list(param_list,category);
+       
+       canidate_list.sort();
+
+       if(canidate_list.empty())
+               sinfg::warning("Action CanidateList is empty!");
+       
+       for(iter=canidate_list.begin();iter!=canidate_list.end();++iter)
+       {
+               if(!(iter->category&sinfgapp::Action::CATEGORY_HIDDEN))
+               {
+                       Gtk::Image* image(manage(new Gtk::Image()));
+                       Gtk::Stock::lookup(get_action_stock_id(*iter),Gtk::ICON_SIZE_MENU,*image);
+                       
+                       /*
+                       if(iter->task=="raise")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_UP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="lower")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_DOWN,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_top")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_TOP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_bottom")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_BOTTOM,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_on")
+                               Gtk::Stock::lookup(Gtk::Stock::YES,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_off")
+                               Gtk::Stock::lookup(Gtk::Stock::NO,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="duplicate")
+                               Gtk::Stock::lookup(Gtk::Stock::COPY,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else
+                       {
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->name),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("gtk-"+iter->task),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->task),Gtk::ICON_SIZE_MENU,*image);
+                       }
+                       */
+                       menu->items().push_back(
+                               Gtk::Menu_Helpers::ImageMenuElem(
+                                       iter->local_name,
+                                       *image,
+                                       sigc::bind(
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *const_cast<studio::Instance*>(this),
+                                                               &studio::Instance::process_action
+                                                       ),
+                                                       param_list
+                                               ),
+                                               iter->name
+                                       )
+                               )
+                       );
+               }
+       }
+}
+
+void
+Instance::add_actions_to_menu(Gtk::Menu *menu, const sinfgapp::Action::ParamList &param_list,const sinfgapp::Action::ParamList &param_list2,sinfgapp::Action::Category category)const
+{
+       sinfgapp::Action::CanidateList canidate_list;
+       sinfgapp::Action::CanidateList canidate_list2;
+       
+       sinfgapp::Action::CanidateList::iterator iter;
+       
+       canidate_list=compile_canidate_list(param_list,category);
+       canidate_list2=compile_canidate_list(param_list2,category);
+       
+       canidate_list.sort();
+
+       if(canidate_list.empty())
+               sinfg::warning("Action CanidateList is empty!");
+       if(canidate_list2.empty())
+               sinfg::warning("Action CanidateList2 is empty!");
+
+       // Seperate out the canidate lists so that there are no conflicts
+       for(iter=canidate_list.begin();iter!=canidate_list.end();++iter)
+       {
+               sinfgapp::Action::CanidateList::iterator iter2(canidate_list2.find(iter->name));
+               if(iter2!=canidate_list2.end())
+                       canidate_list2.erase(iter2);
+       }
+               
+       for(iter=canidate_list2.begin();iter!=canidate_list2.end();++iter)
+       {
+               if(!(iter->category&sinfgapp::Action::CATEGORY_HIDDEN))
+               {
+                       Gtk::Image* image(manage(new Gtk::Image()));
+                       Gtk::Stock::lookup(get_action_stock_id(*iter),Gtk::ICON_SIZE_MENU,*image);
+
+/*                     if(iter->task=="raise")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_UP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="lower")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_DOWN,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_top")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_TOP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_bottom")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_BOTTOM,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_on")
+                               Gtk::Stock::lookup(Gtk::Stock::YES,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_off")
+                               Gtk::Stock::lookup(Gtk::Stock::NO,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="duplicate")
+                               Gtk::Stock::lookup(Gtk::Stock::COPY,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else
+                       {
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->name),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("gtk-"+iter->task),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->task),Gtk::ICON_SIZE_MENU,*image);
+                       }
+*/
+                       menu->items().push_back(
+                               Gtk::Menu_Helpers::ImageMenuElem(
+                                       iter->local_name,
+                                       *image,
+                                       sigc::bind(
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *const_cast<studio::Instance*>(this),
+                                                               &studio::Instance::process_action
+                                                       ),
+                                                       param_list2
+                                               ),
+                                               iter->name
+                                       )
+                               )
+                       );
+               }
+       }
+
+       for(iter=canidate_list.begin();iter!=canidate_list.end();++iter)
+       {
+               if(!(iter->category&sinfgapp::Action::CATEGORY_HIDDEN))
+               {
+                       Gtk::Image* image(manage(new Gtk::Image()));
+                       Gtk::Stock::lookup(get_action_stock_id(*iter),Gtk::ICON_SIZE_MENU,*image);
+/*                     if(iter->task=="raise")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_UP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="lower")
+                               Gtk::Stock::lookup(Gtk::Stock::GO_DOWN,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_top")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_TOP,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="move_bottom")
+                               Gtk::Stock::lookup(Gtk::Stock::GOTO_BOTTOM,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_on")
+                               Gtk::Stock::lookup(Gtk::Stock::YES,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="set_off")
+                               Gtk::Stock::lookup(Gtk::Stock::NO,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="duplicate")
+                               Gtk::Stock::lookup(Gtk::Stock::COPY,Gtk::ICON_SIZE_MENU,*image);
+                       else if(iter->task=="remove")
+                               Gtk::Stock::lookup(Gtk::Stock::DELETE,Gtk::ICON_SIZE_MENU,*image);
+                       else
+                       {
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->name),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("gtk-"+iter->task),Gtk::ICON_SIZE_MENU,*image) ||
+                               Gtk::Stock::lookup(Gtk::StockID("sinfg-"+iter->task),Gtk::ICON_SIZE_MENU,*image);
+                       }
+*/
+                       menu->items().push_back(
+                               Gtk::Menu_Helpers::ImageMenuElem(
+                                       iter->local_name,
+                                       *image,
+                                       sigc::bind(
+                                               sigc::bind(
+                                                       sigc::mem_fun(
+                                                               *const_cast<studio::Instance*>(this),
+                                                               &studio::Instance::process_action
+                                                       ),
+                                                       param_list
+                                               ),
+                                               iter->name
+                                       )
+                               )
+                       );
+               }
+       }
+}
+
+void
+Instance::process_action(String name, sinfgapp::Action::ParamList param_list)
+{
+       assert(sinfgapp::Action::book().count(name));
+
+       sinfgapp::Action::BookEntry entry(sinfgapp::Action::book().find(name)->second);
+       
+       sinfgapp::Action::Handle action(entry.factory());
+
+       if(!action)
+       {
+               sinfg::error("Bad Action");
+               return;
+       }
+       
+       action->set_param_list(param_list);
+
+       sinfgapp::Action::ParamVocab param_vocab(entry.get_param_vocab());
+       sinfgapp::Action::ParamVocab::const_iterator iter;
+       
+       for(iter=param_vocab.begin();iter!=param_vocab.end();++iter)
+       {
+               if(!iter->get_mutual_exclusion().empty() && param_list.count(iter->get_mutual_exclusion()))
+                       continue;
+
+               // If the parameter is optionally user-supplied,
+               // and has not been already provided in the param_list,
+               // then we should go ahead and see if we can
+               // provide that data.
+               if(iter->get_user_supplied() && param_list.count(iter->get_name())==0)
+               {
+                       switch(iter->get_type())
+                       {
+                       case sinfgapp::Action::Param::TYPE_STRING:
+                       {
+                               String str;
+                               if(!studio::App::dialog_entry(entry.local_name, iter->get_local_name()+":"+iter->get_desc(),str))
+                                       return;
+                               action->set_param(iter->get_name(),str);
+                               break;
+                       }
+                       default:
+                               sinfg::error("Unsupported user-supplied action parameter");
+                               return;
+                               break;
+                       }
+               }
+       }
+               
+       if(!action->is_ready())
+       {
+               sinfg::error("Action not ready");
+               return;
+       }
+
+       perform_action(action);
+}
+
+void
+Instance::make_param_menu(Gtk::Menu *menu,sinfg::Canvas::Handle canvas, sinfgapp::ValueDesc value_desc, float location)
+{
+       Gtk::Menu& parammenu(*menu);
+       
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface(find_canvas_interface(canvas));
+       
+       if(!canvas_interface)
+               return;
+       
+       sinfgapp::Action::ParamList param_list,param_list2;
+       param_list=canvas_interface->generate_param_list(value_desc);
+       param_list.add("origin",location);
+
+       if(value_desc.get_value_type()==ValueBase::TYPE_BLINEPOINT && value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               param_list2=canvas_interface->generate_param_list(
+                       sinfgapp::ValueDesc(
+                               ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
+                               ,0
+                       )
+               );
+               param_list2.add("origin",location);
+       }
+
+       
+       // Populate the convert menu by looping through
+       // the ValueNode book and find the ones that are
+       // relevant.
+       {
+               Gtk::Menu *convert_menu=manage(new Gtk::Menu());
+               LinkableValueNode::Book::const_iterator iter;
+               for(iter=LinkableValueNode::book().begin();iter!=LinkableValueNode::book().end();++iter)
+               {
+                       if(iter->second.check_type(value_desc.get_value_type()))
+                       {
+                               convert_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->second.local_name,
+                                       sigc::hide_return(
+                                               sigc::bind(
+                                                       sigc::bind(
+                                                               sigc::mem_fun(*canvas_interface.get(),&sinfgapp::CanvasInterface::convert),
+                                                               iter->first
+                                                       ),
+                                                       value_desc
+                                               )
+                                       )
+                               ));
+                       }
+               }
+
+               parammenu.items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::CONVERT,*convert_menu));                       
+       }
+
+       if(param_list2.empty())
+               add_actions_to_menu(&parammenu, param_list,sinfgapp::Action::CATEGORY_VALUEDESC|sinfgapp::Action::CATEGORY_VALUENODE);
+       else
+               add_actions_to_menu(&parammenu, param_list2,param_list,sinfgapp::Action::CATEGORY_VALUEDESC|sinfgapp::Action::CATEGORY_VALUENODE);
+
+       if(value_desc.get_value_type()==ValueBase::TYPE_BLINEPOINT && value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               value_desc=sinfgapp::ValueDesc(ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()),0);
+       }
+
+       if(value_desc.is_value_node() && ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()));
+               
+               try
+               {
+                       WaypointList::iterator iter(value_node->find(canvas->get_time()));
+                       parammenu.items().push_back(Gtk::Menu_Helpers::MenuElem(_("Edit Waypoint"),
+                               sigc::bind(
+                                       sigc::bind(
+                                               sigc::bind(
+                                                       sigc::mem_fun(*find_canvas_view(canvas),&studio::CanvasView::on_waypoint_clicked),
+                                                       -1
+                                               ),
+                                               *iter
+                                       ),
+                                       value_desc
+                               )
+                       ));
+               }
+               catch(...)
+               {
+               }
+       }
+}
+
+void
+edit_several_waypoints(etl::handle<CanvasView> canvas_view, std::list<sinfgapp::ValueDesc> value_desc_list)
+{
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface(canvas_view->canvas_interface());
+
+       Gtk::Dialog dialog(
+               "Edit Multiple Waypoints",              // Title
+               true,           // Modal
+               true            // use_separator
+       );
+
+       Widget_WaypointModel widget_waypoint_model;
+       widget_waypoint_model.show();
+
+       dialog.get_vbox()->pack_start(widget_waypoint_model);
+       
+       
+       dialog.add_button(Gtk::StockID("gtk-apply"),1);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),0);
+       dialog.show();
+       
+       DEBUGPOINT();
+       if(dialog.run()==0 || widget_waypoint_model.get_waypoint_model().is_trivial())
+               return;
+       DEBUGPOINT();
+       sinfgapp::Action::PassiveGrouper group(canvas_interface->get_instance().get(),_("Set Waypoints"));
+
+       std::list<sinfgapp::ValueDesc>::iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               sinfgapp::ValueDesc value_desc(*iter);
+               
+               if(!value_desc.is_valid())
+                       continue;
+
+               ValueNode_Animated::Handle value_node;
+               
+               // If this value isn't a ValueNode_Animated, but
+               // it is somewhat constant, then go ahead and convert
+               // it to a ValueNode_Animated.
+               if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+               {
+                       ValueBase value;
+                       if(value_desc.is_value_node())
+                               value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
+                       else
+                               value=value_desc.get_value();
+                       
+                       value_node=ValueNode_Animated::create(value,canvas_interface->get_time());
+                       
+                       sinfgapp::Action::Handle action;
+                       
+                       if(!value_desc.is_value_node())
+                       {
+                               action=sinfgapp::Action::create("value_desc_connect");
+                               action->set_param("dest",value_desc);
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       else
+                       {
+                               action=sinfgapp::Action::create("value_node_replace");
+                               action->set_param("dest",value_desc.get_value_node());
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       
+                       action->set_param("canvas",canvas_view->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface);
+                       
+       
+                       if(!canvas_interface->get_instance()->perform_action(action))
+                       {
+                               canvas_view->get_ui_interface()->error(_("Unable to convert to animated waypoint"));
+                               group.cancel();
+                               return;
+                       }
+               }
+               else
+               {
+                       if(value_desc.is_value_node())
+                               value_node=ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node());
+               }
+               
+               
+               if(value_node)
+               {
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("waypoint_set_smart"));
+
+                       if(!action)
+                       {
+                               canvas_view->get_ui_interface()->error(_("Unable to find waypoint_set_smart action"));
+                               group.cancel();
+                               return;
+                       }
+                               
+
+                       action->set_param("canvas",canvas_view->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface);                 
+                       action->set_param("value_node",ValueNode::Handle(value_node));                  
+                       action->set_param("time",canvas_interface->get_time());                                         
+                       action->set_param("model",widget_waypoint_model.get_waypoint_model());
+               
+                       if(!canvas_interface->get_instance()->perform_action(action))
+                       {
+                               canvas_view->get_ui_interface()->error(_("Unable to set a specific waypoint"));
+                               group.cancel();
+                               return;
+                       }
+               }
+               else
+               {
+                       //get_canvas_view()->get_ui_interface()->error(_("Unable to animate a specific valuedesc"));
+                       //group.cancel();
+                       //return;
+               }
+                       
+       }
+}
+
+void
+Instance::make_param_menu(Gtk::Menu *menu,sinfg::Canvas::Handle canvas,const std::list<sinfgapp::ValueDesc>& value_desc_list)
+{
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface(find_canvas_interface(canvas));
+
+       sinfgapp::Action::ParamList param_list;
+       param_list=canvas_interface->generate_param_list(value_desc_list);
+
+       add_actions_to_menu(menu, param_list,sinfgapp::Action::CATEGORY_VALUEDESC|sinfgapp::Action::CATEGORY_VALUENODE);
+
+       // Add the edit waypoints option if that might be useful
+       if(canvas->rend_desc().get_time_end()-Time::epsilon()>canvas->rend_desc().get_time_start())
+       {
+               menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Edit Waypoints"),
+                       sigc::bind(
+                               sigc::bind(
+                                       sigc::ptr_fun(
+                                               &edit_several_waypoints
+                                       ),
+                                       value_desc_list
+                               ),
+                               find_canvas_view(canvas)
+                       )
+               ));
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/instance.h b/synfig-studio/trunk/src/gtkmm/instance.h
new file mode 100644 (file)
index 0000000..bd68918
--- /dev/null
@@ -0,0 +1,223 @@
+/* === S I N F G =========================================================== */
+/*!    \file instance.h
+**     \brief writeme
+**
+**     $Id: instance.h,v 1.2 2005/01/13 18:37:30 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_INSTANCE_H
+#define __SINFG_STUDIO_INSTANCE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <sinfgapp/instance.h>
+#include <sigc++/object.h>
+#include <sinfgapp/value_desc.h>
+#include "historytreestore.h"
+#include <sinfg/canvas.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; class ActionGroup; };
+
+namespace studio {
+
+class CanvasView;
+       
+
+class Instance : public sinfgapp::Instance
+{
+public:
+       typedef std::list< etl::handle<CanvasView> > CanvasViewList;
+
+       class CanvasTreeModel : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::ustring> id;
+
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle> canvas;
+               Gtk::TreeModelColumn<bool> is_canvas;
+
+               Gtk::TreeModelColumn<sinfg::ValueNode::Handle> value_node;
+               Gtk::TreeModelColumn<bool> is_value_node;
+               Gtk::TreeModelColumn<sinfg::ValueBase> value;
+               Gtk::TreeModelColumn<Glib::ustring> type;
+               Gtk::TreeModelColumn<int> link_id;
+               Gtk::TreeModelColumn<int> link_count;
+
+               Gtk::TreeModelColumn<bool> is_editable;
+
+               Gtk::TreeModelColumn<sinfgapp::ValueDesc> value_desc;
+       
+               CanvasTreeModel()
+               {
+                       add(value);
+                       add(name);
+                       add(label);
+                       add(icon);
+                       add(type);
+                       add(id);
+                       add(canvas);
+                       add(value_node);
+                       add(is_canvas);
+                       add(is_value_node);
+
+                       add(is_editable);
+                       add(value_desc);
+                       add(link_count);
+                       add(link_id);
+               }
+       } canvas_tree_model;
+       
+private:
+
+       sigc::signal<void,CanvasView*> signal_canvas_view_created_;
+       sigc::signal<void,CanvasView*> signal_canvas_view_deleted_;
+       
+       sigc::signal<void> signal_undo_redo_status_changed_;
+
+       //! Tree containing the canvases -- used for the "canvas browser"
+       Glib::RefPtr<Gtk::TreeStore> canvas_tree_store_;
+
+       //! Tree containing the actions -- used for the "canvas browser"
+       Glib::RefPtr<HistoryTreeStore> history_tree_store_;
+
+       //! Instance number
+       int     id_;
+
+       //! Used to calculate instance ID
+       static int instance_count_;
+
+       //! List of canvas view windows
+       CanvasViewList canvas_view_list_;
+       
+       bool undo_status_;
+       bool redo_status_;
+
+       void set_undo_status(bool x);
+       void set_redo_status(bool x);
+
+       static void _revert(Instance *);
+
+protected:
+
+       Instance(sinfg::Canvas::Handle);
+
+public:
+
+       sigc::signal<void>& signal_undo_redo_status_changed() { return signal_undo_redo_status_changed_; }
+
+       ~Instance();
+
+       sigc::signal<void,CanvasView*>& signal_canvas_view_created() { return signal_canvas_view_created_; }
+       sigc::signal<void,CanvasView*>& signal_canvas_view_deleted() { return signal_canvas_view_deleted_; }
+
+       bool get_undo_status()const { return undo_status_; }
+
+       bool get_redo_status()const { return redo_status_; }
+
+       int get_visible_canvases()const;
+       
+       Glib::RefPtr<Gtk::TreeStore> canvas_tree_store() { return canvas_tree_store_; }
+
+       Glib::RefPtr<const Gtk::TreeStore> canvas_tree_store()const { return canvas_tree_store_; }
+
+       Glib::RefPtr<HistoryTreeStore> history_tree_store() { return history_tree_store_; }
+
+       Glib::RefPtr<const HistoryTreeStore> history_tree_store()const { return history_tree_store_; }
+
+       //! Returns the number of instances that are currently open in the program
+       static int get_count() { return instance_count_; }
+
+       //etl::handle<sinfg::Canvas> get_canvas()const { return sinfgapp::Instance::get_canvas(); }
+       
+       etl::handle<CanvasView> find_canvas_view(etl::handle<sinfg::Canvas> canvas);
+
+       //! Sets the focus to a specific canvas
+       void focus(etl::handle<sinfg::Canvas> canvas);
+
+       CanvasViewList & canvas_view_list() { return canvas_view_list_; }
+       
+       const CanvasViewList & canvas_view_list()const { return canvas_view_list_; }
+
+       bool save_as(const sinfg::String &filename)const;
+
+       bool save_as(const sinfg::String &filename);
+
+       //! Opens a "Save As" dialog, and then saves the composition to that file
+       void dialog_save_as();
+
+       bool save();
+
+       void dialog_cvs_commit();
+
+       void dialog_cvs_add();
+
+       void dialog_cvs_update();
+
+       void dialog_cvs_revert();
+       
+       //! Closes the instance of this composition
+       void close();
+       
+       void revert();
+       
+       void update_all_titles();
+
+       void refresh_canvas_tree();
+       
+       bool safe_revert();
+       bool safe_close();
+
+       void add_actions_to_menu(Gtk::Menu *menu,   const sinfgapp::Action::ParamList &param_list, sinfgapp::Action::Category category=sinfgapp::Action::CATEGORY_ALL)const;
+       void add_actions_to_menu(Gtk::Menu *menu, const sinfgapp::Action::ParamList &param_list1,const sinfgapp::Action::ParamList &param_list2, sinfgapp::Action::Category category=sinfgapp::Action::CATEGORY_ALL)const;
+
+       void add_actions_to_group(const Glib::RefPtr<Gtk::ActionGroup>& action_group, sinfg::String& ui_info,   const sinfgapp::Action::ParamList &param_list, sinfgapp::Action::Category category=sinfgapp::Action::CATEGORY_ALL)const;
+
+       void process_action(sinfg::String name, sinfgapp::Action::ParamList param_list);
+
+       void make_param_menu(Gtk::Menu *menu,sinfg::Canvas::Handle canvas, sinfgapp::ValueDesc value_desc, float location=0.5f);
+
+       void make_param_menu(Gtk::Menu *menu,sinfg::Canvas::Handle canvas,const std::list<sinfgapp::ValueDesc>& value_desc_list);
+
+
+       static void edit_waypoint(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint);
+
+private:
+       void insert_canvas(Gtk::TreeRow row,sinfg::Canvas::Handle canvas);
+
+public:
+       static etl::handle<Instance> create(sinfg::Canvas::Handle canvas);
+}; // END class Instance
+
+}; // END namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/ipc.cpp b/synfig-studio/trunk/src/gtkmm/ipc.cpp
new file mode 100644 (file)
index 0000000..630063c
--- /dev/null
@@ -0,0 +1,324 @@
+/* === S I N F G =========================================================== */
+/*!    \file ipc.cpp
+**     \brief Template File
+**
+**     $Id: ipc.cpp,v 1.6 2005/01/16 19:55:57 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "ipc.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include <sinfg/main.h>
+#include "app.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#define BUFSIZE   128
+#define read   _read
+#endif
+
+#include "toolbox.h"
+#include <glibmm/dispatcher.h>
+#include <sinfg/mutex.h>
+#include <sinfg/string.h>
+#include <glibmm/thread.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+#ifdef _WIN32
+#define WIN32_PIPE_PATH "\\\\.\\pipe\\SynfigStudio.Cmd"
+static sinfg::Mutex cmd_mutex;
+static std::list<sinfg::String> cmd_queue;
+static Glib::Dispatcher* cmd_dispatcher;
+static void
+pipe_listen_thread()
+{
+       for(;;)
+       {
+               HANDLE pipe_handle;
+               pipe_handle=CreateNamedPipe(
+                       WIN32_PIPE_PATH, // pipe name
+                       PIPE_ACCESS_INBOUND, // Access type
+                       PIPE_READMODE_BYTE /*|PIPE_NOWAIT*/,
+                       PIPE_UNLIMITED_INSTANCES,
+                       BUFSIZE,
+                       BUFSIZE,
+                       NMPWAIT_USE_DEFAULT_WAIT,
+                       NULL
+               );
+               if(pipe_handle==INVALID_HANDLE_VALUE)
+               {
+                       sinfg::error("IPC(): Call to CreateNamedPipe failed. Ignore next error. GetLastError=%d",GetLastError());
+                       return;
+               }
+               
+               bool connected;
+               connected=ConnectNamedPipe(pipe_handle,NULL)?true:(GetLastError()==ERROR_PIPE_CONNECTED);
+               DWORD read_bytes;
+               bool success;
+
+               Glib::Thread::yield();
+
+               if(connected)
+               do {
+                       String data;
+                       char c;                 
+                       do
+                       {
+                               success= ReadFile(
+                                       pipe_handle,
+                                       &c,             // buffer pointer
+                                       1,              // buffer size
+                                       &read_bytes,
+                                       NULL
+                               );
+                               if(success && read_bytes==1 && c!='\n')
+                                       data+=c;
+                       }while(c!='\n');
+                       sinfg::Mutex::Lock lock(cmd_mutex);
+                       cmd_queue.push_back(data);
+                       cmd_dispatcher->emit();
+               } while(success && read_bytes);
+               
+               CloseHandle(pipe_handle);
+       }
+}
+
+static void
+empty_cmd_queue()
+{
+       sinfg::Mutex::Lock lock(cmd_mutex);
+       while(!cmd_queue.empty())
+       {
+               IPC::process_command(cmd_queue.front());
+               cmd_queue.pop_front();
+       }
+}
+
+#endif
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+IPC::IPC()
+{
+#ifdef _WIN32
+
+       cmd_dispatcher=new Glib::Dispatcher;
+       cmd_dispatcher->connect(sigc::ptr_fun(empty_cmd_queue));
+       
+       Glib::Thread::create(
+               sigc::ptr_fun(pipe_listen_thread),
+               false
+       );
+       
+#else
+       
+       remove(fifo_path().c_str());
+       fd=-1;
+       
+       if(mkfifo(fifo_path().c_str(), S_IRWXU)!=0)
+       {
+               sinfg::error("IPC(): mkfifo failed for "+fifo_path());
+       }
+       
+       {
+               fd=open(fifo_path().c_str(),O_RDWR);
+
+
+               if(fd<0)
+               {
+                       sinfg::error("IPC(): Failed to open fifo \"%s\". (errno=%d)",fifo_path().c_str(),errno);
+               }
+               else
+               {
+                       file=SmartFILE(fdopen(fd,"r"));
+                       
+                       Glib::signal_io().connect(
+                               sigc::mem_fun(this,&IPC::fifo_activity),
+                               fd,
+                               Glib::IO_IN|Glib::IO_PRI|Glib::IO_ERR|Glib::IO_HUP|Glib::IO_NVAL
+                       );
+               }
+       }
+#endif
+}
+
+IPC::~IPC()
+{
+       //if(file)
+       //      fclose(file.get());
+
+       remove(fifo_path().c_str());
+       
+       //if(fd>=0)
+       //      close(fd);
+}
+
+sinfg::String
+IPC::fifo_path()
+{
+#ifdef _WIN32
+       return WIN32_PIPE_PATH;
+#else
+       return Glib::build_filename(App::get_user_app_directory(),"fifo");
+#endif
+}
+
+bool
+IPC::fifo_activity(Glib::IOCondition cond)
+{
+       sinfg::info(__FILE__":%d: fifo activity",__LINE__);
+       
+       if(cond&(Glib::IO_ERR|Glib::IO_HUP|Glib::IO_NVAL))
+       {
+               if(cond&(Glib::IO_ERR))
+                       sinfg::error("IPC::fifo_activity(): IO_ERR");
+               if(cond&(Glib::IO_HUP))
+                       sinfg::error("IPC::fifo_activity(): IO_HUP");
+               if(cond&(Glib::IO_NVAL))
+                       sinfg::error("IPC::fifo_activity(): IO_NVAL");
+               return false;
+       }
+       sinfg::info(__FILE__":%d: fifo activity",__LINE__);
+
+       String command;
+       {
+               char tmp;
+               do {
+                       if(read(fd,&tmp,sizeof(tmp))<=0)
+                               break;
+                       if(tmp!='\n')
+                               command+=tmp;
+               } while(tmp!='\n');
+       }
+       
+       process_command(command);
+       return true;
+}
+
+bool
+IPC::process_command(const sinfg::String& command_line)
+{
+       if(command_line.empty())
+               return false;
+       
+       char cmd=command_line[0];
+       
+       String args(command_line.begin()+1,command_line.end());
+       while(!args.empty() && args[0]==' ') args.erase(args.begin());
+       while(!args.empty() && args[args.size()-1]=='\n' || args[args.size()-1]==' ') args.erase(args.end()-1);
+       
+       switch(toupper(cmd))
+       {
+               case 'F': // Focus/Foreground
+                       App::signal_present_all()();
+                       break;
+               case 'N': // New file
+                       App::signal_present_all()();
+                       App::new_instance();
+                       break;
+               case 'O': // Open <arg>
+                       App::signal_present_all()();
+                       App::open(args);
+                       break;
+               case 'X': // Quit
+               case 'Q': // Quit
+                       App::quit();
+                       break;
+               default:
+                       sinfg::warning("Received unknown command '%c' with arg '%s'",cmd,args.c_str());
+                       break;
+       }
+       
+       return true;
+}
+
+sinfg::SmartFILE
+IPC::make_connection()
+{
+       SmartFILE ret;
+#ifdef _WIN32
+       HANDLE pipe_handle;
+       pipe_handle=CreateFile(
+               fifo_path().c_str(),
+               GENERIC_WRITE, // desired access
+               0, // share mode
+               NULL, // security attributes
+               OPEN_EXISTING, // creation disposition
+               FILE_ATTRIBUTE_NORMAL, // flags and attributes
+               NULL  // template file 
+       );
+       if(pipe_handle==INVALID_HANDLE_VALUE)
+       {
+               sinfg::warning("IPC::make_connection(): Unable to connect to previous instance. GetLastError=%d",GetLastError());
+       }
+       int fd=_open_osfhandle(reinterpret_cast<long int>(pipe_handle),_O_APPEND|O_WRONLY);
+#else
+       struct stat file_stat;
+       if(stat(fifo_path().c_str(),&file_stat)!=0)
+               return ret;
+       
+       if(!S_ISFIFO(file_stat.st_mode))
+               return ret;
+       
+       int fd=open(fifo_path().c_str(),O_WRONLY|O_NONBLOCK);
+#endif
+       
+       if(fd>=0)
+               ret=SmartFILE(fdopen(fd,"w"));
+
+       sinfg::info("uplink fd=%d",fd);
+
+       return ret;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/ipc.h b/synfig-studio/trunk/src/gtkmm/ipc.h
new file mode 100644 (file)
index 0000000..b38e033
--- /dev/null
@@ -0,0 +1,64 @@
+/* === S I N F G =========================================================== */
+/*!    \file ipc.h
+**     \brief Template Header
+**
+**     $Id: ipc.h,v 1.2 2005/01/12 00:31:11 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_IPC_H
+#define __SINFG_IPC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/smartfile.h>
+#include <glibmm/main.h>
+#include <sinfg/string.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class IPC
+{
+private:
+
+       int fd;
+       sinfg::SmartFILE file;
+
+       bool fifo_activity(Glib::IOCondition cond);
+
+public:
+       IPC();
+       ~IPC();
+
+       static sinfg::String fifo_path();
+       static sinfg::SmartFILE make_connection();
+
+       static bool process_command(const sinfg::String& cmd);
+}; // END of class IPC
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/keyframeactionmanager.cpp b/synfig-studio/trunk/src/gtkmm/keyframeactionmanager.cpp
new file mode 100644 (file)
index 0000000..2d44451
--- /dev/null
@@ -0,0 +1,246 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeactionmanager.cpp
+**     \brief Template File
+**
+**     $Id: keyframeactionmanager.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframeactionmanager.h"
+#include "keyframetree.h"
+#include <sinfgapp/action_param.h>
+#include "instance.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+static const guint no_prev_popup((guint)-1);
+
+/* === M A C R O S ========================================================= */
+
+//#define ONE_ACTION_GROUP 1
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+KeyframeActionManager::KeyframeActionManager():
+       action_group_(Gtk::ActionGroup::create()),
+       popup_id_(no_prev_popup),
+       queued(false)
+{
+}
+
+KeyframeActionManager::~KeyframeActionManager()
+{
+}
+
+void
+KeyframeActionManager::set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x)
+{
+       clear();
+
+#ifdef ONE_ACTION_GROUP
+       if(ui_manager_) get_ui_manager()->remove_action_group(action_group_);
+       ui_manager_=x;
+       if(ui_manager_) get_ui_manager()->insert_action_group(action_group_);
+#else
+       ui_manager_=x;
+#endif
+}
+
+void
+KeyframeActionManager::set_keyframe_tree(KeyframeTree* x)
+{
+       selection_changed_connection.disconnect();
+       keyframe_tree_=x;
+       if(keyframe_tree_)
+       {
+               selection_changed_connection=keyframe_tree_->get_selection()->signal_changed().connect(
+                       sigc::mem_fun(*this,&KeyframeActionManager::queue_refresh)
+               );
+       }
+}
+
+void
+KeyframeActionManager::set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x)
+{
+       time_changed_connection.disconnect();
+       canvas_interface_=x;
+       if(canvas_interface_)
+       {
+               canvas_interface_->signal_time_changed().connect(
+                       sigc::mem_fun(*this,&KeyframeActionManager::queue_refresh)
+               );
+       }
+}
+
+void
+KeyframeActionManager::clear()
+{
+       if(ui_manager_)
+       {
+               // Clear out old stuff
+               if(popup_id_!=no_prev_popup)
+               {
+                       get_ui_manager()->remove_ui(popup_id_);
+                       popup_id_=no_prev_popup;
+#ifdef ONE_ACTION_GROUP
+                       while(!action_group_->get_actions().empty())action_group_->remove(*action_group_->get_actions().begin());
+#else
+                       get_ui_manager()->remove_action_group(action_group_);
+                       action_group_=Gtk::ActionGroup::create();
+#endif
+               }
+       }
+}
+
+void
+KeyframeActionManager::queue_refresh()
+{
+       if(queued)
+               return;
+       
+       //queue_refresh_connection.disconnect();
+       queue_refresh_connection=Glib::signal_idle().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&KeyframeActionManager::refresh),
+                       false
+               )
+       );
+       
+       queued=true;
+}
+
+void
+KeyframeActionManager::on_keyframe_properties()
+{
+       signal_show_keyframe_properties_();
+}
+
+void
+KeyframeActionManager::on_add_keyframe()
+{
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_add"));
+
+       if(!action)
+               return;
+       
+       action->set_param("canvas",canvas_interface_->get_canvas());
+       action->set_param("canvas_interface",canvas_interface_);
+       action->set_param("keyframe",Keyframe(canvas_interface_->get_time()));
+
+       canvas_interface_->get_instance()->perform_action(action);
+}
+
+void
+KeyframeActionManager::refresh()
+{
+       KeyframeTreeStore::Model model;
+       
+       if(queued)
+       {
+               queued=false;
+               //queue_refresh_connection.disconnect();
+       }
+
+
+       clear();
+       
+       // Make sure we are ready
+       if(!ui_manager_ || !keyframe_tree_ || !canvas_interface_)
+       {
+               sinfg::error("KeyframeActionManager::refresh(): Not ready!");
+               return;
+       }
+               
+       String ui_info;
+       
+       {
+               sinfgapp::Action::ParamList param_list;
+               param_list.add("time",get_canvas_interface()->get_time());
+               param_list.add("canvas",get_canvas_interface()->get_canvas());
+               param_list.add("canvas_interface",get_canvas_interface());
+               if(keyframe_tree_->get_selection()->count_selected_rows()==1)
+               {
+                       Keyframe keyframe((*keyframe_tree_->get_selection()->get_selected())[model.keyframe]);
+                       param_list.add("keyframe",keyframe);
+               }
+
+               handle<studio::Instance>::cast_static(
+                       get_canvas_interface()->get_instance()
+               )->add_actions_to_group(
+                       action_group_,
+                       ui_info,
+                       param_list,
+                       sinfgapp::Action::CATEGORY_KEYFRAME
+               );
+       }
+       if(action_group_->get_action("action-keyframe_add"))
+       {
+               action_group_->remove(action_group_->get_action("action-keyframe_add"));
+       }
+       
+               action_group_->add(Gtk::Action::create(
+                       "action-keyframe_add",
+                       Gtk::StockID("gtk-add"),
+                       _("Add new Keyframe"),_("Add new Keyframe")
+               ),
+                       sigc::mem_fun(*this,&KeyframeActionManager::on_add_keyframe)
+               );
+       
+       try
+       {
+               canvas_interface_->get_canvas()->keyframe_list().find(canvas_interface_->get_time());
+               action_group_->get_action("action-keyframe_add")->set_sensitive(false);
+               if(action_group_->get_action("action-keyframe_duplicate"))
+                       action_group_->get_action("action-keyframe_duplicate")->set_sensitive(false);
+       }
+       catch(...)
+       {
+       }
+       
+       {
+               Glib::RefPtr<Gtk::Action> action(Gtk::Action::create("keyframe-properties", Gtk::StockID("gtk-properties"), _("Keyframe Properties")));
+               action_group_->add(action,sigc::mem_fun(*this,&KeyframeActionManager::on_keyframe_properties));
+               if(keyframe_tree_->get_selection()->count_selected_rows()==0)
+                       action->set_sensitive(false);
+       }
+
+       ui_info="<ui><menubar action='menu-main'><menu action='menu-keyframe'>"+ui_info+"</menu></menubar></ui>";
+       popup_id_=get_ui_manager()->add_ui_from_string(ui_info);        
+#ifdef ONE_ACTION_GROUP
+#else
+       get_ui_manager()->insert_action_group(action_group_);
+#endif
+}
diff --git a/synfig-studio/trunk/src/gtkmm/keyframeactionmanager.h b/synfig-studio/trunk/src/gtkmm/keyframeactionmanager.h
new file mode 100644 (file)
index 0000000..f3f072c
--- /dev/null
@@ -0,0 +1,90 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeactionmanager.h
+**     \brief Template Header
+**
+**     $Id: keyframeactionmanager.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_KEYFRAME_ACTION_MANAGER_H
+#define __SINFG_KEYFRAME_ACTION_MANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/uimanager.h>
+#include <gtkmm/treeview.h>
+#include <sinfgapp/canvasinterface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class KeyframeTree;
+
+class KeyframeActionManager
+{
+       sigc::signal<void> signal_show_keyframe_properties_;
+               
+       Glib::RefPtr<Gtk::UIManager> ui_manager_;
+       //Glib::RefPtr<Gtk::TreeSelection> tree_selection_;
+       KeyframeTree* keyframe_tree_;
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gtk::ActionGroup>  action_group_;
+       Gtk::UIManager::ui_merge_id     popup_id_;
+       
+       
+       sigc::connection selection_changed_connection;
+
+       bool queued;
+       sigc::connection queue_refresh_connection;
+       sigc::connection time_changed_connection;
+       
+       void on_add_keyframe();
+       void on_keyframe_properties();
+       
+public:
+       sigc::signal<void>& signal_show_keyframe_properties() { return signal_show_keyframe_properties_; }
+
+       void queue_refresh();
+
+       KeyframeActionManager();
+       ~KeyframeActionManager();
+
+       void set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x);
+       Glib::RefPtr<Gtk::UIManager> get_ui_manager()const { return ui_manager_; }
+
+       void set_keyframe_tree(KeyframeTree* x);
+       KeyframeTree* get_keyframe_tree()const { return keyframe_tree_; }
+
+       void set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x);
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       void refresh();
+       void clear();
+}; // END of KeyframeActionManager
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/keyframetree.cpp b/synfig-studio/trunk/src/gtkmm/keyframetree.cpp
new file mode 100644 (file)
index 0000000..6d6222b
--- /dev/null
@@ -0,0 +1,299 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframetree.cpp
+**     \brief Template File
+**
+**     $Id: keyframetree.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframetree.h"
+#include "cellrenderer_time.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+KeyframeTree::KeyframeTree()
+{
+       const KeyframeTreeStore::Model model;
+       
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time")) );
+
+               cell_renderer_time = Gtk::manage( new CellRenderer_Time() );
+               column->pack_start(*cell_renderer_time,true);
+               column->add_attribute(cell_renderer_time->property_time(), model.time);
+               
+               cell_renderer_time->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time));
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               //column->set_sort_column_id(COLUMNID_TIME);
+               column->set_sort_column_id(model.time);
+
+               append_column(*column);
+               //column->clicked();
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Length")) );
+
+               cell_renderer_time_delta = Gtk::manage( new CellRenderer_Time() );
+               column->pack_start(*cell_renderer_time_delta,true);
+               column->add_attribute(cell_renderer_time_delta->property_time(), model.time_delta);
+               
+               cell_renderer_time_delta->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_time_delta));
+
+               column->set_reorderable();
+               column->set_resizable();
+
+               column->set_sort_column_id(model.time_delta);
+
+               column->set_clickable(false);
+
+               append_column(*column);
+               //column->clicked();
+       }
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Jump")) );
+
+               Gtk::CellRendererText* cell_renderer_jump=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_jump,true);
+               
+               cell_renderer_jump->property_text()="(JMP)";
+               cell_renderer_jump->property_foreground()="#003a7f";
+               
+               column->set_reorderable();
+               column->set_resizable();
+               
+               column->set_sort_column_id(COLUMNID_JUMP);
+
+               column->set_clickable(false);
+
+               append_column(*column);
+               //column->clicked();
+       }
+       //append_column_editable(_("Description"),model.description);
+       {
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Description")) );
+               
+               cell_renderer_description=Gtk::manage(new Gtk::CellRendererText());
+               column->pack_start(*cell_renderer_description,true);
+               column->add_attribute(cell_renderer_description->property_text(), model.description);
+               cell_renderer_description->signal_edited().connect(sigc::mem_fun(*this,&studio::KeyframeTree::on_edited_description));
+
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               //column->set_sort_column_id(COLUMNID_DESCRIPTION);
+               column->set_sort_column_id(model.description);
+
+               append_column(*column);
+       }
+
+       set_enable_search(true);
+       set_search_column(model.description);
+
+       // This makes things easier to read.
+       set_rules_hint();
+               
+       // Make us more sensitive to several events
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+}
+
+KeyframeTree::~KeyframeTree()
+{
+       sinfg::info("KeyframeTree::~KeyframeTree(): deleted");
+}
+
+void
+KeyframeTree::on_rend_desc_changed()
+{
+       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+       queue_draw();
+}
+
+void
+KeyframeTree::set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store)
+{
+       keyframe_tree_store_=keyframe_tree_store;
+       KeyframeTreeStore::Model model;
+       
+       if(true)
+       {
+               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(keyframe_tree_store_));
+               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+               sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::KeyframeTreeStore::time_sorter));
+               sorted_store->set_sort_column_id(model.time.index(), Gtk::SORT_ASCENDING);
+               Gtk::TreeView::set_model(sorted_store);
+       }
+       else
+               Gtk::TreeView::set_model(keyframe_tree_store);
+       
+       keyframe_tree_store_->canvas_interface()->signal_rend_desc_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::KeyframeTree::on_rend_desc_changed
+               )
+       );
+       cell_renderer_time->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+       cell_renderer_time_delta->property_fps().set_value(keyframe_tree_store_->canvas_interface()->get_canvas()->rend_desc().get_frame_rate());
+}
+
+void
+KeyframeTree::set_editable(bool x)
+{
+       editable_=x;
+       
+       if(editable_)
+       {
+               cell_renderer_time->property_editable()=true;
+               cell_renderer_time_delta->property_editable()=true;
+               cell_renderer_description->property_editable()=true;
+       }
+       else
+       {
+               cell_renderer_time->property_editable()=false;
+               cell_renderer_time_delta->property_editable()=false;
+               cell_renderer_description->property_editable()=false;
+       }
+}
+
+void
+KeyframeTree::on_edited_time(const Glib::ustring&path_string,sinfg::Time time)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+       
+       sinfg::Keyframe keyframe(row[model.keyframe]);
+       if(time!=keyframe.get_time())
+       {
+               row[model.time]=time;
+               //keyframe.set_time(time);
+               //signal_edited_time()(keyframe,time);
+               //signal_edited()(keyframe);
+       }
+}
+
+void
+KeyframeTree::on_edited_time_delta(const Glib::ustring&path_string,sinfg::Time time)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+       
+       if(row)row[model.time_delta]=time;
+}
+
+void
+KeyframeTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+       
+       const sinfg::String description(desc);
+       sinfg::Keyframe keyframe(row[model.keyframe]);
+       if(description!=keyframe.get_description())
+       {
+               row[model.description]=desc;
+               keyframe.set_description(description);
+               signal_edited_description()(keyframe,description);
+               signal_edited()(keyframe);
+       }
+}
+
+bool
+KeyframeTree::on_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+                       //tree_to_widget_coords (,, wx, wy);
+                       if(!get_path_at_pos(
+                               wx,wy,  // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+                       
+                       signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+                       }
+               }
+               break;
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+                       
+                       {
+                               keyframe_tree_store_->canvas_interface()->set_time(row[model.time]);
+                               return true;
+                       }
+               }
+               break;
+               
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/keyframetree.h b/synfig-studio/trunk/src/gtkmm/keyframetree.h
new file mode 100644 (file)
index 0000000..24c8f39
--- /dev/null
@@ -0,0 +1,148 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframetree.h
+**     \brief Template Header
+**
+**     $Id: keyframetree.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_KEYFRAMETREE_H
+#define __SINFG_STUDIO_KEYFRAMETREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "keyframetreestore.h"
+#include <sinfg/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CellRenderer_Time;
+
+class KeyframeTree : public Gtk::TreeView
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       enum ColumnID
+       {
+               COLUMNID_TIME,
+               COLUMNID_DESCRIPTION,
+               COLUMNID_JUMP,
+               
+               COLUMNID_END                    //!< \internal
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       KeyframeTreeStore::Model model;
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_;
+
+       CellRenderer_Time *cell_renderer_time;
+
+       CellRenderer_Time *cell_renderer_time_delta;
+
+       Gtk::CellRendererText *cell_renderer_description;
+
+       sigc::signal<void,sinfg::Keyframe> signal_edited_;
+
+       sigc::signal<void,sinfg::Keyframe,sinfg::Time> signal_edited_time_;
+
+       sigc::signal<void,sinfg::Keyframe,sinfg::String> signal_edited_description_;
+
+       sigc::signal<void, int, Gtk::TreeRow, ColumnID> signal_user_click_;
+
+       bool editable_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_time(const Glib::ustring&path_string,sinfg::Time time);
+
+       void on_edited_time_delta(const Glib::ustring&path_string,sinfg::Time time);
+
+       void on_edited_description(const Glib::ustring&path_string,const Glib::ustring &description);
+
+       bool on_event(GdkEvent *event);
+
+       void on_rend_desc_changed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       KeyframeTree();
+       ~KeyframeTree();
+
+       void set_model(Glib::RefPtr<KeyframeTreeStore> keyframe_tree_store_);
+
+       void set_editable(bool x=true);
+       
+       bool get_editable()const { return editable_; }
+
+       //! Signal called when a keyframe has been edited in any way
+       sigc::signal<void,sinfg::Keyframe>& signal_edited() { return signal_edited_; }
+       
+       //! Signal called when a time has been edited.
+       sigc::signal<void,sinfg::Keyframe,sinfg::Time>& signal_edited_time() { return signal_edited_time_; }
+
+       //! Signal called when a description has been edited.
+       sigc::signal<void,sinfg::Keyframe,sinfg::String>& signal_edited_description() { return signal_edited_description_; }
+
+       sigc::signal<void,int, Gtk::TreeRow, ColumnID>& signal_user_click() { return signal_user_click_; }
+}; // END of KeyframeTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/keyframetreestore.cpp b/synfig-studio/trunk/src/gtkmm/keyframetreestore.cpp
new file mode 100644 (file)
index 0000000..346aa9f
--- /dev/null
@@ -0,0 +1,945 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframetreestore.cpp
+**     \brief Template File
+**
+**     $Id: keyframetreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframetreestore.h"
+#include <sinfg/valuenode.h>
+#include "iconcontroler.h"
+#include <sinfg/valuenode_timedswap.h>
+#include <gtkmm/button.h>
+#include <gtkmm/treerowreference.h>
+#include <sinfg/canvas.h>
+#include <sinfg/keyframe.h>
+#include <time.h>
+#include <cstdlib>
+#include <ETL/smart_ptr>
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+#include "onemoment.h"
+#include <sinfg/exception.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+KeyframeTreeStore_Class KeyframeTreeStore::keyframe_tree_store_class_;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+struct _keyframe_iterator
+{
+       sinfg::KeyframeList::iterator iter;
+       int ref_count;
+       int index;
+};
+
+/*
+Gtk::TreeModel::iterator keyframe_iter_2_model_iter(sinfg::KeyframeList::iterator iter,int index)
+{
+       Gtk::TreeModel::iterator ret;
+       
+       _keyframe_iterator*& data(static_cast<_keyframe_iterator*&>(ret->gobj()->user_data));
+       data=new _keyframe_iterator();
+       data->ref_count=1;
+       data->iter=iter;
+       data->index=index;
+       
+       return ret;
+}
+*/
+
+sinfg::KeyframeList::iterator model_iter_2_keyframe_iter(Gtk::TreeModel::iterator iter)
+{
+       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+       if(!data)
+               throw std::runtime_error("bad data");
+       return data->iter;
+}
+
+int get_index_from_model_iter(Gtk::TreeModel::iterator iter)
+{
+       _keyframe_iterator* data(static_cast<_keyframe_iterator*>(iter->gobj()->user_data));
+       if(!data)
+               throw std::runtime_error("bad data");
+       return data->index;
+}
+
+
+/*
+#ifndef TreeRowReferenceHack
+class TreeRowReferenceHack
+{
+       GtkTreeRowReference *gobject_;
+public:
+       TreeRowReferenceHack():
+               gobject_(0)
+       {
+       }
+       
+       TreeRowReferenceHack(const Glib::RefPtr<Gtk::TreeModel>& model, const Gtk::TreeModel::Path& path):
+               gobject_ ( gtk_tree_row_reference_new(model->gobj(), const_cast<GtkTreePath*>(path.gobj())) )
+       {
+       }
+
+       TreeRowReferenceHack(const TreeRowReferenceHack &x):
+               gobject_ ( x.gobject_?gtk_tree_row_reference_copy(x.gobject_):0 )
+       {
+               
+       }
+
+       void swap(TreeRowReferenceHack & other)
+       {
+               GtkTreeRowReference *const temp = gobject_;
+               gobject_ = other.gobject_;
+               other.gobject_ = temp;
+       }
+
+       const TreeRowReferenceHack &
+       operator=(const TreeRowReferenceHack &rhs)
+       {
+               TreeRowReferenceHack temp (rhs);
+               swap(temp);
+               return *this;
+       }
+       
+       ~TreeRowReferenceHack()
+       {
+               if(gobject_)
+                       gtk_tree_row_reference_free(gobject_);
+       }
+       
+       Gtk::TreeModel::Path get_path() { return Gtk::TreeModel::Path(gtk_tree_row_reference_get_path(gobject_),false); }
+       GtkTreeRowReference *gobj() { return gobject_; }
+};
+#endif
+*/
+
+/* === P R O C E D U R E S ================================================= */
+
+void clear_iterator(GtkTreeIter* iter)
+{
+       iter->stamp=0;
+       iter->user_data=iter->user_data2=iter->user_data3=0;
+}
+
+/* === M E T H O D S ======================================================= */
+
+const Glib::Class&
+KeyframeTreeStore_Class::init()
+{
+       if(!gtype_)
+       {
+               class_init_func_ = &KeyframeTreeStore_Class::class_init_function;
+               
+               const GTypeInfo derived_info =
+               {
+                       sizeof(GObjectClass),
+                       NULL,
+                       NULL,
+                       class_init_func_,
+                       NULL,
+                       NULL,
+                       sizeof(GObject),
+                       0,
+                       0,
+                       NULL
+               };
+               
+               gtype_ = g_type_register_static(G_TYPE_OBJECT, "KeyframeTreeStore", &derived_info, GTypeFlags(0));
+               Gtk::TreeModel::add_interface(get_type());
+       }
+       return *this;
+}
+
+void
+KeyframeTreeStore_Class::class_init_function(gpointer g_class, gpointer class_data)
+{
+       // ???
+}
+
+KeyframeTreeStore::KeyframeTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Glib::ObjectBase        ("KeyframeTreeStore"),
+       Glib::Object            (Glib::ConstructParams(keyframe_tree_store_class_.init(), (char*) 0)),
+       canvas_interface_       (canvas_interface_)
+{
+       reset_stamp();
+       //reset_path_table();
+
+       canvas_interface()->signal_keyframe_added().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::add_keyframe));
+       canvas_interface()->signal_keyframe_removed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::remove_keyframe));
+       canvas_interface()->signal_keyframe_changed().connect(sigc::mem_fun(*this,&studio::KeyframeTreeStore::change_keyframe));
+}
+
+KeyframeTreeStore::~KeyframeTreeStore()
+{
+       sinfg::info("KeyframeTreeStore::~KeyframeTreeStore(): Deleted");
+}
+
+Glib::RefPtr<KeyframeTreeStore>
+KeyframeTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_)
+{
+       KeyframeTreeStore *store(new KeyframeTreeStore(canvas_interface_));
+       Glib::RefPtr<KeyframeTreeStore> ret(store);
+       assert(ret);
+       return ret;
+}
+
+void
+KeyframeTreeStore::reset_stamp()
+{
+       stamp_=time(0)+reinterpret_cast<int>(this);
+}
+
+/*
+void
+KeyframeTreeStore::reset_path_table()
+{
+       Gtk::TreeModel::Children::iterator iter;
+       const Gtk::TreeModel::Children children(children());
+       path_table_.clear();    
+       for(iter = children.begin(); iter != children.end(); ++iter)
+       {
+               Gtk::TreeModel::Row row(*iter);
+               path_table_[(Keyframe)row[model.keyframe]]=TreeRowReferenceHack(Glib::RefPtr<KeyframeTreeStore>(this),Gtk::TreePath(row));
+       }
+}
+*/
+
+
+inline bool
+KeyframeTreeStore::iterator_sane(const GtkTreeIter* iter)const
+{
+       if(iter && iter->stamp==stamp_)
+               return true;
+       g_warning("KeyframeTreeStore::iterator_sane(): Bad iterator stamp");
+       return false;
+}
+
+inline bool
+KeyframeTreeStore::iterator_sane(const Gtk::TreeModel::iterator& iter)const
+{
+       return iterator_sane(iter->gobj());
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const GtkTreeIter* gtk_iter, const Glib::ustring &name)const
+{
+#if 0
+       if(!gtk_iter)
+       {
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is NULL (Root?)",name.c_str());
+               return;
+       }
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+       if(gtk_iter->stamp!=stamp_ || !iter)
+       {
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\" is INVALID",name.c_str());
+               return;
+       }
+
+       if((unsigned)iter->index>=canvas_interface()->get_canvas()->keyframe_list().size())
+               g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) has bad index(index:%d)",name.c_str(),gtk_iter,iter->index);
+
+       g_warning("KeyframeTreeStore::dump_iterator: \"%s\"(%p) ref:%d, index:%d, time:%s",name.c_str(),gtk_iter,iter->ref_count,iter->index,iter->iter->get_time().get_string().c_str());
+#endif
+}
+
+inline void
+KeyframeTreeStore::dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const
+{
+       dump_iterator(iter->gobj(),name);
+}
+
+int
+KeyframeTreeStore::time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+       
+       _keyframe_iterator *rhs_iter(static_cast<_keyframe_iterator*>(rhs->gobj()->user_data));
+       _keyframe_iterator *lhs_iter(static_cast<_keyframe_iterator*>(lhs->gobj()->user_data));
+       
+       Time diff(rhs_iter->iter->get_time()-lhs_iter->iter->get_time());
+       if(diff<0)
+               return -1;
+       if(diff>0)
+               return 1;
+       return 0;
+}
+
+void
+KeyframeTreeStore::set_value_impl(const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value)
+{
+       if(!iterator_sane(row))
+               return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(row.gobj()->user_data));
+       
+       try
+       {
+               if(column==model.time_delta.index())
+               {                       
+                       Glib::Value<sinfg::Time> x;
+                       g_value_init(x.gobj(),model.time.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       Time new_delta(x.get());
+                       if(new_delta<=Time::zero()+Time::epsilon())
+                       {
+                               // Bad value
+                               return;
+                       }
+                       
+                       Time old_delta((*row)[model.time_delta]);
+                       if(old_delta<=Time::zero()+Time::epsilon())
+                       {
+                               // Bad old delta
+                               return;
+                       }
+                       //Gtk::TreeModel::iterator row(row);
+                       //row++;
+                       //if(!row)return;
+                       
+                       Time change_delta(new_delta-old_delta);
+                       
+                       if(change_delta<=Time::zero()+Time::epsilon() &&change_delta>=Time::zero()-Time::epsilon())
+                       {
+                               // Not an error, just no change
+                               return;
+                       }
+                       
+                       // New Method
+                       {
+                               Keyframe keyframe((*row)[model.keyframe]);
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_set_delta"));
+       
+                               if(!action)return;
+                               
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("keyframe",keyframe);
+                               action->set_param("delta",change_delta);
+                               
+                               canvas_interface()->get_instance()->perform_action(action);
+                       }
+                       
+                       
+                       if(0)
+                       {       // Old Method The slowest method EVER!!!
+                               OneMoment one_moment;
+                               
+                               // Create the action group
+                               sinfgapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Adjust Time"));
+                               sinfgapp::PushMode push_mode(canvas_interface(), sinfgapp::MODE_NORMAL);
+                               
+                               Gtk::TreeModel::iterator iter(row);
+                               if(change_delta<0)
+                               {
+                                       //DEBUGPOINT();
+                                       KeyframeList keyframe_list(get_canvas()->keyframe_list());
+                                       sinfg::KeyframeList::iterator iter(keyframe_list.find((*row)[model.keyframe]));
+                                       //DEBUGPOINT();
+                                       for(;iter!=keyframe_list.end();++iter)
+                                       {
+                                       //DEBUGPOINT();
+                                               sinfg::Keyframe keyframe(*iter);
+
+                                               keyframe.set_time(keyframe.get_time()+change_delta);
+                       
+                                               sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_set"));
+                       
+                                               if(!action)return;
+                                               
+                                               action->set_param("canvas",canvas_interface()->get_canvas());
+                                               action->set_param("canvas_interface",canvas_interface());
+                                               action->set_param("keyframe",keyframe);
+                                               
+                                               canvas_interface()->get_instance()->perform_action(action);
+                                       }
+                               }
+                               else
+                               {
+                                       //DEBUGPOINT();
+                                       KeyframeList keyframe_list(get_canvas()->keyframe_list());
+                                       sinfg::KeyframeList::reverse_iterator end(keyframe_list.find((*row)[model.keyframe]));
+                                       sinfg::KeyframeList::reverse_iterator iter(keyframe_list.rbegin());
+                                       //end++;
+                                       //DEBUGPOINT();
+                                       for(;iter!=end;++iter)
+                                       {
+                                       //DEBUGPOINT();
+                                               sinfg::Keyframe keyframe(*iter);
+
+                                               keyframe.set_time(keyframe.get_time()+change_delta);
+                       
+                                               sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_set"));
+                       
+                                               if(!action)return;
+                                               
+                                               action->set_param("canvas",canvas_interface()->get_canvas());
+                                               action->set_param("canvas_interface",canvas_interface());
+                                               action->set_param("keyframe",keyframe);
+                                               
+                                               canvas_interface()->get_instance()->perform_action(action);
+                                       }
+                               }
+                       }
+                       
+                       return;
+               }
+               else
+               if(column==model.time.index())
+               {
+                       OneMoment one_moment;
+
+                       Glib::Value<sinfg::Time> x;
+                       g_value_init(x.gobj(),model.time.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       sinfg::Keyframe keyframe(*iter->iter);
+
+                       sinfg::info("KeyframeTreeStore::set_value_impl():old_time=%s",keyframe.get_time().get_string().c_str());
+                       keyframe.set_time(x.get());
+                       sinfg::info("KeyframeTreeStore::set_value_impl():new_time=%s",keyframe.get_time().get_string().c_str());
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_set"));
+                       
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("keyframe",keyframe);
+                       
+                       canvas_interface()->get_instance()->perform_action(action);
+               }
+               else if(column==model.description.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.description.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       sinfg::Keyframe keyframe(*iter->iter);
+                       keyframe.set_description(x.get());
+
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("keyframe_set"));
+                       
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("keyframe",keyframe);
+                       
+                       canvas_interface()->get_instance()->perform_action(action);
+               }
+               else if(column==model.keyframe.index())
+               {
+                       g_warning("KeyframeTreeStore::set_value_impl: This column is read-only");
+               }
+               else
+               {
+                       assert(0);
+               }
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
+
+Gtk::TreeModelFlags
+KeyframeTreeStore::get_flags_vfunc ()
+{
+       return Gtk::TREE_MODEL_LIST_ONLY;
+}
+
+int
+KeyframeTreeStore::get_n_columns_vfunc ()
+{
+       return model.size();
+}
+
+GType
+KeyframeTreeStore::get_column_type_vfunc (int index)
+{
+       return model.types()[index];
+}
+
+bool
+KeyframeTreeStore::iter_next_vfunc (const iterator& xiter, iterator& iter_next) const
+{
+       if(!iterator_sane(xiter)) return false;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(xiter.gobj()->user_data));
+
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+
+       _keyframe_iterator *next(new _keyframe_iterator());
+       iter_next.gobj()->user_data=static_cast<gpointer>(next);        
+       next->ref_count=1;
+       next->index=iter->index+1;
+       next->iter=iter->iter;
+       ++next->iter;
+
+       if(next->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+       
+       iter_next.gobj()->stamp=stamp_;         
+
+       return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_next_vfunc (GtkTreeIter* gtk_iter)
+{
+       if(!iterator_sane(gtk_iter)) return false;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+
+       // If we are already at the end, then we are very invalid
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               return false;
+       
+       ++(iter->iter);
+       
+       if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+       {
+               --(iter->iter);
+               return false;
+       }
+       (iter->index)++;
+       return true;
+}
+
+bool
+KeyframeTreeStore::iter_children_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent)
+{
+       dump_iterator(gtk_iter,"gtk_iter");
+       dump_iterator(parent,"parent");
+
+       if(!parent || !iterator_sane(parent))
+       {
+               clear_iterator(gtk_iter);
+               return false;
+       }
+       
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=0;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+       
+       gtk_iter->user_data=static_cast<gpointer>(iter);
+       gtk_iter->stamp=stamp_;         
+
+       return true;    
+}
+
+bool
+KeyframeTreeStore::iter_has_child_vfunc (const GtkTreeIter*parent)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+               return false;
+
+       return true;
+}
+
+int
+KeyframeTreeStore::iter_n_children_vfunc (const GtkTreeIter* parent)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+               return 0;
+       
+       return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+*/
+
+int
+KeyframeTreeStore::iter_n_root_children_vfunc () const
+{
+       return canvas_interface()->get_canvas()->keyframe_list().size();
+}
+
+bool
+KeyframeTreeStore::iter_nth_root_child_vfunc (int n, iterator& xiter)const
+{
+       if(canvas_interface()->get_canvas()->keyframe_list().size()==0)
+       {
+               return false;
+       }
+
+       if(n<0)
+       {
+               g_warning("KeyframeTreeStore::iter_nth_root_child_vfunc: Out of range (negative index)");
+               return false;
+       }
+       if(n && (unsigned)n>=canvas_interface()->get_canvas()->keyframe_list().size())
+       {
+               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: Out of range (large index)");
+               return false;
+       }
+
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=n;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+       while(n--)
+       {
+               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               {
+                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+                       delete iter;
+                       return false;
+               }
+               ++iter->iter;
+       }
+       xiter.gobj()->user_data=static_cast<gpointer>(iter);    
+       xiter.gobj()->stamp=stamp_;     
+       return true;
+}
+
+/*
+bool
+KeyframeTreeStore::iter_nth_child_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* parent, int n)
+{
+       dump_iterator(parent,"parent");
+
+       if(parent)
+       {
+               g_warning("KeyframeTreeStore::iter_nth_child_vfunc: I am a list");
+               clear_iterator(gtk_iter);
+               return false;
+       }
+
+
+       
+       _keyframe_iterator *iter(new _keyframe_iterator());
+       iter->ref_count=1;
+       iter->index=n;
+       iter->iter=canvas_interface()->get_canvas()->keyframe_list().begin();
+       while(n--)
+       {
+               if(iter->iter==canvas_interface()->get_canvas()->keyframe_list().end())
+               {
+                       g_warning("KeyframeTreeStore::iter_nth_child_vfunc: >>>BUG<<< in %s on line %d",__FILE__,__LINE__);
+                       delete iter;
+                       clear_iterator(gtk_iter);
+                       return false;
+               }
+               ++iter->iter;
+       }
+       
+       gtk_iter->user_data=static_cast<gpointer>(iter);
+       gtk_iter->stamp=stamp_;         
+       return true;
+}
+
+bool
+KeyframeTreeStore::iter_parent_vfunc (GtkTreeIter* gtk_iter, const GtkTreeIter* child)
+{
+       dump_iterator(child,"child");
+       iterator_sane(child);
+       clear_iterator(gtk_iter);
+       return false;
+}
+*/
+
+void
+KeyframeTreeStore::ref_node_vfunc (iterator& xiter)const
+{
+       GtkTreeIter* gtk_iter(xiter.gobj());
+       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+       iter->ref_count++;
+}
+
+void
+KeyframeTreeStore::unref_node_vfunc (iterator& xiter)const
+{
+       GtkTreeIter* gtk_iter(xiter.gobj());
+       if(!gtk_iter || !iterator_sane(gtk_iter)) return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+       iter->ref_count--;
+       if(!iter->ref_count)
+       {
+               delete iter;
+               
+               // Make this iterator invalid
+               gtk_iter->stamp=0;
+       }
+}
+
+Gtk::TreeModel::Path
+KeyframeTreeStore::get_path_vfunc (const TreeModel::iterator& gtk_iter)const
+{
+       Gtk::TreeModel::Path path;
+
+       // If this is the root node, then return
+       // a root path
+       if(!iterator_sane(gtk_iter))
+               return path;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+       
+       path.append_index(iter->index);
+
+       return path;
+}
+
+bool
+KeyframeTreeStore::get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter)const
+{
+       if(path.get_depth()>=1)
+               return iter_nth_root_child_vfunc(path.front(),iter);
+
+       // Error case
+       g_warning("KeyframeTreeStore::get_iter_vfunc(): Bad path \"%s\"",path.to_string().c_str());
+       //clear_iterator(iter);
+       return false;
+}
+
+bool
+KeyframeTreeStore::iter_is_valid (const iterator& iter) const
+{
+       return iterator_sane(iter);
+}
+
+void
+KeyframeTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& gtk_iter, int column, Glib::ValueBase& value)const
+{
+       dump_iterator(gtk_iter,"gtk_iter");
+       if(!iterator_sane(gtk_iter))
+               return;
+
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->gobj()->user_data));
+
+       switch(column)
+       {
+       case 0:         // Time
+       {
+               Glib::Value<sinfg::Time> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(iter->iter->get_time());
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       case 3:         // Time Delta
+       {
+               Glib::Value<sinfg::Time> x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               sinfg::Keyframe prev_keyframe(*iter->iter);
+               sinfg::Keyframe keyframe;
+               {
+                       KeyframeList::iterator tmp(iter->iter);
+                       tmp++;
+                       if(tmp==get_canvas()->keyframe_list().end())
+                       {
+                               x.set(Time(0));
+                               g_value_init(value.gobj(),x.value_type());
+                               g_value_copy(x.gobj(),value.gobj());
+                               return;
+                       }
+                       keyframe=*tmp;
+               }
+               
+               Time delta(0);
+               try {
+                       delta=keyframe.get_time()-prev_keyframe.get_time();
+               }catch(...) { }
+               x.set(delta);
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       case 1:         // Description
+       {
+               g_value_init(value.gobj(),G_TYPE_STRING);
+               g_value_set_string(value.gobj(),iter->iter->get_description().c_str());
+               return;
+       }
+       case 2:         // Keyframe
+       {
+               Glib::Value<sinfg::Keyframe> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(*iter->iter);
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+               return;
+       }
+       default:
+               break;
+       }
+}
+
+Gtk::TreeModel::Row
+KeyframeTreeStore::find_row(const sinfg::Keyframe &keyframe)
+{
+       Gtk::TreeModel::Row row(*(children().begin()));
+       dump_iterator(row,"find_row,begin");
+       const GtkTreeIter *gtk_iter(row.gobj());
+       if(!iterator_sane(gtk_iter))
+               throw std::runtime_error(_("Unable to find Keyframe in table"));
+               
+       _keyframe_iterator *iter(static_cast<_keyframe_iterator*>(gtk_iter->user_data));
+       
+       sinfg::KeyframeList &keyframe_list(canvas_interface()->get_canvas()->keyframe_list());
+       if(keyframe_list.empty())
+               throw std::runtime_error(_("There are no keyframes n this canvas"));
+
+       iter->index=0;
+               
+       for(iter->iter=keyframe_list.begin();iter->iter!=keyframe_list.end() && *iter->iter!=keyframe;++iter->iter)
+       {
+               iter->index++;
+       }
+       if(iter->iter==keyframe_list.end())
+               throw std::runtime_error(_("Unable to find Keyframe in table"));
+       return row;
+}
+
+void
+KeyframeTreeStore::add_keyframe(Keyframe keyframe)
+{
+       try
+       {
+               Gtk::TreeRow row(find_row(keyframe));
+               dump_iterator(row.gobj(),"add_keyframe,row");
+               Gtk::TreePath path(get_path(row));
+               
+               row_inserted(path,row);
+
+               old_keyframe_list=get_canvas()->keyframe_list();
+               //old_keyframe_list.add(keyframe);
+               //old_keyframe_list.sort();
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
+
+void
+KeyframeTreeStore::remove_keyframe(Keyframe keyframe)
+{
+       try
+       {
+               if(1)
+               {       
+                       Gtk::TreeRow row(find_row(keyframe));
+                       dump_iterator(row,"remove_keyframe,row");
+                       Gtk::TreePath path(get_path(row));
+                       row_deleted(path);
+
+                       old_keyframe_list.erase(keyframe);
+               }
+               else
+               {
+                       g_warning("KeyframeTreeStore::remove_keyframe: Keyframe not in table");
+               }
+       }
+       catch(std::exception x)
+       {
+               DEBUGPOINT();
+               g_warning(x.what());
+       }       
+}
+
+void
+KeyframeTreeStore::change_keyframe(Keyframe keyframe)
+{
+       try
+       {
+               Gtk::TreeRow row(find_row(keyframe));
+
+               unsigned int new_index(get_index_from_model_iter(row));
+               unsigned int old_index(0);
+               sinfg::KeyframeList::iterator iter;
+               for(old_index=0,iter=old_keyframe_list.begin();iter!=old_keyframe_list.end() && (UniqueID)*iter!=(UniqueID)keyframe;++iter,old_index++);
+               
+               if(iter!=old_keyframe_list.end() && new_index!=old_index)
+               {
+                       DEBUGPOINT();
+                       std::vector<int> new_order;
+                       for(unsigned int i=0;i<old_keyframe_list.size();i++)
+                       {
+                               new_order.push_back(i);
+                       }
+                       if(new_order.size()>new_index)
+                       {
+                               new_order.erase(new_order.begin()+new_index);
+                               new_order.insert(new_order.begin()+old_index,new_index);
+                               
+                               //new_order[old_index]=
+                               
+                               rows_reordered (Path(), iterator(), &new_order[0]);
+                       }
+                       old_keyframe_list=get_canvas()->keyframe_list();
+                               
+                       row=find_row(keyframe);
+               }
+
+               dump_iterator(row,"change_keyframe,row");
+               row_changed(get_path(row),row); 
+       }
+       catch(std::exception x)
+       {
+               DEBUGPOINT();
+               g_warning(x.what());
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/keyframetreestore.h b/synfig-studio/trunk/src/gtkmm/keyframetreestore.h
new file mode 100644 (file)
index 0000000..b0b9754
--- /dev/null
@@ -0,0 +1,221 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframetreestore.h
+**     \brief Template Header
+**
+**     $Id: keyframetreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_KEYFRAMETREESTORE_H
+#define __SINFG_STUDIO_KEYFRAMETREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/liststore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <sinfg/keyframe.h>
+#include <map>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+//class TreeRowReferenceHack;
+//#define TreeRowReferenceHack Gtk::TreeRowReference
+
+namespace studio {
+
+class KeyframeTreeStore_Class;
+       
+class KeyframeTreeStore :
+       public Glib::Object,
+       public Gtk::TreeModel,
+       public Gtk::TreeDragSource,
+       public Gtk::TreeDragDest
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<sinfg::Time> time;
+               Gtk::TreeModelColumn<Glib::ustring> description;
+               Gtk::TreeModelColumn<sinfg::Keyframe> keyframe;
+               Gtk::TreeModelColumn<sinfg::Time> time_delta;
+       
+               Model()
+               {
+                       add(time);
+                       add(description);
+                       add(keyframe);
+                       add(time_delta);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       //! Unique stamp for this TreeModel.
+       int stamp_;
+       
+       static KeyframeTreeStore_Class keyframe_tree_store_class_;
+
+       //std::map<sinfg::Keyframe,TreeRowReferenceHack> path_table_;
+
+       sinfg::KeyframeList old_keyframe_list;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       void add_keyframe(sinfg::Keyframe);
+
+       void remove_keyframe(sinfg::Keyframe);
+
+       void change_keyframe(sinfg::Keyframe);
+
+       static int sorter(const Gtk::TreeModel::iterator &,const Gtk::TreeModel::iterator &);
+
+       bool iterator_sane(const GtkTreeIter* iter)const;
+
+       bool iterator_sane(const Gtk::TreeModel::iterator& iter)const;
+
+       void dump_iterator(const GtkTreeIter* iter, const Glib::ustring &name)const;
+
+       void dump_iterator(const Gtk::TreeModel::iterator& iter, const Glib::ustring &name)const;
+
+       //! Resets the iterator stamp for this model.
+       /*!     This should be called whenever the class is
+       **      constructed     or when large numbers of
+       **      iterators become invalid. */
+       void reset_stamp();
+       
+       //void reset_path_table();
+
+       /*
+ -- ** -- V I R T U A L   F U N C T I O N S -----------------------------------
+       */
+
+protected:
+       
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual Gtk::TreeModelFlags  get_flags_vfunc ();
+       virtual int  get_n_columns_vfunc ();
+       virtual GType  get_column_type_vfunc (int index);
+       virtual bool iter_next_vfunc (const iterator& iter, iterator& iter_next) const;
+       virtual bool  get_iter_vfunc (const Gtk::TreeModel::Path& path, iterator& iter_next)const;
+       virtual bool  iter_nth_root_child_vfunc (int n, iterator& iter)const;
+       virtual Gtk::TreeModel::Path  get_path_vfunc (const iterator& iter)const;
+       virtual void  ref_node_vfunc (iterator& iter)const;
+       virtual void  unref_node_vfunc (iterator& iter)const;
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       virtual bool    iter_is_valid (const iterator& iter) const;
+       virtual int     iter_n_root_children_vfunc () const;
+
+       //virtual bool  iter_nth_child_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent, int n);
+       //virtual bool  iter_children_vfunc (GtkTreeIter* iter, const GtkTreeIter* parent);
+       //virtual bool  iter_has_child_vfunc (const GtkTreeIter* iter);
+       //virtual int  iter_n_children_vfunc (const GtkTreeIter* iter);
+       //virtual bool  iter_parent_vfunc (GtkTreeIter* iter, const GtkTreeIter* child);
+
+       /*
+       virtual bool  get_sort_column_id_vfunc (int* sort_column_id, Gtk::SortType* order);
+       virtual void  set_sort_column_id_vfunc (int sort_column_id, Gtk::SortType order);
+       virtual void  set_sort_func_vfunc (int sort_column_id, GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+       virtual void  set_default_sort_func_vfunc (GtkTreeIterCompareFunc func, void* data, GtkDestroyNotify destroy);
+       virtual bool  has_default_sort_func_vfunc ();
+       */
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       KeyframeTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+       ~KeyframeTreeStore();
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const sinfgapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+       
+       sinfg::Canvas::Handle get_canvas() { return canvas_interface()->get_canvas(); }
+       sinfg::Canvas::Handle get_canvas()const { return canvas_interface()->get_canvas(); }
+
+       Gtk::TreeModel::Row find_row(const sinfg::Keyframe &keyframe);
+
+       /*
+ -- ** -- S T A T I C  M E T H O D S ------------------------------------------
+       */
+
+public:
+
+       static Glib::RefPtr<KeyframeTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+
+       static int time_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+}; // END of class KeyframeTreeStore
+
+//! \internal
+class KeyframeTreeStore_Class : public Glib::Class
+{
+public:
+       struct KeyframeTreeStoreClass
+       {
+               GObjectClass parent_class;
+       };
+       
+       friend class KeyframeTreeStore;
+       
+       const Glib::Class& init();
+       
+       static void class_init_function(gpointer g_blass, gpointer class_data);
+}; // END of CustomTreeStore_Class
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/keymapsettings.cpp b/synfig-studio/trunk/src/gtkmm/keymapsettings.cpp
new file mode 100644 (file)
index 0000000..0260580
--- /dev/null
@@ -0,0 +1,110 @@
+/* === S I N F G =========================================================== */
+/*!    \file keymapsettings.cpp
+**     \brief Contains Info for Key Map settings
+**
+**     $Id: keymapsettings.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keymapsettings.h"
+
+#include <gtkmm/accelkey.h>
+#include <gtkmm/accelmap.h>
+#include <gtk/gtkaccelmap.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+//using namespace sinfg;
+using namespace studio;
+
+using namespace Gtk;
+//using namespace Gtk::Menu_Helpers;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+// KeyMapSettings Definitions
+KeyMapSettings::KeyMapSettings()
+{
+}
+
+KeyMapSettings::~KeyMapSettings()
+{
+}
+
+bool KeyMapSettings::set_key(const char *path, guint key, Gdk::ModifierType mod, bool replace)
+{
+       if(gtk_accel_map_lookup_entry(path,NULL))
+       {
+               return AccelMap::change_entry(path,key,mod,replace);
+       }else
+       {
+               AccelMap::add_entry(path,key,mod);
+               return true;
+       }
+}
+
+bool KeyMapSettings::get_key(const char *path, AccelKey *key)
+{
+       GtkAccelKey     ac;
+       if(gtk_accel_map_lookup_entry(path,&ac))
+       {
+               *key = AccelKey(ac.accel_key,(Gdk::ModifierType)ac.accel_mods,string(path));
+               return true;
+       }
+       
+       return false;
+}
+
+bool KeyMapSettings::load(const char *filename)
+{
+       string n(filename);
+       n += ".skm";
+       
+       AccelMap::load(filename);
+       
+       return true;    
+}
+
+bool KeyMapSettings::save(const char *filename)
+{
+       string n(filename);
+       n += ".skm";
+       
+       AccelMap::save(filename);
+       
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/keymapsettings.h b/synfig-studio/trunk/src/gtkmm/keymapsettings.h
new file mode 100644 (file)
index 0000000..5dba3fb
--- /dev/null
@@ -0,0 +1,82 @@
+/* === S I N F G =========================================================== */
+/*!    \file keymapsettings.h
+**     \brief Defines the structures for managing key map settings
+**
+**     $Id: keymapsettings.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_KEYMAPSETTINGS_H
+#define __SINFG_KEYMAPSETTINGS_H
+
+/* === H E A D E R S ======================================================= */
+#include <gtkmm/dialog.h>
+
+#include <set>
+#include <map>
+#include <string>
+
+#include <gtkmm/accelkey.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+//a dialog for viewing and setting options, though it can also be used just as is
+class KeyMapSettings : public Gtk::Dialog
+{
+       struct AcKeyInfo
+       {
+               guint                           key;
+               Gdk::ModifierType       mod;
+               
+               bool                            on;
+               
+               AcKeyInfo(guint k = 0, Gdk::ModifierType m = Gdk::ModifierType())
+               :key(k),mod(m) {}
+       };
+       
+       //std::map<const char *,AcKeyInfo>      pathmap; //uses string info from paths set
+       //std::set<std::string>                         accelpaths;
+       
+       bool unsaved; //Assume as such...
+               
+public:
+
+       KeyMapSettings();
+       ~KeyMapSettings();
+
+       //void add_path(const char *path);
+       
+       bool set_key(const char *path, guint key, Gdk::ModifierType mod, bool replace = true);
+       bool get_key(const char *path, Gtk::AccelKey *key);
+
+       // These files must be sent a filename without extension (so the key map can be obtained)
+       bool load(const char *filename);
+       bool save(const char *filename);
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layeractionmanager.cpp b/synfig-studio/trunk/src/gtkmm/layeractionmanager.cpp
new file mode 100644 (file)
index 0000000..5f1c5da
--- /dev/null
@@ -0,0 +1,464 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: layeractionmanager.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layeractionmanager.h"
+#include "layertree.h"
+#include <sinfgapp/action_param.h>
+#include "instance.h"
+#include <sinfgapp/selectionmanager.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+static const guint no_prev_popup((guint)-1);
+
+/* === M A C R O S ========================================================= */
+
+//#define ONE_ACTION_GROUP 1
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerActionManager::LayerActionManager():
+       action_group_(Gtk::ActionGroup::create()),
+       action_group_copy_paste(Gtk::ActionGroup::create()),
+       popup_id_(no_prev_popup),
+       queued(false)
+{
+       action_cut_=Gtk::Action::create(
+               "cut",
+               Gtk::StockID("gtk-cut")
+       );
+       action_cut_->signal_activate().connect(
+               sigc::mem_fun(
+                       *this,
+                       &LayerActionManager::cut
+               )
+       );
+       action_copy_=Gtk::Action::create(
+               "copy",
+               Gtk::StockID("gtk-copy")
+       );
+       action_copy_->signal_activate().connect(
+               sigc::mem_fun(
+                       *this,
+                       &LayerActionManager::copy
+               )
+       );
+       action_paste_=Gtk::Action::create(
+               "paste",
+               Gtk::StockID("gtk-paste")
+       );
+       action_paste_->signal_activate().connect(
+               sigc::mem_fun(
+                       *this,
+                       &LayerActionManager::paste
+               )
+       );
+       
+       
+       action_amount_inc_=Gtk::Action::create(
+               "amount-inc",
+               Gtk::StockID("gtk-add"),
+               _("Increase Amount"),_("Increase Amount")
+       );
+       action_amount_inc_->signal_activate().connect(
+               sigc::mem_fun(
+                       *this,
+                       &LayerActionManager::amount_inc
+               )
+       );
+
+       action_amount_dec_=Gtk::Action::create(
+               "amount-dec",
+               Gtk::StockID("gtk-remove"),
+               _("Decrease Amount"),_("Decrease Amount")
+       );
+       action_amount_dec_->signal_activate().connect(
+               sigc::mem_fun(
+                       *this,
+                       &LayerActionManager::amount_dec
+               )
+       );
+
+       action_amount_=Gtk::Action::create(
+               "amount",
+               Gtk::StockID("gtk-index"),
+               _("Amount"),_("Amount")
+       );
+
+
+}
+
+LayerActionManager::~LayerActionManager()
+{
+}
+
+void
+LayerActionManager::set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x)
+{
+       clear();
+
+#ifdef ONE_ACTION_GROUP
+       if(ui_manager_) get_ui_manager()->remove_action_group(action_group_);
+       ui_manager_=x;
+       if(ui_manager_) get_ui_manager()->insert_action_group(action_group_);
+#else
+       ui_manager_=x;
+#endif
+}
+
+void
+LayerActionManager::set_layer_tree(LayerTree* x)
+{
+       selection_changed_connection.disconnect();
+       layer_tree_=x;
+       if(layer_tree_)
+       {
+               selection_changed_connection=layer_tree_->get_selection()->signal_changed().connect(
+                       sigc::mem_fun(*this,&LayerActionManager::queue_refresh)
+               );
+       }
+}
+
+void
+LayerActionManager::set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x)
+{
+       canvas_interface_=x;
+}
+
+void
+LayerActionManager::clear()
+{
+       if(ui_manager_)
+       {
+               // Clear out old stuff
+               if(popup_id_!=no_prev_popup)
+               {
+                       get_ui_manager()->remove_ui(popup_id_);
+                       if(action_group_)get_ui_manager()->ensure_update();
+                       popup_id_=no_prev_popup;
+                       if(action_group_)while(!action_group_->get_actions().empty())action_group_->remove(*action_group_->get_actions().begin());
+#ifdef ONE_ACTION_GROUP
+#else
+                       if(action_group_)get_ui_manager()->remove_action_group(action_group_);
+                       action_group_=Gtk::ActionGroup::create();
+#endif
+               }
+       }
+
+       while(!update_connection_list.empty())
+       {
+               update_connection_list.front().disconnect();
+               update_connection_list.pop_front();
+       }
+}
+
+void
+LayerActionManager::queue_refresh()
+{
+       if(queued)
+               return;
+               
+       //queue_refresh_connection.disconnect();
+       queue_refresh_connection=Glib::signal_idle().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerActionManager::refresh),
+                       false
+               )
+       );
+       
+       queued=true;
+}
+
+void
+LayerActionManager::refresh()
+{
+       if(queued)
+       {
+               queued=false;
+               //queue_refresh_connection.disconnect();
+       }
+
+
+       clear();
+       
+       // Make sure we are ready
+       if(!ui_manager_ || !layer_tree_ || !canvas_interface_)
+       {
+               sinfg::error("LayerActionManager::refresh(): Not ready!");
+               return;
+       }
+       
+       
+       String ui_info;
+
+       action_paste_->set_sensitive(!clipboard_.empty());
+       action_group_->add(action_paste_);
+       
+       if(layer_tree_->get_selection()->count_selected_rows()!=0)
+       {
+               bool multiple_selected(layer_tree_->get_selection()->count_selected_rows()>1);
+               Layer::Handle layer(layer_tree_->get_selected_layer());
+               
+               {
+                       bool canvas_set(false);
+                       sinfgapp::Action::ParamList param_list;
+                       param_list.add("time",get_canvas_interface()->get_time());
+                       param_list.add("canvas_interface",get_canvas_interface());
+                       {
+                               sinfgapp::SelectionManager::LayerList layer_list(layer_tree_->get_selected_layers());
+                               sinfgapp::SelectionManager::LayerList::iterator iter;
+                               action_copy_->set_sensitive(!layer_list.empty());
+                               action_cut_->set_sensitive(!layer_list.empty());
+                               action_group_->add(action_copy_);
+                               action_group_->add(action_cut_);
+
+                               action_amount_inc_->set_sensitive(!layer_list.empty());
+                               action_amount_dec_->set_sensitive(!layer_list.empty());
+                               action_amount_->set_sensitive(!layer_list.empty());
+                               action_group_->add(action_amount_inc_);
+                               action_group_->add(action_amount_dec_);
+                               action_group_->add(action_amount_);
+                               
+                               for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                               {
+                                       update_connection_list.push_back(
+                                               (*iter)->signal_changed().connect(
+                                                       sigc::mem_fun(*this, &LayerActionManager::queue_refresh)
+                                               )
+                                       );
+                                       
+                                       if(!canvas_set)
+                                       {
+                                               param_list.add("canvas",Canvas::Handle((*iter)->get_canvas()));
+                                               canvas_set=true;
+                                               update_connection_list.push_back(
+                                                       (*iter)->get_canvas()->signal_changed().connect(
+                                                               sigc::mem_fun(*this, &LayerActionManager::queue_refresh)
+                                                       )
+                                               );
+                                       }
+                                       param_list.add("layer",Layer::Handle(*iter));
+                               }
+                       }
+                       
+                       if(!multiple_selected && layer->get_name()=="PasteCanvas")
+                       {
+                               action_group_->add(Gtk::Action::create(
+                                       "select-all-child-layers",
+                                       _("Select All Child Layers")
+                               ),
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *layer_tree_,
+                                                       &studio::LayerTree::select_all_children_layers
+                                               ),
+                                               Layer::LooseHandle(layer)
+                                       )
+                               );
+                               ui_info+="<menuitem action='select-all-child-layers'/>";
+                       }
+                       handle<studio::Instance>::cast_static(get_canvas_interface()->get_instance())->
+                               add_actions_to_group(action_group_, ui_info,   param_list, sinfgapp::Action::CATEGORY_LAYER);
+               }
+       }
+       
+       ui_info="<ui><menubar action='menu-main'><menu action='menu-layer'>"+ui_info+"<separator/><menuitem action='cut' /><menuitem action='copy' /><menuitem action='paste' /><separator/></menu></menubar></ui>";
+       popup_id_=get_ui_manager()->add_ui_from_string(ui_info);        
+#ifdef ONE_ACTION_GROUP
+#else
+       get_ui_manager()->insert_action_group(action_group_);
+#endif
+       DEBUGPOINT();
+}
+
+void
+LayerActionManager::cut()
+{
+       copy();
+       if(action_group_->get_action("action-layer_remove"))
+               action_group_->get_action("action-layer_remove")->activate();
+}
+
+void
+LayerActionManager::copy()
+{
+       sinfgapp::SelectionManager::LayerList layer_list(layer_tree_->get_selected_layers());
+       clipboard_.clear();
+       sinfg::GUID guid;
+       
+       while(!layer_list.empty())
+       {
+               clipboard_.push_back(layer_list.front()->clone(guid));
+               layer_list.pop_front();
+       }
+
+       action_paste_->set_sensitive(!clipboard_.empty());
+       
+       //queue_refresh();
+}
+
+void
+LayerActionManager::paste()
+{
+       sinfg::GUID guid;
+
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Paste"));
+
+       Canvas::Handle canvas(get_canvas_interface()->get_canvas());
+       int depth(0);
+       
+       // we are temporarily using the layer to hold something
+       Layer::Handle layer(layer_tree_->get_selected_layer());
+       if(layer)
+       {
+               depth=layer->get_depth();
+               canvas=layer->get_canvas();
+       }
+       
+       sinfgapp::SelectionManager::LayerList layer_selection;
+       
+       for(std::list<sinfg::Layer::Handle>::iterator iter=clipboard_.begin();iter!=clipboard_.end();++iter)
+       {
+               layer=(*iter)->clone(guid);
+               layer_selection.push_back(layer);
+               sinfgapp::Action::Handle        action(sinfgapp::Action::create("layer_add"));
+       
+               assert(action);
+               if(!action)
+                       return;
+               
+               action->set_param("canvas",canvas);
+               action->set_param("canvas_interface",etl::loose_handle<sinfgapp::CanvasInterface>(get_canvas_interface()));
+               action->set_param("new",layer);
+               
+               if(!action->is_ready())
+               {
+                       return;
+               }
+               
+               if(!get_instance()->perform_action(action))
+               {
+                       return;
+               }
+       
+               sinfg::info("DEPTH=%d",depth);
+               // Action to move the layer (if necessary)
+               if(depth>0)
+               {
+                       sinfgapp::Action::Handle        action(sinfgapp::Action::create("layer_move"));
+               
+                       assert(action);
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas);
+                       action->set_param("canvas_interface",etl::loose_handle<sinfgapp::CanvasInterface>(get_canvas_interface()));
+                       action->set_param("layer",layer);
+                       action->set_param("new_index",depth);
+                       
+                       if(!action->is_ready())
+                       {
+                               //get_ui_interface()->error(_("Move Action Not Ready"));                        
+                               //return 0;
+                               return;
+                       }
+                       
+                       if(!get_instance()->perform_action(action))
+                       {
+                               //get_ui_interface()->error(_("Move Action Not Ready"));                        
+                               //return 0;
+                               return;
+                       }
+               }       
+               depth++;
+       }
+       get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+       get_canvas_interface()->get_selection_manager()->set_selected_layers(layer_selection);
+}
+
+void
+LayerActionManager::amount_inc()
+{
+       float adjust(0.1);
+       
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Decrease Amount"));
+       
+       if(adjust>0)
+               group.set_name(_("Increase Amount"));
+
+       sinfgapp::SelectionManager::LayerList layer_list(layer_tree_->get_selected_layers());
+
+       while(!layer_list.empty())
+       {
+               ValueBase value(layer_list.front()->get_param("amount"));
+               if(value.same_as(Real()))
+               {
+                       get_canvas_interface()->change_value(sinfgapp::ValueDesc(layer_list.front(),"amount"),value.get(Real())+adjust);
+               }
+               layer_list.pop_front();
+       }
+}
+
+void
+LayerActionManager::amount_dec()
+{
+       float adjust(-0.1);
+       
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Decrease Amount"));
+       
+       if(adjust>0)
+               group.set_name(_("Increase Amount"));
+
+       sinfgapp::SelectionManager::LayerList layer_list(layer_tree_->get_selected_layers());
+
+       while(!layer_list.empty())
+       {
+               ValueBase value(layer_list.front()->get_param("amount"));
+               if(value.same_as(Real()))
+               {
+                       get_canvas_interface()->change_value(sinfgapp::ValueDesc(layer_list.front(),"amount"),value.get(Real())+adjust);
+               }
+               layer_list.pop_front();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/layeractionmanager.h b/synfig-studio/trunk/src/gtkmm/layeractionmanager.h
new file mode 100644 (file)
index 0000000..4e6a1ee
--- /dev/null
@@ -0,0 +1,107 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: layeractionmanager.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_LAYER_ACTION_MANAGER_H
+#define __SINFG_LAYER_ACTION_MANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/uimanager.h>
+#include <gtkmm/treeview.h>
+#include <sinfgapp/canvasinterface.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTree;
+
+class LayerActionManager
+{
+       Glib::RefPtr<Gtk::UIManager> ui_manager_;
+       //Glib::RefPtr<Gtk::TreeSelection> tree_selection_;
+       LayerTree* layer_tree_;
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gtk::ActionGroup>  action_group_;
+       Gtk::UIManager::ui_merge_id     popup_id_;
+       
+
+       Glib::RefPtr<Gtk::ActionGroup> action_group_copy_paste;
+
+       Glib::RefPtr<Gtk::Action>       action_cut_;
+       Glib::RefPtr<Gtk::Action>       action_copy_;
+       Glib::RefPtr<Gtk::Action>       action_paste_;
+
+       Glib::RefPtr<Gtk::Action>       action_amount_inc_;
+       Glib::RefPtr<Gtk::Action>       action_amount_dec_;
+       Glib::RefPtr<Gtk::Action>       action_amount_;
+
+
+       std::list<sinfg::Layer::Handle> clipboard_;
+
+       
+       sigc::connection selection_changed_connection;
+
+       bool queued;
+       sigc::connection queue_refresh_connection;
+
+       std::list<sigc::connection> update_connection_list;
+
+       void cut();
+       void copy();
+       void paste();
+
+       void amount_inc();
+       void amount_dec();
+
+public:
+       void queue_refresh();
+
+       LayerActionManager();
+       ~LayerActionManager();
+
+       void set_ui_manager(const Glib::RefPtr<Gtk::UIManager> &x);
+       Glib::RefPtr<Gtk::UIManager> get_ui_manager()const { return ui_manager_; }
+
+       void set_layer_tree(LayerTree* x);
+       LayerTree* get_layer_tree()const { return layer_tree_; }
+
+       void set_canvas_interface(const etl::handle<sinfgapp::CanvasInterface> &x);
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       etl::loose_handle<sinfgapp::Instance> get_instance()const { return canvas_interface_->get_instance(); }
+
+       void refresh();
+       void clear();
+}; // END of LayerActionManager
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layergrouptree.cpp b/synfig-studio/trunk/src/gtkmm/layergrouptree.cpp
new file mode 100644 (file)
index 0000000..88dc5fe
--- /dev/null
@@ -0,0 +1,329 @@
+/* === S I N F G =========================================================== */
+/*!    \file layergrouptree.cpp
+**     \brief Template File
+**
+**     $Id: layergrouptree.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <sinfg/layer.h>
+#include "layergrouptree.h"
+#include <gtkmm/treemodelsort.h>
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerGroupTree::LayerGroupTree()
+{
+       const LayerGroupTreeStore::Model model;
+
+       
+       {       // --- O N / O F F ----------------------------------------------------
+               int index;
+               index=append_column_editable(_(" "),model.active);
+               //Gtk::TreeView::Column* column = get_column(index-1);
+       }
+       {       // --- I C O N --------------------------------------------------------
+               int index;
+               index=append_column(_(" "),model.icon);
+               Gtk::TreeView::Column* column = get_column(index-1);
+               set_expander_column(*column);
+       }
+       {       // --- N A M E --------------------------------------------------------
+               int index;
+               index=append_column_editable(_("Name"),model.label);
+               label_column = get_column(index-1);
+
+               //column->set_sort_column_id(layer_model.index);
+
+               //set_expander_column(*column);
+               //column->set_reorderable();
+               //column->set_resizable();
+               //column->set_clickable(false);
+               
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+
+       set_enable_search(true);
+       set_search_column(model.label);
+       set_search_equal_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::search_func));
+
+       // This makes things easier to read.
+       set_rules_hint();
+               
+       // Make us more sensitive to several events
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+
+       set_reorderable(true);
+
+       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+
+       //set_flags(get_flags()|Gtk::RECEIVES_DEFAULT|Gtk::HAS_GRAB);
+
+       //std::list<Gtk::TargetEntry> listTargets;
+       //listTargets.push_back( Gtk::TargetEntry("LAYER") );
+       //listTargets.push_back( Gtk::TargetEntry("GROUP") );
+       //drag_dest_set(listTargets);
+}
+
+LayerGroupTree::~LayerGroupTree()
+{
+       sinfg::info("LayerGroupTree::~LayerGroupTree(): deleted");
+}
+
+void
+LayerGroupTree::set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store)
+{
+       layer_group_tree_store_=layer_group_tree_store;
+       LayerGroupTreeStore::Model model;
+       
+#if 0
+       {
+               Glib::RefPtr<Gtk::TreeModelSort> sorted_store(Gtk::TreeModelSort::create(layer_group_tree_store_));
+               sorted_store->set_default_sort_func(sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+               sorted_store->set_sort_func(model.time.index(),sigc::ptr_fun(&studio::LayerGroupTreeStore::time_sorter));
+               sorted_store->set_sort_column_id(model.time.index(), Gtk::SORT_ASCENDING);
+               Gtk::TreeView::set_model(sorted_store);
+       }
+#else
+               Gtk::TreeView::set_model(layer_group_tree_store);
+#endif
+}
+
+void
+LayerGroupTree::set_editable(bool x)
+{
+       editable_=x;
+/*     
+       if(editable_)
+       {
+               cell_renderer_time->property_editable()=true;
+               cell_renderer_time_delta->property_editable()=true;
+               cell_renderer_description->property_editable()=true;
+       }
+       else
+       {
+               cell_renderer_time->property_editable()=false;
+               cell_renderer_time_delta->property_editable()=false;
+               cell_renderer_description->property_editable()=false;
+       }
+*/
+}
+/*
+void
+LayerGroupTree::on_edited_time(const Glib::ustring&path_string,sinfg::Time time)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+       
+       sinfg::Keyframe keyframe(row[model.keyframe]);
+       if(time!=keyframe.get_time())
+       {
+               row[model.time]=time;
+               //keyframe.set_time(time);
+               //signal_edited_time()(keyframe,time);
+               //signal_edited()(keyframe);
+       }
+}
+
+void
+LayerGroupTree::on_edited_time_delta(const Glib::ustring&path_string,sinfg::Time time)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row(*(get_model()->get_iter(path)));
+       
+       if(row)row[model.time_delta]=time;
+}
+
+void
+LayerGroupTree::on_edited_description(const Glib::ustring&path_string,const Glib::ustring &desc)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+       
+       const sinfg::String description(desc);
+       sinfg::Keyframe keyframe(row[model.keyframe]);
+       if(description!=keyframe.get_description())
+       {
+               row[model.description]=desc;
+               keyframe.set_description(description);
+               signal_edited_description()(keyframe,description);
+               signal_edited()(keyframe);
+       }
+}
+*/
+
+bool
+LayerGroupTree::on_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       int wx(round_to_int(event->button.x)),wy(round_to_int(event->button.y));
+                       //tree_to_widget_coords (,, wx, wy);
+                       if(!get_path_at_pos(
+                               wx,wy,  // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+                       if(row[model.is_layer] && event->button.button==3)
+                       {
+                               signal_popup_layer_menu()((Layer::Handle)row[model.layer]);
+                               return true;
+                       }
+                       
+                       /*signal_user_click()(event->button.button,row,(ColumnID)column->get_sort_column_id());
+                       if((ColumnID)column->get_sort_column_id()==COLUMNID_JUMP)
+                       {
+                               layer_group_tree_store_->canvas_interface()->set_time(row[model.time]);
+                       }*/
+               }
+               break;
+       case GDK_2BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_model()->get_iter(path));
+                       
+                       LayerList layer_list(row[model.all_layers]);
+                       if(!layer_list.empty())
+                       {
+                               if(!(event->button.state&GDK_CONTROL_MASK))
+                               {
+                                       layer_group_tree_store_->canvas_interface()->get_selection_manager()->clear_selected_layers();
+                               }
+                               layer_group_tree_store_->canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+                               return true;
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return Gtk::TreeView::on_event(event);
+       //return false;
+}
+
+static inline void __group_grabber(const Gtk::TreeModel::iterator& iter, std::list<sinfg::String>* ret)
+{
+       const LayerGroupTreeStore::Model model;
+       if((bool)(*iter)[model.is_group])
+               ret->push_back((Glib::ustring)(*iter)[model.group_name]);
+}
+
+std::list<sinfg::String>
+LayerGroupTree::get_selected_groups()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+       if(!selection)
+               return std::list<sinfg::String>();
+
+       std::list<sinfg::String> ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__group_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerGroupTree::LayerList* ret)
+{
+       const LayerGroupTreeStore::Model model;
+       if((bool)(*iter)[model.is_layer])
+               ret->push_back((Layer::Handle)(*iter)[model.layer]);
+}
+
+LayerGroupTree::LayerList
+LayerGroupTree::get_selected_layers()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<LayerGroupTree&>(*this).get_selection();
+
+       if(!selection)
+               return LayerList();
+
+       LayerList ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__layer_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+void
+LayerGroupTree::set_cursor(const Gtk::TreeModel::Path& path, bool start_editing)
+{
+       Gtk::TreeView::set_cursor(path, *label_column, start_editing);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/layergrouptree.h b/synfig-studio/trunk/src/gtkmm/layergrouptree.h
new file mode 100644 (file)
index 0000000..7e76a62
--- /dev/null
@@ -0,0 +1,126 @@
+/* === S I N F G =========================================================== */
+/*!    \file layergrouptree.h
+**     \brief Template Header
+**
+**     $Id: layergrouptree.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_LAYERGROUPTREE_H
+#define __SINFG_STUDIO_LAYERGROUPTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "layergrouptreestore.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class Layer; }
+
+namespace studio {
+
+class LayerGroupTree : public Gtk::TreeView
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef std::list<sinfg::Layer::Handle> LayerList;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       LayerGroupTreeStore::Model model;
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_;
+
+       Gtk::CellRendererText *cell_renderer_description;
+
+       bool editable_;
+
+
+       sigc::signal<void,etl::handle<sinfg::Layer> > signal_popup_layer_menu_;
+
+//     sigc::signal<void,LayerList> signal_select_layers_;
+       Gtk::TreeView::Column* label_column;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_event(GdkEvent *event);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       LayerGroupTree();
+       ~LayerGroupTree();
+       void set_cursor(const Gtk::TreeModel::Path& path, bool start_editing=false);
+
+       Glib::RefPtr<LayerGroupTreeStore> get_model() { return layer_group_tree_store_; }
+
+       sigc::signal<void,etl::handle<sinfg::Layer> >& signal_popup_layer_menu() { return signal_popup_layer_menu_; }
+
+//     sigc::signal<void,LayerList>& signal_select_layers() { return signal_select_layers_; }
+
+       void set_model(Glib::RefPtr<LayerGroupTreeStore> layer_group_tree_store_);
+
+       void set_editable(bool x=true);
+       
+       bool get_editable()const { return editable_; }
+       
+       std::list<sinfg::String> get_selected_groups()const;
+
+       LayerList get_selected_layers()const;   
+}; // END of LayerGroupTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layergrouptreestore.cpp b/synfig-studio/trunk/src/gtkmm/layergrouptreestore.cpp
new file mode 100644 (file)
index 0000000..061f3f4
--- /dev/null
@@ -0,0 +1,1038 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertreestore.cpp
+**     \brief Template File
+**
+**     $Id: layergrouptreestore.cpp,v 1.2 2005/01/13 18:37:30 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layergrouptreestore.h"
+#include "iconcontroler.h"
+#include <gtkmm/button.h>
+#include <sinfg/paramdesc.h>
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include <sinfgapp/action_system.h>
+#include "dockmanager.h"
+#include "dockable.h"
+#include "iconcontroler.h"
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define GROUP_NEST_CHAR        '.'
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerGroupTreeStore::Model& ModelHack()
+{
+       static LayerGroupTreeStore::Model* model(0);
+       if(!model)model=new LayerGroupTreeStore::Model;
+       return *model;
+}
+
+LayerGroupTreeStore::LayerGroupTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+       layer_icon=Gtk::Button().render_icon(Gtk::StockID("sinfg-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       group_icon=Gtk::Button().render_icon(Gtk::StockID("sinfg-group"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       // Connect Signals to Terminals
+       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_status_changed));
+       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_layer_new_description));
+
+       canvas_interface()->get_canvas()->signal_group_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_added)));
+       canvas_interface()->get_canvas()->signal_group_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_removed)));
+       canvas_interface()->get_canvas()->signal_group_changed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_changed)));
+
+       canvas_interface()->get_canvas()->signal_group_pair_added().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_added)));
+       canvas_interface()->get_canvas()->signal_group_pair_removed().connect(sigc::hide_return(sigc::mem_fun(*this,&studio::LayerGroupTreeStore::on_group_pair_removed)));
+
+       rebuild();
+}
+
+LayerGroupTreeStore::~LayerGroupTreeStore()
+{
+       //clear();
+       sinfg::info("LayerGroupTreeStore::~LayerGroupTreeStore(): Deleted");
+}
+
+bool
+LayerGroupTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+       const Model model;
+
+       Glib::ustring substr(x.uppercase());
+       Glib::ustring label((*iter)[model.label]);
+       label=label.uppercase();
+               
+       return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerGroupTreeStore>
+LayerGroupTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<LayerGroupTreeStore>(new LayerGroupTreeStore(canvas_interface_));
+}
+
+void
+LayerGroupTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.child_layers.index())
+       {
+               Glib::Value<LayerList> x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               if((bool)(*iter)[model.is_group])
+               {
+                       set<Layer::Handle> layer_set(canvas_interface()->get_canvas()->get_layers_in_group((Glib::ustring)(*iter)[model.group_name]));
+               
+                       x.set(LayerList(layer_set.begin(),layer_set.end()));
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       LayerList layer_list;
+                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+                       x.set(layer_list);
+               }
+               
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.all_layers.index())
+       {
+               Glib::Value<LayerList> x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               if((bool)(*iter)[model.is_group])
+               {
+                       LayerList layer_list;
+                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
+                       for(;child_iter;++child_iter)
+                       {
+                               LayerList layer_list2((LayerList)(*child_iter)[model.all_layers]);
+                               for(;layer_list2.size();layer_list2.pop_front())
+                                       layer_list.push_back(layer_list2.front());
+                       }
+                       x.set(layer_list);
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       LayerList layer_list;
+                       layer_list.push_back((Layer::Handle)(*iter)[model.layer]);
+                       x.set(layer_list);
+               }
+               
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.group_name.index())
+       {
+               if((bool)(*iter)[model.is_group])
+                       return Gtk::TreeStore::get_value_vfunc(iter,column,value);
+               return get_value_vfunc(iter->parent(),column,value);
+       }
+       else if(column==model.parent_group_name.index())
+       {
+               if(iter->parent())
+                       return get_value_vfunc(iter->parent(),model.group_name.index(),value);
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(Glib::ustring());
+               g_value_init(value.gobj(),x.value_type());
+               value=x;
+       }
+       else if(column==model.label.index())
+       {
+               if((bool)(*iter)[model.is_group])
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),x.value_type());
+       
+                       Glib::ustring group_name((*iter)[model.group_name]);
+                       
+                       // Get rid of any parent group crap
+                       while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+                       
+                       x.set(group_name);
+                       
+                       g_value_init(value.gobj(),x.value_type());
+
+                       value=x;
+               }
+               else if((bool)(*iter)[model.is_layer])
+               {
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+       
+                       if(!layer)return;
+       
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),x.value_type());
+       
+       
+                       if(!layer->get_description().empty())
+                               x.set(layer->get_description());
+                       else
+                               x.set(layer->get_local_name());
+                       
+                       g_value_init(value.gobj(),x.value_type());
+                       //g_value_copy(x.gobj(),value.gobj());
+                       value=x;
+               }
+       }
+       else
+       if(column==model.tooltip.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_local_name());
+               
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.canvas.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Canvas::Handle> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_canvas());
+               
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.active.index())
+       {
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_layer])
+               {
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+                       x.set(layer->active());
+               }
+               else if((bool)(*iter)[model.is_group])
+               {
+                       int activecount(0),total(0);
+                       Gtk::TreeModel::iterator child_iter(iter->children().begin());
+                       for(;child_iter;++child_iter)
+                       {
+                               total++;
+                               if((*child_iter)[model.active])
+                                       activecount++;
+                       }
+                       x.set(activecount>total/2);
+               }
+               else
+                       x.set(false);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.icon.index())
+       {
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+
+               if((bool)(*iter)[model.is_layer])
+               {
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+                       if(!layer)return;
+                       //x.set(layer_icon);
+                       x.set(get_tree_pixbuf_layer(layer->get_name()));
+               }
+               if((bool)(*iter)[model.is_group])
+                       x.set(group_icon);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerGroupTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerGroupTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerGroupTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.label.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.label.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       if((bool)(*iter)[model.is_layer])
+                       {
+                               sinfg::Layer::Handle layer((*iter)[model.layer]);
+                               if(!layer)
+                                       return;
+                               sinfg::String new_desc(x.get());
+                               
+                               if(new_desc==layer->get_local_name())
+                                       new_desc=sinfg::String();
+       
+                               if(new_desc==layer->get_description())
+                                       return;
+                               
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_set_desc"));
+                               
+                               if(!action)
+                                       return;
+                               
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",layer);
+                               action->set_param("new_description",sinfg::String(x.get()));
+                               
+                               canvas_interface()->get_instance()->perform_action(action);
+                               return;
+                       }
+                       else if((bool)(*iter)[model.is_group])
+                       {
+                               sinfg::String group((Glib::ustring)(*iter)[model.label]);
+                               sinfg::String new_group(x.get());
+                               
+                               if(x.get()==group)
+                                       return;
+
+                               Glib::ustring group_name((*iter)[model.group_name]);
+                               group=group_name;
+                               new_group.clear();
+                               
+                               // Get rid of any parent group crap
+                               while(group_name.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               {
+                                       new_group+=Glib::ustring(group_name,0,group_name.find(GROUP_NEST_CHAR)+1);
+                                       group_name=Glib::ustring(group_name,group_name.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+                               }
+                               new_group+=x.get();
+                               
+                               sinfg::info("Renaming group \"%s\" to \"%s\"...",group.c_str(),new_group.c_str());
+                               
+                               // Check to see if this group is real or not.
+                               // If it isn't real, then renaming it is a cinch.
+                               // We know it isn't real if it doesn't have any
+                               // children yet.
+                               if(iter->children().empty())
+                               {
+                                       (*iter)[model.group_name]=new_group;
+                               }
+                               else
+                               {
+                                       sinfgapp::Action::Handle action(sinfgapp::Action::create("group_rename"));
+                                       
+                                       if(!action)
+                                               return;
+                                       
+                                       action->set_param("canvas",canvas_interface()->get_canvas());
+                                       action->set_param("canvas_interface",canvas_interface());
+                                       action->set_param("group",group);
+                                       action->set_param("new_group",new_group);
+                                       
+                                       canvas_interface()->get_instance()->perform_action(action);
+                               }
+                               return;
+                       }
+                       return;
+               }
+               else
+               if(column==model.active.index())
+               {
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       if((bool)(*iter)[model.is_layer])
+                       {                       
+                               sinfg::Layer::Handle layer((*iter)[model.layer]);
+                               if(!layer)return;
+                                       
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_activate"));
+                               
+                               if(!action)
+                                       return;
+                               
+                               action->set_param("canvas",canvas_interface()->get_canvas());
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",layer);
+                               action->set_param("new_status",bool(x.get()));
+
+                               
+                               canvas_interface()->get_instance()->perform_action(action);
+                               return;
+                       }
+                       else if(!iter->children().empty())
+                       {
+                               sinfgapp::Action::PassiveGrouper group(
+                                       get_canvas_interface()->get_instance().get(),
+                                       String(
+                                               x.get()?_("Activate "):_("Deactivate ")
+                                       )+(Glib::ustring)(*iter)[model.label]
+                               );
+                               
+                               Gtk::TreeModel::iterator child_iter(iter->children().begin());
+                               
+                               for(;child_iter;++child_iter)
+                                       (*child_iter)[model.active]=x.get();
+                               
+                               Gtk::TreeStore::set_value_impl(iter,column, value);
+                       }
+               }
+               else
+                       Gtk::TreeStore::set_value_impl(iter,column, value);
+
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
+
+
+
+
+bool
+LayerGroupTreeStore::row_draggable_vfunc (const TreeModel::Path& path)const
+{
+       //if(!get_iter(path)) return false;
+//     Gtk::TreeModel::Row row(*get_iter(path));
+       
+       return true;
+//     return (bool)true;
+}
+
+bool
+LayerGroupTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+       if(!const_cast<LayerGroupTreeStore*>(this)->get_iter(path)) return false;
+       //sinfg::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       Gtk::TreeModel::Row row(*const_cast<LayerGroupTreeStore*>(this)->get_iter(path));
+
+       if((bool)row[model.is_layer])
+       {
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+
+               std::vector<Layer*> layers;
+
+               layers.push_back(layer);
+               
+               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+
+               return true;
+       }
+       else if((bool)row[model.is_group])
+       {
+               sinfg::String group((Glib::ustring)row[model.group_name]);
+               if(group.empty())
+                       return false;
+               
+               selection_data.set("GROUP", 8, reinterpret_cast<const guchar*>(&*group.begin()), sizeof(void*)*group.size());
+
+               return true;            
+       }
+               
+       return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_delete_vfunc (const TreeModel::Path& path)
+{
+       return true;
+}
+
+bool
+LayerGroupTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+       Gtk::TreeIter iter(const_cast<LayerGroupTreeStore*>(this)->get_iter(dest));
+       if(!iter) return false;
+
+       if(sinfg::String(selection_data.get_data_type())=="LAYER")
+               return true;
+
+       if(sinfg::String(selection_data.get_data_type())=="GROUP")
+       {
+               sinfg::String dest_group((Glib::ustring)(*iter)[model.group_name]);
+               sinfg::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+               //sinfg::String src_group(const_cast<gchar*>(selection_data.get_data()));
+               
+               // Avoid putting a group inside of itself
+               if(dest_group.size()>src_group.size() && src_group==String(dest_group,0,src_group.size()))
+                       return false;
+               return true;
+       }
+       
+       return false;
+       //sinfg::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       
+       //Gtk::TreeModel::Row row(*get_iter(dest));
+
+/*     if(sinfg::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+               return true;
+*/
+       return false;
+}
+
+bool
+LayerGroupTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+       if(!get_iter(dest)) return false;
+//     bool ret=false;
+       //int i(0);
+       
+       Gtk::TreeModel::Row row(*get_iter(dest));
+
+       //sinfg::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       sinfgapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Regroup"));
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               sinfg::String dest_group;
+               
+               dest_group=(Glib::ustring)row[model.group_name];
+               
+               if(dest_group.empty())
+                       return false;
+
+               if(sinfg::String(selection_data.get_data_type())=="LAYER")
+               {
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("group_add_layers"));
+                       
+                       if(!action)
+                               return false;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("group",dest_group);
+
+                       for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+                       {
+                               Layer::Handle layer(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                               assert(layer);
+       
+                               action->set_param("layer",layer);
+                       }
+                       if(!canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               passive_grouper.cancel();
+                               return false;
+                       }
+                       return true;
+               }
+               if(sinfg::String(selection_data.get_data_type())=="GROUP")
+               {
+                       sinfg::String src_group(reinterpret_cast<const gchar*>(selection_data.get_data()));
+                       sinfg::String group(src_group);
+                       
+                       // Get rid of any parent group crap
+                       while(group.find(GROUP_NEST_CHAR)!=Glib::ustring::npos)
+                               group=Glib::ustring(group,group.find(GROUP_NEST_CHAR)+1,Glib::ustring::npos);
+                       
+                       group=dest_group+GROUP_NEST_CHAR+group;
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("group_rename"));
+                       
+                       if(!action)
+                               return false;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("group",src_group);
+                       action->set_param("new_group",group);
+                       
+                       if(!canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               passive_grouper.cancel();
+                               return false;
+                       }
+                       return true;
+               }
+       }
+/*     // Save the selection data
+       sinfgapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Canvas::Handle dest_canvas;
+               Layer::Handle dest_layer;
+               
+               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+               dest_layer=(Layer::Handle)(row[model.layer]);
+               assert(dest_canvas);
+
+               if(!dest_layer)
+                       return false;
+
+               int dest_layer_depth=dest_layer->get_depth();
+               
+               if(sinfg::String(selection_data.get_data_type())=="LAYER")for(i=0;i<selection_data.get_length()/sizeof(void*);i++)
+               {
+                       //sinfg::info("dest_layer_depth=%d",dest_layer_depth);
+                       
+                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                       assert(src);
+                       if(dest_layer==src)
+                               continue;
+                       
+                       // In this case, we are just moving.
+//                     if(dest_canvas==src->get_canvas())
+                       {
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+                                       dest_layer_depth--;
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+                                       continue;
+                               
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_move"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_layer_depth);
+                               action->set_param("dest_canvas",dest_canvas);
+                               if(canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       DEBUGPOINT();
+                                       ret=true;
+                               }
+                               else
+                               {
+                                       DEBUGPOINT();
+                                       passive_grouper.cancel();
+                                       return false;
+                               }
+                               continue;
+                       }
+               }
+       }
+       sinfg::info("I suposidly moved %d layers",i);
+
+       // Reselect the previously selected layers
+       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+       
+       return ret;
+       */
+       return false;
+}
+
+
+
+
+
+
+
+void
+LayerGroupTreeStore::rebuild()
+{
+       rebuilding=true;
+               etl::clock timer;timer.reset();
+       try {
+       
+               // Clear out the current list
+               clear();
+               Canvas::Handle canvas(canvas_interface()->get_canvas());
+               std::set<String> groups(canvas->get_groups());
+               for(;groups.size();groups.erase(groups.begin()))
+               {
+                       String group(*groups.begin());
+                       Gtk::TreeRow row(on_group_added(group));
+                       std::set<Layer::Handle> layers(canvas->get_layers_in_group(group));
+                       
+                       for(;layers.size();layers.erase(layers.begin()))
+                       {
+                               Gtk::TreeRow layer_row(*(prepend(row.children())));
+                               Layer::Handle layer(*layers.begin());
+                               set_row_layer(layer_row,layer);
+                       }               
+               }
+               
+               // Go ahead and and add all the layers
+               /*std::for_each(
+                       canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+                       sigc::mem_fun(*this, &studio::LayerGroupTreeStore::on_layer_added)
+               );*/
+       }
+       catch(...)
+       {
+               rebuilding=false;
+               throw;
+       }
+       rebuilding=false;
+       sinfg::info("LayerGroupTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerGroupTreeStore::refresh()
+{
+       rebuild();
+}
+
+void
+LayerGroupTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       if((bool)row[model.is_layer])
+       {
+               Layer::Handle layer=row[model.layer];
+       
+               
+               //if(layer->dynamic_param_list().count("z_depth"))
+               //      row[model.z_depth]=Time::begin();
+       }
+
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+
+void
+LayerGroupTreeStore::set_row_layer(Gtk::TreeRow &row,sinfg::Layer::Handle &handle)
+{
+       row[model.is_layer] = true;
+       row[model.is_group] = false;
+       row[model.layer] = handle;
+}
+
+Gtk::TreeRow
+LayerGroupTreeStore::on_group_added(sinfg::String group)
+{
+       // Check to see if this group perhaps already
+       // exists
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(find_group_row(group,  iter))
+                       return *iter;
+       }
+       
+       if(group.find(GROUP_NEST_CHAR)!=String::npos)
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               String parent_name;
+               do
+               {
+                       if(parent_name.size())
+                               parent_name+=GROUP_NEST_CHAR;
+                       parent_name+=string(group,0,group.find(GROUP_NEST_CHAR));
+                               
+                       if(!find_group_row(parent_name, iter))
+                               iter=on_group_added(parent_name);
+                       
+                       group=String(group,group.find(GROUP_NEST_CHAR)+1,String::npos);
+               }while(group.find(GROUP_NEST_CHAR)!=String::npos);
+
+               if(parent_name.size())
+                       parent_name+=GROUP_NEST_CHAR;
+               parent_name+=group;
+               
+               if(iter)
+               {
+                       Gtk::TreeRow row(*(prepend(iter->children())));
+                       row[model.group_name]=parent_name;
+                       row[model.is_layer]=false;
+                       row[model.is_group]=true;
+                       on_activity();
+                       return row;
+               }
+       }
+
+       Gtk::TreeRow row(*(append()));
+       row[model.group_name]=group;
+       row[model.is_layer]=false;
+       row[model.is_group]=true;
+       on_activity();
+       return row;
+}
+
+bool
+LayerGroupTreeStore::on_group_removed(sinfg::String group)
+{
+       //DEBUGPOINT();
+       
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_group_row(group,iter) && iter->children().size()==0)
+               erase(iter);
+       else
+               return false;
+       
+       return true;
+}
+
+bool
+LayerGroupTreeStore::on_group_changed(sinfg::String group)
+{
+       //DEBUGPOINT();
+       return true;
+}
+
+void
+LayerGroupTreeStore::on_group_pair_added(String group, etl::handle<Layer> layer)
+{
+       if(!layer->get_canvas())
+               return;
+       //DEBUGPOINT();
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_group_row(group, iter))
+               iter=on_group_added(group);
+
+       Gtk::TreeRow layer_row(*(append(iter->children())));
+       set_row_layer(layer_row,layer);
+       on_activity();
+}
+
+void
+LayerGroupTreeStore::on_group_pair_removed(String group, etl::handle<Layer> layer)
+{
+       if(!layer->get_canvas())
+               return;
+       //DEBUGPOINT();
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_group_row(group, iter))
+               return;
+
+       Gtk::TreeModel::Children::iterator prev,layer_iter;
+       
+       if(!find_layer_row_(layer, layer->get_canvas(), iter->children(), layer_iter, prev))
+               return;
+       
+       erase(layer_iter);
+       
+       on_activity();
+}
+
+void
+LayerGroupTreeStore::on_activity()
+{
+       // If we aren't rebuilding and the last action
+       // had something to do with groups, then go
+       // a head and present the groups dialog.
+       if(!rebuilding && canvas_interface()->get_instance()->get_most_recent_action() && canvas_interface()->get_instance()->get_most_recent_action()->get_name().find("group")!=String::npos)
+       try
+       {
+               App::dock_manager->find_dockable("groups").present();
+       }
+       catch(...) { }
+}
+
+void
+LayerGroupTreeStore::on_layer_status_changed(sinfg::Layer::Handle handle,bool x)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               (*iter)[model.layer]=handle;
+       else
+       {
+               sinfg::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+               rebuild();
+       }
+}
+
+
+void
+LayerGroupTreeStore::on_layer_new_description(sinfg::Layer::Handle handle,sinfg::String desc)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               Gtk::TreeRow row(*iter);
+               
+               Layer::Handle layer(row[model.layer]);          
+               
+               if(desc.empty())
+               {
+                       //row[model.label]=layer->get_local_name();
+                       row[model.tooltip]=Glib::ustring(_("Layer"));
+               }
+               else
+                       //row[model.label]=layer->get_description();
+                       row[model.tooltip]=layer->get_local_name();
+       }
+       else    
+       {
+               rebuild();
+       }
+}
+
+bool
+LayerGroupTreeStore::find_layer_row_(const sinfg::Layer::Handle &layer, sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+       assert(layer);
+       
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if((bool)row[model.is_layer] && layer==(sinfg::Layer::Handle)row[model.layer])
+                               return true;
+               }
+               
+               iter=children().end();
+               //DEBUGPOINT();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+       
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+               
+               if(row.children().empty())
+                       continue;
+               
+               /*Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+               if(!canvas)
+                       continue;
+               */
+               
+               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+                       return true;
+       }
+       
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerGroupTreeStore::find_layer_row(const sinfg::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row(const String &group, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_group_row_(group,children(),iter,prev);
+}
+
+bool
+LayerGroupTreeStore::find_group_row_(const sinfg::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if((bool)row[model.is_group] && group==(Glib::ustring)row[model.group_name])
+                               return true;
+               }
+               
+               iter=children().end();
+               //DEBUGPOINT();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+       
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+               
+               if(row.children().empty())
+                       continue;
+                               
+               if(find_group_row_(group,iter2->children(),iter,prev))
+                       return true;
+       }
+       
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerGroupTreeStore::find_prev_layer_row(const sinfg::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+               return false;
+       if(iter==children().begin())
+               return false;
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/layergrouptreestore.h b/synfig-studio/trunk/src/gtkmm/layergrouptreestore.h
new file mode 100644 (file)
index 0000000..dfd83a7
--- /dev/null
@@ -0,0 +1,201 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertreestore.h
+**     \brief Template Header
+**
+**     $Id: layergrouptreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_LAYERGROUPTREESTORE_H
+#define __SINFG_STUDIO_LAYERGROUPTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/value.h>
+#include <sinfg/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerGroupTreeStore :  public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+       typedef std::list<sinfg::Layer::Handle> LayerList;
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+               
+               Gtk::TreeModelColumn<Glib::ustring> group_name;
+               Gtk::TreeModelColumn<Glib::ustring> parent_group_name;
+
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle> canvas;
+
+               Gtk::TreeModelColumn<bool>                                              active;
+               Gtk::TreeModelColumn<bool>                                              is_layer;
+               Gtk::TreeModelColumn<bool>                                              is_group;
+               Gtk::TreeModelColumn<sinfg::Layer::Handle>              layer;
+               
+               Gtk::TreeModelColumn<LayerList>         all_layers;
+               Gtk::TreeModelColumn<LayerList>         child_layers;
+               
+               Model()
+               {
+                       add(icon);
+                       add(label);
+                       add(group_name);
+                       add(parent_group_name);
+                       add(canvas);
+                       add(tooltip);
+                       add(active);
+                       add(layer);
+                       add(is_layer);
+                       add(is_group);
+                       add(all_layers);
+                       add(child_layers);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       //! TreeModel for the layers
+       const Model model;
+       
+       bool rebuilding;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+       Glib::RefPtr<Gdk::Pixbuf> group_icon;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+private:
+
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
+       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
+       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+
+       void on_group_pair_added(sinfg::String group, etl::handle<sinfg::Layer> layer);
+       void on_group_pair_removed(sinfg::String group, etl::handle<sinfg::Layer> layer);
+
+       void on_activity();
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       void on_layer_new_description(sinfg::Layer::Handle handle,sinfg::String desc);
+
+       void on_layer_status_changed(sinfg::Layer::Handle handle,bool);
+
+       bool find_layer_row_(const sinfg::Layer::Handle &handle, sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool find_group_row_(const sinfg::String &group, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool on_group_removed(sinfg::String group);
+       bool on_group_changed(sinfg::String group);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       LayerGroupTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+       ~LayerGroupTreeStore();
+
+       Gtk::TreeRow on_group_added(sinfg::String group);
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const sinfgapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       bool find_layer_row(const sinfg::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_group_row(const sinfg::String &group, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_prev_layer_row(const sinfg::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       void rebuild();
+
+       void refresh();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       void set_row_layer(Gtk::TreeRow &row,sinfg::Layer::Handle &handle);
+
+       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+       
+       static Glib::RefPtr<LayerGroupTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+
+}; // END of class LayerGroupTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layerparamtreestore.cpp b/synfig-studio/trunk/src/gtkmm/layerparamtreestore.cpp
new file mode 100644 (file)
index 0000000..c36abad
--- /dev/null
@@ -0,0 +1,559 @@
+/* === S I N F G =========================================================== */
+/*!    \file childrentreestore.cpp
+**     \brief Template File
+**
+**     $Id: layerparamtreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamtreestore.h"
+#include "iconcontroler.h"
+#include <gtkmm/button.h>
+#include <sinfg/paramdesc.h>
+#include "layertree.h"
+#include <sinfgapp/action_system.h>
+#include <sinfgapp/instance.h>
+#include "app.h"
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+class Profiler : private etl::clock
+{
+       const std::string name;
+public:
+       Profiler(const std::string& name):name(name) { reset(); }
+       ~Profiler() { float time(operator()()); sinfg::info("%s: took %f msec",name.c_str(),time*1000); }
+};
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerParamTreeStore::Model& ModelHack()
+{
+       static LayerParamTreeStore::Model* model(0);
+       if(!model)model=new LayerParamTreeStore::Model;
+       return *model;
+}
+
+LayerParamTreeStore::LayerParamTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_,LayerTree* layer_tree):
+       Gtk::TreeStore                  (ModelHack()),
+       CanvasTreeStore                 (canvas_interface_),
+       layer_tree                              (layer_tree)
+{
+       queued=false;
+       // Connect all the signals
+       canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_changed));
+       canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_added));
+       canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_deleted));
+       canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_replaced));
+       canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_layer_param_changed));
+
+       canvas_interface()->signal_value_node_child_added().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_added));
+       canvas_interface()->signal_value_node_child_removed().connect(sigc::mem_fun(*this,&studio::LayerParamTreeStore::on_value_node_child_removed));
+       
+       
+       layer_tree->get_selection()->signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_rebuild));
+       
+       signal_changed().connect(sigc::mem_fun(*this,&LayerParamTreeStore::queue_refresh));
+       rebuild();
+}
+
+LayerParamTreeStore::~LayerParamTreeStore()
+{
+       while(!changed_connection_list.empty())
+       {
+               changed_connection_list.back().disconnect();
+               changed_connection_list.pop_back();
+       }
+       sinfg::info("LayerParamTreeStore::~LayerParamTreeStore(): Deleted");
+}
+
+Glib::RefPtr<LayerParamTreeStore>
+LayerParamTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree)
+{
+       return Glib::RefPtr<LayerParamTreeStore>(new LayerParamTreeStore(canvas_interface_,layer_tree));
+}
+
+
+
+void
+LayerParamTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column<0)
+       {
+               sinfg::error("LayerParamTreeStore::get_value_vfunc(): Bad column!");
+               return;
+       }
+       
+/*     if(column==model.label.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               if(!layer->get_description().empty())
+                       x.set(layer->get_description());
+               else
+                       x.set(layer->get_local_name());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+*/
+       if(column==model.label.index())
+       {
+               sinfgapp::ValueDesc value_desc((*iter)[model.value_desc]);
+               Glib::ustring label;
+               
+               if(!(*iter)[model.is_toplevel])
+                       return CanvasTreeStore::get_value_vfunc(iter,column,value);
+               sinfg::ParamDesc param_desc((*iter)[model.param_desc]);
+               label=param_desc.get_local_name();
+               
+               if(!(*iter)[model.is_inconsistent])
+               if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
+               {
+                       label+=strprintf(" (%s)",value_desc.get_value_node()->get_id().c_str());
+               }
+               
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(label);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_toplevel.index())
+       {
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               TreeModel::Path path(get_path(iter));
+               
+               x.set(path.get_depth()<=1);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.is_inconsistent.index())
+       {
+               if((*iter)[model.is_toplevel])
+               {
+                       CanvasTreeStore::get_value_vfunc(iter,column,value);
+                       return;
+               }
+               
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(false);
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       CanvasTreeStore::get_value_vfunc(iter,column,value);
+}
+
+
+
+void
+LayerParamTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.value.index())
+               {
+                       Glib::Value<sinfg::ValueBase> x;
+                       g_value_init(x.gobj(),model.value.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       if((bool)(*iter)[model.is_toplevel])
+                       {
+                               sinfgapp::Action::PassiveGrouper group(canvas_interface()->get_instance().get(),_("Set Layer Params"));
+
+                               sinfg::ParamDesc param_desc((*iter)[model.param_desc]);
+
+                               LayerList::iterator iter2(layer_list.begin());
+                               
+                               for(;iter2!=layer_list.end();++iter2)
+                               {
+                                       if(!canvas_interface()->change_value(sinfgapp::ValueDesc(*iter2,param_desc.get_name()),x.get()))
+                                       {
+                                               // ERROR!
+                                               group.cancel();
+                                               App::dialog_error_blocking(_("Error"),_("Unable to set all layer parameters."));
+                                               
+                                               return;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               canvas_interface()->change_value((*iter)[model.value_desc],x.get());
+                       }
+                       return;
+               }
+               else
+/*
+               if(column==model.active.index())
+               {
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+                       
+                       if(!layer)return;
+
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_activate"));
+                       
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_status",bool(x.get()));
+                       
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else
+*/
+               CanvasTreeStore::set_value_impl(iter,column, value);
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
+
+
+
+
+
+
+
+
+
+
+void
+LayerParamTreeStore::rebuild()
+{
+       Profiler profiler("LayerParamTreeStore::rebuild()");
+       if(queued)queued=false;
+       clear();
+       layer_list=layer_tree->get_selected_layers();
+       
+       if(layer_list.size()<=0)
+               return;
+       
+       // Get rid of all the connections,
+       // and clear the connection map.
+       //while(!connection_map.empty())connection_map.begin()->second.disconnect(),connection_map.erase(connection_map.begin());
+       while(!changed_connection_list.empty())
+       {
+               changed_connection_list.back().disconnect();
+               changed_connection_list.pop_back();
+       }
+
+       struct REBUILD_HELPER
+       {
+               ParamVocab vocab;
+
+               static ParamVocab::iterator find_param_desc(ParamVocab& vocab, const sinfg::String& x)
+               {
+                       ParamVocab::iterator iter;
+       
+                       for(iter=vocab.begin();iter!=vocab.end();++iter)
+                               if(iter->get_name()==x)
+                                       break;
+                       return iter;
+               }
+               
+               void process_vocab(ParamVocab x)
+               {
+                       ParamVocab::iterator iter;
+       
+                       for(iter=vocab.begin();iter!=vocab.end();++iter)
+                       {
+                               ParamVocab::iterator iter2(find_param_desc(x,iter->get_name()));
+                               if(iter2==x.end())
+                               {
+                                       // remove it and start over
+                                       vocab.erase(iter);
+                                       iter=vocab.begin();
+                                       iter--;
+                                       continue;
+                               }
+                       }
+               }
+               
+       } rebuild_helper;
+
+       
+       {
+               LayerList::iterator iter(layer_list.begin());
+               rebuild_helper.vocab=(*iter)->get_param_vocab();
+               
+               for(++iter;iter!=layer_list.end();++iter)
+               {
+                       rebuild_helper.process_vocab((*iter)->get_param_vocab());
+                       changed_connection_list.push_back(
+                               (*iter)->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+       }
+       
+       ParamVocab::iterator iter;
+       for(iter=rebuild_helper.vocab.begin();iter!=rebuild_helper.vocab.end();++iter)
+       {
+               if(iter->get_hidden())
+                       continue;
+               
+               /*
+               if(iter->get_animation_only())
+               {
+                       int length(layer_list.front()->get_canvas()->rend_desc().get_frame_end()-layer_list.front()->get_canvas()->rend_desc().get_frame_start());
+                       if(!length)
+                               continue;
+               }
+               */
+               Gtk::TreeRow row(*(append()));
+               sinfgapp::ValueDesc value_desc(layer_list.front(),iter->get_name());
+               CanvasTreeStore::set_row(row,value_desc);
+               if(value_desc.is_value_node())
+               {
+                       changed_connection_list.push_back(
+                               value_desc.get_value_node()->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+               if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
+               {
+                       changed_connection_list.push_back(
+                               value_desc.get_value().get(Canvas::Handle())->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               this,
+                                               &LayerParamTreeStore::changed
+                                       )
+                               )
+                       );
+               }
+               //row[model.label] = iter->get_local_name();
+               row[model.param_desc] = *iter;
+               row[model.canvas] = layer_list.front()->get_canvas();
+               row[model.is_inconsistent] = false;
+               //row[model.is_toplevel] = true;
+
+
+               LayerList::iterator iter2(layer_list.begin());
+               ValueBase value((*iter2)->get_param(iter->get_name()));
+               for(++iter2;iter2!=layer_list.end();++iter2)
+               {
+                       if(value!=((*iter2)->get_param(iter->get_name())))
+                       {
+                               row[model.is_inconsistent] = true;
+                               while(!row.children().empty() && erase(row.children().begin()));
+                               break;
+                       }       
+               }
+       }       
+}
+
+void
+LayerParamTreeStore::queue_refresh()
+{
+       if(queued)
+               return;
+       queued=1;
+       queue_connection.disconnect();
+       queue_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerParamTreeStore::refresh),
+                       false
+               )
+       ,150);
+
+}
+
+void
+LayerParamTreeStore::queue_rebuild()
+{
+       if(queued==2)
+               return;
+       queued=2;
+       queue_connection.disconnect();
+       queue_connection=Glib::signal_timeout().connect(
+               sigc::bind_return(
+                       sigc::mem_fun(*this,&LayerParamTreeStore::rebuild),
+                       false
+               )
+       ,150);
+
+}
+
+void
+LayerParamTreeStore::refresh()
+{
+       if(queued)queued=false;
+       
+       Gtk::TreeModel::Children children_(children());
+       
+       Gtk::TreeModel::Children::iterator iter;
+       
+       if(!children_.empty())
+               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+void
+LayerParamTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       if(row[model.is_toplevel])
+       {
+               row[model.is_inconsistent] = false;
+               ParamDesc param_desc(row[model.param_desc]);
+               
+               LayerList::iterator iter2(layer_list.begin());
+               ValueBase value((*iter2)->get_param(param_desc.get_name()));
+               for(++iter2;iter2!=layer_list.end();++iter2)
+               {
+                       if(value!=((*iter2)->get_param(param_desc.get_name())))
+                       {
+                               row[model.is_inconsistent] = true;
+                               while(!row.children().empty() && erase(row.children().begin()));
+                               return;
+                       }       
+               }
+       }
+
+       //handle<ValueNode> value_node=row[model.value_node];
+       //if(value_node)
+       {
+               CanvasTreeStore::refresh_row(row);
+               return;
+       }
+}
+
+void
+LayerParamTreeStore::set_row(Gtk::TreeRow row,sinfgapp::ValueDesc value_desc)
+{
+       Gtk::TreeModel::Children children = row.children();
+       while(!children.empty() && erase(children.begin()));
+
+       CanvasTreeStore::set_row(row,value_desc);
+}
+
+void
+LayerParamTreeStore::on_value_node_added(ValueNode::Handle value_node)
+{
+//     queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_deleted(etl::handle<ValueNode> value_node)
+{
+//     queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_added(sinfg::ValueNode::Handle value_node,sinfg::ValueNode::Handle child)
+{
+       queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_child_removed(sinfg::ValueNode::Handle value_node,sinfg::ValueNode::Handle child)
+{
+       queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_value_node_changed(etl::handle<ValueNode> value_node)
+{
+       queue_refresh();
+}
+
+void
+LayerParamTreeStore::on_value_node_replaced(sinfg::ValueNode::Handle replaced_value_node,sinfg::ValueNode::Handle new_value_node)
+{
+       queue_rebuild();
+}
+
+void
+LayerParamTreeStore::on_layer_param_changed(sinfg::Layer::Handle handle,sinfg::String param_name)
+{
+       queue_refresh();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/layerparamtreestore.h b/synfig-studio/trunk/src/gtkmm/layerparamtreestore.h
new file mode 100644 (file)
index 0000000..24d338d
--- /dev/null
@@ -0,0 +1,163 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamtreestore.h
+**     \brief Template Header
+**
+**     $Id: layerparamtreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_LAYERPARAMTREESTORE_H
+#define __SINFG_STUDIO_LAYERPARAMTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include "canvastreestore.h"
+#include <sinfg/value.h>
+#include <sinfg/valuenode.h>
+#include <sinfg/paramdesc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTree;
+       
+class LayerParamTreeStore : public CanvasTreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+       typedef std::list<sinfg::Layer::Handle> LayerList;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       //! TreeModel for the layer parameters
+       class Model : public CanvasTreeStore::Model
+       {
+       public:
+
+               Gtk::TreeModelColumn<sinfg::ParamDesc>  param_desc;
+
+               Gtk::TreeModelColumn<bool>      is_inconsistent;
+               Gtk::TreeModelColumn<bool>      is_toplevel;
+
+               Model()
+               {
+                       add(param_desc);
+                       add(is_inconsistent);
+                       add(is_toplevel);
+               }
+       };
+       
+       Model model;
+
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       int queued;
+       
+       LayerTree* layer_tree;
+       
+       LayerList layer_list;
+
+       sigc::connection queue_connection;
+       
+       std::list<sigc::connection> changed_connection_list;
+
+       sigc::signal<void> signal_changed_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+protected:
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void set_row(Gtk::TreeRow row,sinfgapp::ValueDesc value_desc);
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_value_node_child_added(sinfg::ValueNode::Handle value_node,sinfg::ValueNode::Handle child);
+       void on_value_node_child_removed(sinfg::ValueNode::Handle value_node,sinfg::ValueNode::Handle child);
+
+       void on_value_node_added(sinfg::ValueNode::Handle value_node);
+       void on_value_node_deleted(sinfg::ValueNode::Handle value_node);
+       virtual void on_value_node_changed(sinfg::ValueNode::Handle value_node);
+       void on_value_node_replaced(sinfg::ValueNode::Handle replaced_value_node,sinfg::ValueNode::Handle new_value_node);
+       void on_layer_param_changed(sinfg::Layer::Handle handle,sinfg::String param_name);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       LayerParamTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_,
+               LayerTree* layer_tree);
+       ~LayerParamTreeStore();
+
+       void rebuild();
+
+       void refresh();
+
+       void queue_refresh();
+
+       void queue_rebuild();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       sigc::signal<void>& signal_changed() { return signal_changed_; }
+
+       void changed() { signal_changed_(); }
+       
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+       
+       static Glib::RefPtr<LayerParamTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_, LayerTree*layer_tree);
+}; // END of class LayerParamTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layertree.cpp b/synfig-studio/trunk/src/gtkmm/layertree.cpp
new file mode 100644 (file)
index 0000000..6e1c05c
--- /dev/null
@@ -0,0 +1,1231 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertree.cpp
+**     \brief Template File
+**
+**     $Id: layertree.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layertree.h"
+#include "layerparamtreestore.h"
+#include "cellrenderer_value.h"
+#include "cellrenderer_timetrack.h"
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/paned.h>
+#include "app.h"
+#include "instance.h"
+#include <gtkmm/treemodelsort.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SMALL_BUTTON
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+#endif
+
+#ifndef NORMAL_BUTTON
+#define NORMAL_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       tooltips_.set_tip(*button,tooltip);     \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       /*button->set_relief(Gtk::RELIEF_NONE);*/ \
+       button->show()
+#endif
+
+#define NEW_SMALL_BUTTON(x,y,z)        Gtk::Button *SMALL_BUTTON(x,y,z)
+
+#define NOT_IMPLEMENTED_SLOT sigc::mem_fun(*reinterpret_cast<studio::CanvasViewUIInterface*>(get_ui_interface().get()),&studio::CanvasViewUIInterface::not_implemented)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+LayerTree::LayerTree():
+       layer_amount_adjustment_(1,0,1,0.01,0.01,0)
+{      
+       param_tree_view_=new Gtk::TreeView;
+       layer_tree_view_=new Gtk::TreeView;
+       
+       //Gtk::HPaned* hpaned(manage(new Gtk::HPaned()));
+       //hpaned->show();
+       //attach(*hpaned, 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //attach(*create_layer_tree(), 0, 3, 0, 1, Gtk::EXPAND|Gtk::FILL,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       create_layer_tree();
+       create_param_tree();
+       
+       //hpaned->pack1(*create_layer_tree(),false,false);
+       //hpaned->pack2(*create_param_tree(),true,false);
+       //hpaned->set_position(200);
+       hbox=manage(new Gtk::HBox());
+       
+       attach(*hbox, 0, 1, 1, 2, Gtk::FILL|Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       attach(blend_method_widget, 2, 3, 1, 2,Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       layer_amount_hscale=manage(new Gtk::HScale(layer_amount_adjustment_));
+       layer_amount_hscale->set_digits(2);
+       layer_amount_hscale->set_value_pos(Gtk::POS_LEFT);
+       layer_amount_hscale->set_sensitive(false);
+       layer_amount_hscale->set_update_policy( Gtk::UPDATE_DISCONTINUOUS);     
+       attach(*layer_amount_hscale, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 1, 1);
+       layer_amount_adjustment_.signal_value_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_amount_value_changed));
+       
+       
+       
+       
+       Gtk::Image *icon;
+       //Gtk::IconSize iconsize(Gtk::IconSize::from_name("sinfg-small_icon"));
+       Gtk::IconSize iconsize(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       SMALL_BUTTON(button_raise,"gtk-go-up","Raise");
+       SMALL_BUTTON(button_lower,"gtk-go-down","Lower");
+       SMALL_BUTTON(button_duplicate,"sinfg-duplicate","Duplicate");
+       SMALL_BUTTON(button_delete,"gtk-delete","Delete");
+       
+       hbox->pack_start(*button_raise,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_lower,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_duplicate,Gtk::PACK_SHRINK);
+       hbox->pack_start(*button_delete,Gtk::PACK_SHRINK);
+
+       button_raise->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_raise_pressed));
+       button_lower->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_lower_pressed));
+       button_duplicate->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_duplicate_pressed));
+       button_delete->signal_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_delete_pressed));
+
+       button_raise->set_sensitive(false);
+       button_lower->set_sensitive(false);
+       button_duplicate->set_sensitive(false);
+       button_delete->set_sensitive(false);
+
+
+
+
+       get_selection()->signal_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_selection_changed));
+
+
+       get_layer_tree_view().set_reorderable(true);
+       get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+       //get_param_tree_view().get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
+       get_layer_tree_view().show();
+       param_tree_view().show();
+
+
+       hbox->show();
+       layer_amount_hscale->show();
+       blend_method_widget.show();
+
+       tooltips_.enable();
+       disable_amount_changed_signal=false;
+
+
+
+
+
+       blend_method_widget.set_param_desc(ParamDesc(Color::BlendMethod(),"blend_method"));
+
+       blend_method_widget.set_value((int)Color::BLEND_COMPOSITE);
+       blend_method_widget.set_size_request(150,-1);
+       blend_method_widget.set_sensitive(false);
+       blend_method_widget.signal_activate().connect(sigc::mem_fun(*this, &studio::LayerTree::on_blend_method_changed));
+}
+
+
+LayerTree::~LayerTree()
+{
+       sinfg::info("LayerTree::~LayerTree(): Deleted");
+}
+
+Gtk::Widget*
+LayerTree::create_layer_tree()
+{
+       const LayerTreeStore::Model model;
+
+       
+       {       // --- O N / O F F ----------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column_editable(_(" "),layer_model.active);
+               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+       }
+       {       // --- I C O N --------------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column(_("Z"),layer_model.icon);
+               Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+               get_layer_tree_view().set_expander_column(*column);
+
+
+               column->set_sort_column_id(layer_model.z_depth);
+               //column->set_reorderable();
+               //column->set_resizable();
+               //column->set_clickable();
+               
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+       //get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+       {       // --- N A M E --------------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column_editable(_("Layer"),layer_model.label);
+               //Gtk::TreeView::Column* column = get_layer_tree_view().get_column(index-1);
+
+               //column->set_sort_column_id(layer_model.index);
+
+               //get_layer_tree_view().set_expander_column(*column);
+               //column->set_reorderable();
+               //column->set_resizable();
+               //column->set_clickable(false);
+               
+               //Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               //column->pack_start(*icon_cellrenderer,false);
+               //column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+       }
+       {       // --- Z D E P T H ----------------------------------------------------
+               int index;
+               index=get_layer_tree_view().append_column(_("Z"),layer_model.z_depth);
+               column_z_depth=get_layer_tree_view().get_column(index-1);
+
+               column_z_depth->set_reorderable();
+               column_z_depth->set_resizable();
+               column_z_depth->set_clickable();
+
+               column_z_depth->set_sort_column_id(layer_model.z_depth);
+       }
+       /*
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Layer")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_start(*icon_cellrenderer,false);
+               column->add_attribute(icon_cellrenderer->property_pixbuf(), layer_model.icon);
+
+               // Set up the text attributes
+               Pango::AttrList attr_list;
+               {
+                       Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
+                       pango_size.set_start_index(0);
+                       pango_size.set_end_index(64);
+                       attr_list.change(pango_size);
+               }
+
+               // Pack the label into the column
+               //column->pack_start(layer_model.label,true);
+               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+               column->pack_start(*text_cellrenderer,false);
+               column->add_attribute(text_cellrenderer->property_text(), layer_model.label);
+               text_cellrenderer->property_attributes()=attr_list;
+                               
+               // Finish setting up the column         
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               get_layer_tree_view().append_column(*column);
+               get_layer_tree_view().set_expander_column(*column);
+       }
+       */
+       
+/*     {
+               Gtk::Widget& widget(get_layer_tree_view());
+               Pango::FontDescription font(widget.get_modifier_style()->get_font());
+               font.set_size(font.get_size()*3/4);
+               widget.get_modifier_style()->set_font(font);
+               widget.modify_style(widget.get_modifier_style());
+       }
+*/
+       get_layer_tree_view().set_enable_search(true);
+       get_layer_tree_view().set_search_column(layer_model.label);
+       get_layer_tree_view().set_search_equal_func(sigc::ptr_fun(&studio::LayerTreeStore::search_func));
+
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("LAYER") );
+       get_layer_tree_view().drag_dest_set(listTargets);
+
+
+       // This makes things easier to read.
+       get_layer_tree_view().set_rules_hint();
+               
+       // Make us more sensitive to several events
+       //get_layer_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+       
+       get_layer_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_layer_tree_event));
+       get_layer_tree_view().show();
+
+
+
+       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+       scroll->set_flags(Gtk::CAN_FOCUS);
+       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       //scroll->add(get_layer_tree_view());
+       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll->show();
+       
+       return scroll;
+}
+
+Gtk::Widget*
+LayerTree::create_param_tree()
+{
+       Pango::AttrList attr_list;
+       {
+               Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*8));
+               pango_size.set_start_index(0);
+               pango_size.set_end_index(64);
+               attr_list.change(pango_size);
+       }
+       
+       Gtk::IconSize icon_size(Gtk::ICON_SIZE_SMALL_TOOLBAR);
+       
+       {       // --- N A M E --------------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Param")) );
+
+               // Set up the icon cell-renderer
+               Gtk::CellRendererPixbuf* icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_start(*icon_cellrenderer,false);
+               column->add_attribute(icon_cellrenderer->property_pixbuf(), param_model.icon);
+               
+               // Pack the label into the column
+               //column->pack_start(layer_model.label,true);
+               Gtk::CellRendererText* text_cellrenderer = Gtk::manage( new Gtk::CellRendererText() );
+               column->pack_start(*text_cellrenderer,false);
+               column->add_attribute(text_cellrenderer->property_text(), param_model.label);
+               text_cellrenderer->property_attributes()=attr_list;
+
+               text_cellrenderer->property_foreground()=Glib::ustring("#7f7f7f");
+               column->add_attribute(text_cellrenderer->property_foreground_set(),param_model.is_inconsistent);
+
+               // Pack the label into the column
+               //column->pack_start(param_model.label,true);
+
+               // Set up the value-node icon cell-renderer to be on the far right
+               Gtk::CellRendererPixbuf* valuenode_icon_cellrenderer = Gtk::manage( new Gtk::CellRendererPixbuf() );
+               column->pack_end(*valuenode_icon_cellrenderer,false);
+               valuenode_icon_cellrenderer->property_pixbuf()=Gtk::Button().render_icon(Gtk::StockID("sinfg-value_node"),icon_size);
+               column->add_attribute(valuenode_icon_cellrenderer->property_visible(), param_model.is_shared);
+
+               // Finish setting up the column         
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_clickable();
+               
+               param_tree_view().append_column(*column);
+       }
+       {       // --- V A L U E  -----------------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("ValueBase")) );
+               
+               // Set up the value cell-renderer
+               cellrenderer_value=LayerParamTreeStore::add_cell_renderer_value(column);
+               cellrenderer_value->signal_edited().connect(sigc::mem_fun(*this, &studio::LayerTree::on_edited_value));
+               cellrenderer_value->property_value()=sinfg::ValueBase();
+               column->add_attribute(cellrenderer_value->property_param_desc(), param_model.param_desc);
+               column->add_attribute(cellrenderer_value->property_inconsistant(),param_model.is_inconsistent);
+               //cellrenderer_value->property_canvas()=canvas_interface->get_canvas(); // Is this line necessary?
+               cellrenderer_value->property_attributes()=attr_list;
+
+               // Finish setting up the column
+               param_tree_view().append_column(*column);
+               column->set_sizing(Gtk::TREE_VIEW_COLUMN_AUTOSIZE);
+               column->set_clickable();
+               column->set_min_width(120);
+               column->set_reorderable();
+               column->set_resizable();
+       }
+       /*{     // --- T I M E   T R A C K --------------------------------------------
+               Gtk::TreeView::Column* column = Gtk::manage( new Gtk::TreeView::Column(_("Time Track")) );
+               column_time_track=column;
+               
+               // Set up the value-node cell-renderer
+               cellrenderer_time_track=LayerParamTreeStore::add_cell_renderer_value_node(column);
+               cellrenderer_time_track->property_mode()=Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
+               cellrenderer_time_track->signal_waypoint_clicked().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_clicked) );
+               cellrenderer_time_track->signal_waypoint_changed().connect(sigc::mem_fun(*this, &studio::LayerTree::on_waypoint_changed) );
+               column->add_attribute(cellrenderer_time_track->property_value_desc(), param_model.value_desc);
+               column->add_attribute(cellrenderer_time_track->property_canvas(), param_model.canvas);
+               //column->add_attribute(cellrenderer_time_track->property_visible(), model.is_value_node);
+
+               //column->pack_start(*cellrenderer_time_track);
+                               
+               // Finish setting up the column
+               column->set_reorderable();
+               column->set_resizable();
+               column->set_min_width(200);
+               //param_tree_view().append_column(*column);
+       }*/
+
+
+       
+       // This makes things easier to read.
+       param_tree_view().set_rules_hint();
+               
+       // Make us more sensitive to several events
+       param_tree_view().add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK|Gdk::POINTER_MOTION_MASK);
+       
+       param_tree_view().signal_event().connect(sigc::mem_fun(*this, &studio::LayerTree::on_param_tree_event));
+       param_tree_view().show();
+       
+       Gtk::ScrolledWindow *scroll = manage(new class Gtk::ScrolledWindow());
+       scroll->set_flags(Gtk::CAN_FOCUS);
+       scroll->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+       //scroll->add(param_tree_view());
+       scroll->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
+       scroll->show();
+
+       //column_time_track->set_visible(false);
+       
+       return scroll;
+}
+
+void
+LayerTree::on_waypoint_changed( sinfg::Waypoint waypoint , sinfg::ValueNode::Handle value_node)
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       param_list.add("value_node",value_node);
+       param_list.add("waypoint",waypoint);
+//     param_list.add("time",canvas_interface()->get_time());
+
+       etl::handle<studio::Instance>::cast_static(layer_tree_store_->canvas_interface()->get_instance())->process_action("waypoint_set_smart", param_list);
+}
+
+void
+LayerTree::select_layer(Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(layer_tree_store_->find_layer_row(layer,iter))
+       {
+               if(sorted_layer_tree_store_)
+                       iter=sorted_layer_tree_store_->convert_child_iter_to_iter(iter);
+               
+               Gtk::TreePath path(iter);
+               for(int i=path.get_depth();i;i--)
+               {
+                       int j;
+                       path=Gtk::TreePath(iter);
+                       for(j=i;j;j--)
+                               path.up();
+                       get_layer_tree_view().expand_row(path,false);
+               }
+               get_layer_tree_view().scroll_to_row(Gtk::TreePath(iter));
+               get_layer_tree_view().get_selection()->select(iter);
+       }
+}
+
+void
+LayerTree::select_all_children(Gtk::TreeModel::Children::iterator iter)
+{
+       get_layer_tree_view().get_selection()->select(iter);
+       if((bool)(*iter)[layer_model.children_lock])
+               return;
+       get_layer_tree_view().expand_row(layer_tree_store_->get_path(iter),false);
+       Gtk::TreeModel::Children children(iter->children());
+       for(iter=children.begin();iter!=children.end();++iter)
+               select_all_children(iter);
+}
+
+void
+LayerTree::select_all_children_layers(sinfg::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(layer_tree_store_->find_layer_row(layer,iter))
+               select_all_children(iter);
+}
+
+void
+LayerTree::select_layers(const LayerList &layer_list)
+{
+       LayerList::const_iterator iter;
+       for(iter = layer_list.begin(); iter != layer_list.end(); ++iter)
+               select_layer(*iter);
+}
+
+static inline void __layer_grabber(const Gtk::TreeModel::iterator& iter, LayerTree::LayerList* ret)
+{
+       const LayerTreeStore::Model layer_tree_model;
+       ret->push_back((Layer::Handle)(*iter)[layer_tree_model.layer]);
+}
+
+LayerTree::LayerList
+LayerTree::get_selected_layers()const
+{
+       Glib::RefPtr<Gtk::TreeSelection> selection=const_cast<Gtk::TreeView&>(get_layer_tree_view()).get_selection();
+
+       if(!selection)
+               return LayerList();
+
+       LayerList ret;
+
+       selection->selected_foreach_iter(
+               sigc::bind(
+                       sigc::ptr_fun(
+                               &__layer_grabber
+                       ),
+                       &ret
+               )
+       );
+
+       return ret;
+}
+
+sinfg::Layer::Handle
+LayerTree::get_selected_layer()const
+{
+       LayerList layers(get_selected_layers());
+
+       if(layers.empty())
+               return 0;
+
+       return *layers.begin();
+}
+
+void
+LayerTree::clear_selected_layers()
+{
+       get_layer_tree_view().get_selection()->unselect_all();
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+void
+LayerTree::set_show_timetrack(bool x)
+{
+       //column_time_track->set_visible(x);
+//     column_time_track->set_visible(false);
+       column_z_depth->set_visible(x);
+}
+
+void
+LayerTree::set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store)
+{
+       layer_tree_store_=layer_tree_store;
+       
+
+       if(false)
+       {
+               sorted_layer_tree_store_=Gtk::TreeModelSort::create(layer_tree_store);  
+       
+               sorted_layer_tree_store_->set_default_sort_func(sigc::ptr_fun(&studio::LayerTreeStore::z_sorter));
+       
+               //sorted_store->set_sort_func(model.time.index(),sigc::mem_fun(&studio::KeyframeTreeStore::time_sorter));
+               //sorted_store->set_sort_column_id(model.time.index(), Gtk::SORT_ASCENDING);
+               
+               get_layer_tree_view().set_model(sorted_layer_tree_store_);
+       }
+       else
+               get_layer_tree_view().set_model(layer_tree_store_);
+       
+       layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+
+       //layer_tree_store_->canvas_interface()->signal_dirty_preview().connect(sigc::mem_fun(*this,&studio::LayerTree::on_dirty_preview));
+       
+       layer_tree_store_->canvas_interface()->signal_time_changed().connect(
+               sigc::mem_fun(
+                       &param_tree_view(),
+                       &Gtk::Widget::queue_draw
+               )
+       );
+       if(!param_tree_store_)
+       {
+               param_tree_store_=LayerParamTreeStore::create(layer_tree_store_->canvas_interface(), this);
+               param_tree_view().set_model(param_tree_store_);
+       }
+       
+/*     if(cellrenderer_time_track && layer_tree_store_ && layer_tree_store_->canvas_interface())
+       {
+               cellrenderer_time_track->set_canvas_interface(layer_tree_store_->canvas_interface());
+       }
+*/
+}
+
+void
+LayerTree::set_time_adjustment(Gtk::Adjustment &adjustment)
+{
+       //cellrenderer_time_track->set_adjustment(adjustment);
+       adjustment.signal_value_changed().connect(sigc::mem_fun(param_tree_view(),&Gtk::TreeView::queue_draw));
+       adjustment.signal_changed().connect(sigc::mem_fun(param_tree_view(),&Gtk::TreeView::queue_draw));
+}
+
+void
+LayerTree::on_dirty_preview()
+{
+/*
+       if(quick_layer && !disable_amount_changed_signal)
+       {
+               layer_amount_hscale->set_sensitive(true);
+               disable_amount_changed_signal=true;
+               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+               disable_amount_changed_signal=false;
+               if(quick_layer->get_param("blend_method").is_valid())
+               {
+                       blend_method_widget.set_sensitive(true);
+                       disable_amount_changed_signal=true;
+                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+                       disable_amount_changed_signal=false;
+               }
+       }
+*/
+}
+
+void
+LayerTree::on_selection_changed()
+{
+       sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+       
+       Gtk::TreeIter iter;
+       if(last_top_selected_layer && !layer_tree_store_->find_layer_row(last_top_selected_layer,iter))
+       {
+               if(layer_list.empty())
+               {
+                       last_top_selected_layer=0;
+                       layer_tree_view_->get_selection()->select(last_top_selected_path);
+                       return;
+               }
+       }
+
+
+       {
+               if(!layer_list.empty())
+               {
+                       last_top_selected_layer=layer_list.front();
+                       last_top_selected_path=*layer_tree_view_->get_selection()->get_selected_rows().begin();
+               }
+               else
+               {
+                       last_top_selected_layer=0;
+               }
+       }
+       
+       
+       if(layer_list.empty())
+       {
+               button_raise->set_sensitive(false);
+               button_lower->set_sensitive(false);
+               button_duplicate->set_sensitive(false);
+               button_delete->set_sensitive(false);
+               layer_amount_hscale->set_sensitive(false);
+               blend_method_widget.set_sensitive(false);
+               return;
+       }
+
+       button_raise->set_sensitive(true);
+       button_lower->set_sensitive(true);
+       button_duplicate->set_sensitive(true);
+       button_delete->set_sensitive(true);
+       
+       if(layer_list.size()==1 && (*layer_list.begin())->get_param("amount").is_valid()&& (*layer_list.begin())->get_param("amount").same_as(Real()))
+       {
+               quick_layer=*layer_list.begin();
+       }
+       else
+               quick_layer=0;
+       
+       if(quick_layer)
+       {
+               layer_amount_hscale->set_sensitive(true);
+               disable_amount_changed_signal=true;
+               layer_amount_adjustment_.set_value(quick_layer->get_param("amount").get(Real()));
+               disable_amount_changed_signal=false;
+               if(quick_layer->get_param("blend_method").is_valid())
+               {
+                       blend_method_widget.set_sensitive(true);
+                       disable_amount_changed_signal=true;
+                       blend_method_widget.set_value(quick_layer->get_param("blend_method"));
+                       disable_amount_changed_signal=false;
+               }
+               else
+                       blend_method_widget.set_sensitive(false);               
+       }
+       else
+       {
+               layer_amount_hscale->set_sensitive(false);      
+               blend_method_widget.set_sensitive(false);
+       }
+}
+
+
+void
+LayerTree::on_blend_method_changed()
+{
+       if(disable_amount_changed_signal)
+               return;
+       if(!quick_layer)
+               return;
+       
+       if(quick_layer->get_param("blend_method").is_valid())
+       {
+               disable_amount_changed_signal=true;
+               signal_edited_value()(sinfgapp::ValueDesc(quick_layer,"blend_method"),blend_method_widget.get_value());
+               disable_amount_changed_signal=false;
+       }
+}
+
+void
+LayerTree::on_amount_value_changed()
+{
+       if(disable_amount_changed_signal)
+               return;
+       if(!quick_layer)
+               return;
+       
+       disable_amount_changed_signal=true;
+       signal_edited_value()(sinfgapp::ValueDesc(quick_layer,"amount"),sinfg::ValueBase(layer_amount_adjustment_.get_value()));
+       disable_amount_changed_signal=false;
+}
+
+
+void
+LayerTree::on_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(param_tree_view().get_model()->get_iter(path));
+       if(!row)
+               return;
+       row[param_model.value]=value;
+       //signal_edited_value()(row[param_model.value_desc],value);
+}
+
+/*
+void
+LayerTree::on_layer_toggle(const Glib::ustring& path_string)
+{
+       Gtk::TreePath path(path_string);
+
+       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+
+       signal_layer_toggle()(row[layer_model.layer]);
+}
+*/
+
+void
+LayerTree::on_waypoint_clicked(const Glib::ustring &path_string, sinfg::Waypoint waypoint,int button)
+{
+       Gtk::TreePath path(path_string);
+       
+       const Gtk::TreeRow row = *(param_tree_view().get_model()->get_iter(path));
+       if(!row)
+               return;
+       
+       signal_waypoint_clicked()(static_cast<sinfgapp::ValueDesc>(row[param_model.value_desc]),waypoint,button);
+}
+
+bool
+LayerTree::on_layer_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_layer_tree_view().get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+                       
+                       //if(column->get_first_cell_renderer()==cellrenderer_time_track)
+                       //      return signal_layer_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                       //else
+                               if(column->get_first_cell_renderer()==cellrenderer_value)
+                               return signal_layer_user_click()(event->button.button,row,COLUMNID_VALUE);
+                       else
+                               return signal_layer_user_click()(event->button.button,row,COLUMNID_NAME);
+                       
+               }
+               break;
+               
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!get_layer_tree_view().get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       
+                       if(!get_layer_tree_view().get_model()->get_iter(path))
+                               break;
+                       
+                       Gtk::TreeRow row = *(get_layer_tree_view().get_model()->get_iter(path));
+                       
+                       /*
+                       if(cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               // Movement on TimeLine
+                               return true;
+                       }
+                       else
+                               */
+                       if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+
+bool
+LayerTree::on_param_tree_event(GdkEvent *event)
+{
+    switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!param_tree_view().get_path_at_pos(
+                               int(event->button.x),int(event->button.y),      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       const Gtk::TreeRow row = *(param_tree_view().get_model()->get_iter(path));
+                       
+/*                     if(column && column->get_first_cell_renderer()==cellrenderer_time_track)
+                       {
+                               Gdk::Rectangle rect;
+                               param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                               //return signal_param_user_click()(event->button.button,row,COLUMNID_TIME_TRACK);
+                       }
+                       else 
+*/                     {
+                               if(event->button.button==3)
+                               {
+                                       LayerList layer_list(get_selected_layers());
+                                       if(layer_list.size()<=1)
+                                       {
+                                               sinfgapp::ValueDesc value_desc(row[param_model.value_desc]);
+                                               Gtk::Menu* menu(manage(new Gtk::Menu()));                                       
+                                               App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc,0.5f);
+                                               menu->popup(event->button.button,gtk_get_current_event_time());
+                                               return true;
+                                       }
+                                       Gtk::Menu* menu(manage(new Gtk::Menu()));                                       
+                                       std::list<sinfgapp::ValueDesc> value_desc_list;
+                                       ParamDesc param_desc(row[param_model.param_desc]);
+                                       for(;!layer_list.empty();layer_list.pop_back())
+                                               value_desc_list.push_back(sinfgapp::ValueDesc(layer_list.back(),param_desc.get_name()));
+                                       App::get_instance(param_tree_store_->canvas_interface()->get_canvas())->make_param_menu(menu,param_tree_store_->canvas_interface()->get_canvas(),value_desc_list);
+                                       menu->popup(event->button.button,gtk_get_current_event_time());
+                                       return true;
+                               }
+                               else
+                               {
+                                       if(column->get_first_cell_renderer()==cellrenderer_value)
+                                               return signal_param_user_click()(event->button.button,row,COLUMNID_VALUE);
+                                       else
+                                               return signal_param_user_click()(event->button.button,row,COLUMNID_NAME);
+                               }
+                       }
+               }
+               break;
+               
+       case GDK_MOTION_NOTIFY:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!param_tree_view().get_path_at_pos(
+                               (int)event->motion.x,(int)event->motion.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       
+                       if(!param_tree_view().get_model()->get_iter(path))
+                               break;
+                       
+                       Gtk::TreeRow row = *(param_tree_view().get_model()->get_iter(path));
+                       
+/*                     if((event->motion.state&GDK_BUTTON1_MASK ||event->motion.state&GDK_BUTTON3_MASK) && column && cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               Gdk::Rectangle rect;
+                               param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               param_tree_view().queue_draw();
+                               //param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+                       }
+                       else
+*/                     if(last_tooltip_path.get_depth()<=0 || path!=last_tooltip_path)
+                       {
+                               tooltips_.unset_tip(*this);
+                               Glib::ustring tooltips_string(row[layer_model.tooltip]);
+                               last_tooltip_path=path;
+                               if(!tooltips_string.empty())
+                               {
+                                       tooltips_.set_tip(*this,tooltips_string);
+                                       tooltips_.force_window();
+                               }
+                       }
+               }
+               break;
+       case GDK_BUTTON_RELEASE:
+               {
+                       Gtk::TreeModel::Path path;
+                       Gtk::TreeViewColumn *column;
+                       int cell_x, cell_y;
+                       if(!param_tree_view().get_path_at_pos(
+                               (int)event->button.x,(int)event->button.y,      // x, y
+                               path, // TreeModel::Path&
+                               column, //TreeViewColumn*&
+                               cell_x,cell_y //int&cell_x,int&cell_y
+                               )
+                       ) break;
+                       
+                       if(!param_tree_view().get_model()->get_iter(path))
+                               break;
+                       
+                       Gtk::TreeRow row = *(param_tree_view().get_model()->get_iter(path));
+                       
+/*                     if(column && cellrenderer_time_track==column->get_first_cell_renderer())
+                       {
+                               Gdk::Rectangle rect;
+                               param_tree_view().get_cell_area(path,*column,rect);
+                               cellrenderer_time_track->property_value_desc()=row[param_model.value_desc];
+                               cellrenderer_time_track->property_canvas()=row[param_model.canvas];
+                               cellrenderer_time_track->activate(event,*this,path.to_string(),rect,rect,Gtk::CellRendererState());
+                               param_tree_view().queue_draw();
+                               param_tree_view().queue_draw_area(rect.get_x(),rect.get_y(),rect.get_width(),rect.get_height());
+                               return true;
+               
+                       }
+*/
+               }
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+void
+LayerTree::on_raise_pressed()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       
+       {
+               sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+               sinfgapp::SelectionManager::LayerList::iterator iter;
+       
+               for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                       param_list.add("layer",Layer::Handle(*iter));
+       }
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_raise"));
+       action->set_param_list(param_list);
+       layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+}
+
+void
+LayerTree::on_lower_pressed()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       
+       {
+               sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+               sinfgapp::SelectionManager::LayerList::iterator iter;
+       
+               for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                       param_list.add("layer",Layer::Handle(*iter));
+       }
+       
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_lower"));
+       action->set_param_list(param_list);
+       layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+}
+
+void
+LayerTree::on_duplicate_pressed()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       
+       {
+               sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+               sinfgapp::SelectionManager::LayerList::iterator iter;
+       
+               for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                       param_list.add("layer",Layer::Handle(*iter));
+       }
+       
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_duplicate"));
+       action->set_param_list(param_list);
+       layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+}
+
+void
+LayerTree::on_delete_pressed()
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",layer_tree_store_->canvas_interface()->get_time());
+       param_list.add("canvas",layer_tree_store_->canvas_interface()->get_canvas());
+       param_list.add("canvas_interface",layer_tree_store_->canvas_interface());
+       
+       {
+               sinfgapp::SelectionManager::LayerList layer_list(get_selection_manager()->get_selected_layers());
+               sinfgapp::SelectionManager::LayerList::iterator iter;
+       
+               for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+                       param_list.add("layer",Layer::Handle(*iter));
+       }
+       
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_remove"));
+       action->set_param_list(param_list);
+       layer_tree_store_->canvas_interface()->get_instance()->perform_action(action);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*
+void
+LayerTree::on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>&context, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       sinfg::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       sinfg::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       sinfg::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       DEBUGPOINT();
+
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(get_selection()
+       Gtk::TreeRow row = *(get_selection()->get_selected());
+       DEBUGPOINT();
+
+       if(sinfg::String(gdk_atom_name(selection_data->target))=="LAYER" && (bool)row[model.is_layer])
+       {
+               DEBUGPOINT();
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+               selection_data.set(8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+               return;
+       }
+       DEBUGPOINT();
+}
+
+void
+LayerTree::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       sinfg::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       sinfg::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       sinfg::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       sinfg::info("Dropped x=%d, y=%d",x,y);
+       bool success=false;
+       bool dropped_on_specific_row=false;
+       
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(!get_path_at_pos(
+               x,y,    // x, y
+               path, // TreeModel::Path&
+               column, //TreeViewColumn*&
+               cell_x,cell_y //int&cell_x,int&cell_y
+               )
+       )
+       {
+               dropped_on_specific_row=false;
+       }
+       else
+               dropped_on_specific_row=true;
+       
+       Gtk::TreeRow row = *(get_model()->get_iter(path));
+
+       
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               if(sinfg::String(selection_data.get_data_type())=="LAYER")do
+               {
+                       Layer::Handle src(*reinterpret_cast<Layer**>(selection_data.get_data()));
+                       assert(src);
+                       
+                       Canvas::Handle dest_canvas;
+                       Layer::Handle dest_layer;
+                       
+                       if(dropped_on_specific_row)
+                       {
+                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                               dest_layer=(Layer::Handle)(row[model.layer]);
+                               assert(dest_canvas);
+                       }
+                       else
+                               dest_canvas=layer_tree_store_->canvas_interface()->get_canvas();
+                       
+                       // In this case, we are just moving.
+                       if(dest_canvas==src->get_canvas())
+                       {
+                               if(!dest_layer || dest_layer==src)
+                                       break;
+                               
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_move"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",layer_tree_store_->canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_canvas->get_depth(dest_layer));
+                               if(layer_tree_store_->canvas_interface()->get_instance()->perform_action(action))
+                                       success=true;
+                               else
+                                       success=false;
+                               break;
+                       }
+               }while(0);
+       }
+       
+       // Finish the drag
+       context->drag_finish(success, false, time);
+}
+*/
+
+/*bool
+LayerTree::on_drag_motion(const Glib::RefPtr<Gdk::DragContext>& context,int x, int    y, guint    time)
+{
+       return get_layer_tree_view().on_drag_motion(context,x,y,time);
+}
+
+void
+LayerTree::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, Gtk::SelectionData& selection_data, guint info, guint time)
+{
+       get_layer_tree_view().on_drag_data_received(context,x,y,selection_data,info,time);
+*/
+/*
+       if(context->gobj()->source_window==context->gobj()->dest_window)
+       {
+               Gtk::TreeView::on_drag_data_received(context,x,y,selection_data,info,time);
+               return;
+       }
+
+       Gtk::TreeModel::Path path;
+       Gtk::TreeViewColumn *column;
+       int cell_x, cell_y;
+       if(!get_path_at_pos(
+               x,y,    // x, y
+               path, // TreeModel::Path&
+               column, //TreeViewColumn*&
+               cell_x,cell_y //int&cell_x,int&cell_y
+               )
+       )
+       {
+               context->drag_finish(false, false, time);
+       }
+       
+       if(layer_tree_store_->row_drop_possible(path,selection_data))
+       {
+               if(layer_tree_store_->drag_data_received(path,selection_data))
+                       context->drag_finish(true, false, time);
+       }
+       context->drag_finish(false, false, time);
+}
+*/
diff --git a/synfig-studio/trunk/src/gtkmm/layertree.h b/synfig-studio/trunk/src/gtkmm/layertree.h
new file mode 100644 (file)
index 0000000..b0e0f98
--- /dev/null
@@ -0,0 +1,254 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertree.h
+**     \brief Template Header
+**
+**     $Id: layertree.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_LAYERTREE_H
+#define __SINFG_STUDIO_LAYERTREE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scale.h>
+#include <gtkmm/button.h>
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "layertreestore.h"
+#include "layerparamtreestore.h"
+#include <sinfg/valuenode_animated.h>
+
+#include "widget_value.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class TreeModelSort; }; 
+
+namespace studio {
+
+class CellRenderer_TimeTrack;
+class CellRenderer_ValueBase;
+
+class LayerTree : public Gtk::Table
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef studio::ColumnID ColumnID;
+/*     enum ColumnID
+       {
+               COLUMNID_NAME,
+               COLUMNID_VALUE,
+               COLUMNID_TIME_TRACK,
+               
+               COLUMNID_END                    //!< \internal
+       };
+*/
+       typedef std::list<sinfg::Layer::Handle> LayerList;
+       
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       //LayerTreeStore::Model model;
+
+       LayerTreeStore::Model layer_model;
+       LayerParamTreeStore::Model param_model;
+
+       sinfg::Layer::Handle last_top_selected_layer;
+       Gtk::TreePath last_top_selected_path;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Gtk::Tooltips tooltips_;
+       Gtk::TreePath last_tooltip_path;
+
+
+
+       Gtk::TreeView* layer_tree_view_;
+
+       Gtk::TreeView* param_tree_view_;
+
+       
+
+       Gtk::HBox *hbox;
+
+       Gtk::Adjustment layer_amount_adjustment_;
+
+       Gtk::HScale *layer_amount_hscale;
+
+       sinfg::Layer::Handle quick_layer;
+
+       Glib::RefPtr<LayerTreeStore> layer_tree_store_;
+
+       Glib::RefPtr<LayerParamTreeStore> param_tree_store_;
+       
+       Glib::RefPtr<Gtk::TreeModelSort> sorted_layer_tree_store_;
+
+//     CellRenderer_TimeTrack *cellrenderer_time_track;
+
+       Gtk::TreeView::Column* column_time_track;
+
+       Gtk::TreeView::Column* column_z_depth;
+
+       CellRenderer_ValueBase *cellrenderer_value;
+
+       sigc::signal<void,sinfg::Layer::Handle> signal_layer_toggle_;
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::ValueBase> signal_edited_value_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_layer_user_click_;
+
+       sigc::signal<bool, int, Gtk::TreeRow, ColumnID> signal_param_user_click_;
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::Waypoint,int> signal_waypoint_clicked_;
+
+       bool disable_amount_changed_signal;
+
+       Gtk::Button *button_raise;
+       Gtk::Button *button_lower;
+       Gtk::Button *button_duplicate;
+       Gtk::Button *button_delete;
+
+       Widget_ValueBase blend_method_widget;
+       
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       Gtk::Widget* create_layer_tree();
+       Gtk::Widget* create_param_tree();
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void on_edited_value(const Glib::ustring&path_string,sinfg::ValueBase value);
+
+       void on_layer_toggle(const Glib::ustring& path_string);
+
+       void on_waypoint_clicked(const Glib::ustring &, sinfg::Waypoint, int button);
+
+       void on_waypoint_changed( sinfg::Waypoint waypoint , sinfg::ValueNode::Handle value_node);
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       bool on_param_tree_event(GdkEvent *event);
+
+       void on_selection_changed();
+
+       void on_dirty_preview();
+
+       void on_amount_value_changed();
+
+       void on_blend_method_changed();
+
+public:
+       
+       void on_raise_pressed();
+
+       void on_lower_pressed();
+
+       void on_duplicate_pressed();
+
+       void on_delete_pressed();
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       //Gtk::TreeView* get_param_tree_view() { return param_tree_view_; }
+       Gtk::TreeView& param_tree_view() { return *param_tree_view_; }
+       Gtk::HBox& get_hbox() { return *hbox; }
+
+       Gtk::TreeView& get_layer_tree_view() { return *layer_tree_view_; }
+       Gtk::TreeView& get_param_tree_view() { return *param_tree_view_; }
+
+       const Gtk::TreeView& get_layer_tree_view()const { return *layer_tree_view_; }
+       const Gtk::TreeView& get_param_tree_view()const { return *param_tree_view_; }
+       
+       Glib::RefPtr<Gtk::TreeSelection> get_selection() { return get_layer_tree_view().get_selection(); }
+       Glib::SignalProxy1< bool,GdkEvent* >  signal_event () { return get_layer_tree_view().signal_event(); }
+       
+       LayerTree();
+       ~LayerTree();
+
+       void set_model(Glib::RefPtr<LayerTreeStore> layer_tree_store_);
+
+       void set_time_adjustment(Gtk::Adjustment &adjustment);
+
+       void set_show_timetrack(bool x=true);
+
+       //! Signal called when layer is toggled.
+       sigc::signal<void,sinfg::Layer::Handle>& signal_layer_toggle() { return signal_layer_toggle_; }
+
+       //! Signal called with a value has been edited.
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::ValueBase>& signal_edited_value() { return signal_edited_value_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_layer_user_click() { return signal_layer_user_click_; }
+
+       sigc::signal<bool,int, Gtk::TreeRow, ColumnID>& signal_param_user_click() { return signal_param_user_click_; }
+
+       sigc::signal<void,sinfgapp::ValueDesc,sinfg::Waypoint,int>& signal_waypoint_clicked() { return signal_waypoint_clicked_; }
+
+       etl::handle<sinfgapp::SelectionManager> get_selection_manager() { return layer_tree_store_->canvas_interface()->get_selection_manager(); }
+       
+       
+       
+       void select_layer(sinfg::Layer::Handle layer);
+       void select_layers(const LayerList& layer_list);
+       void select_all_children_layers(sinfg::Layer::Handle layer);
+       void select_all_children(Gtk::TreeModel::Children::iterator iter);
+       LayerList get_selected_layers()const;
+       sinfg::Layer::Handle get_selected_layer()const;
+       void clear_selected_layers();
+
+}; // END of LayerTree
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/layertreestore.cpp b/synfig-studio/trunk/src/gtkmm/layertreestore.cpp
new file mode 100644 (file)
index 0000000..4aac862
--- /dev/null
@@ -0,0 +1,1080 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertreestore.cpp
+**     \brief Template File
+**
+**     $Id: layertreestore.cpp,v 1.2 2005/01/12 07:03:42 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layertreestore.h"
+#include "iconcontroler.h"
+#include <gtkmm/button.h>
+#include <sinfg/paramdesc.h>
+#include <sinfgapp/action.h>
+#include <sinfgapp/instance.h>
+#include "app.h"
+#include "instance.h"
+#include "iconcontroler.h"
+#include <sinfgapp/action_system.h>
+
+#include <gtk/gtkversion.h>
+#include <ETL/clock>
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static LayerTreeStore::Model& ModelHack()
+{
+       static LayerTreeStore::Model* model(0);
+       if(!model)model=new LayerTreeStore::Model;
+       return *model;
+}
+
+LayerTreeStore::LayerTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore                  (ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+       layer_icon=Gtk::Button().render_icon(Gtk::StockID("sinfg-layer"),Gtk::ICON_SIZE_SMALL_TOOLBAR);
+
+       // Connect Signals to Terminals
+       canvas_interface()->signal_layer_status_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_status_changed));
+       canvas_interface()->signal_layer_lowered().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_lowered));
+       canvas_interface()->signal_layer_raised().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_raised));
+       canvas_interface()->signal_layer_removed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_removed));
+       canvas_interface()->signal_layer_inserted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_inserted));
+       canvas_interface()->signal_layer_moved().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_moved));
+       //canvas_interface()->signal_layer_param_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_param_changed));
+       canvas_interface()->signal_layer_new_description().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_layer_new_description));
+
+       canvas_interface()->signal_time_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::refresh));
+
+       //canvas_interface()->signal_value_node_changed().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_changed));
+       //canvas_interface()->signal_value_node_added().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_added));
+       //canvas_interface()->signal_value_node_deleted().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_deleted));
+       //canvas_interface()->signal_value_node_replaced().connect(sigc::mem_fun(*this,&studio::LayerTreeStore::on_value_node_replaced));
+
+       set_default_sort_func(sigc::ptr_fun(index_sorter));
+       
+//     rebuild();
+}
+
+LayerTreeStore::~LayerTreeStore()
+{
+       sinfg::info("LayerTreeStore::~LayerTreeStore()q: Deleted");
+
+}
+
+int
+LayerTreeStore::z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+       
+       float diff((float)(*rhs)[model.z_depth]-(float)(*lhs)[model.z_depth]);
+
+       if(diff<0)
+               return -1;
+       if(diff>0)
+               return 1;
+       return 0;
+}
+
+int
+LayerTreeStore::index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs)
+{
+       const Model model;
+       
+       return ((int)(*rhs)[model.index]-(int)(*lhs)[model.index]);
+}
+
+bool
+LayerTreeStore::search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring& x,const TreeModel::iterator& iter)
+{
+       const Model model;
+
+       Glib::ustring substr(x.uppercase());
+       Glib::ustring label((*iter)[model.label]);
+       label=label.uppercase();
+               
+       return label.find(substr)==Glib::ustring::npos;
+}
+
+
+Glib::RefPtr<LayerTreeStore>
+LayerTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<LayerTreeStore>(new LayerTreeStore(canvas_interface_));
+}
+
+void
+LayerTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column==model.index.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<int> x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               x.set(layer->get_depth());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.z_depth.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<float> x;
+               g_value_init(x.gobj(),x.value_type());
+               
+               x.set(layer->get_z_depth(canvas_interface()->get_time())*1.0001+layer->get_depth());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.children_lock.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+               x.set(false);
+               
+               ValueBase v(layer->get_param("children_lock"));
+               if(v.same_as(bool()))
+                       x.set(v.get(bool()));
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.label.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               if(!layer->get_description().empty())
+                       x.set(layer->get_description());
+               else
+                       x.set(layer->get_local_name());
+               
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.tooltip.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_local_name());
+               
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.canvas.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<Canvas::Handle> x;
+               g_value_init(x.gobj(),x.value_type());
+
+
+               x.set(layer->get_canvas());
+               
+               g_value_init(value.gobj(),x.value_type());
+               //g_value_copy(x.gobj(),value.gobj());
+               value=x;
+       }
+       else
+       if(column==model.active.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+
+               if(!layer)return;
+
+               Glib::Value<bool> x;
+               g_value_init(x.gobj(),x.value_type());
+
+               x.set(layer->active());
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+       if(column==model.icon.index())
+       {
+               sinfg::Layer::Handle layer((*iter)[model.layer]);
+               if(!layer)return;
+
+               Glib::Value<Glib::RefPtr<Gdk::Pixbuf> > x;
+               g_value_init(x.gobj(),x.value_type());
+
+               //x.set(layer_icon);
+               x.set(get_tree_pixbuf_layer(layer->get_name()));
+               
+               g_value_init(value.gobj(),x.value_type());
+               g_value_copy(x.gobj(),value.gobj());
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+LayerTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       //if(!iterator_sane(row))
+       //      return;
+
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("LayerTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       try
+       {
+               if(column==model.label.index())
+               {
+                       Glib::Value<Glib::ustring> x;
+                       g_value_init(x.gobj(),model.label.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+                       if(!layer)
+                               return;
+                       sinfg::String new_desc(x.get());
+                       
+                       if(new_desc==layer->get_local_name())
+                               new_desc=sinfg::String();
+
+                       if(new_desc==layer->get_description())
+                               return;
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_set_desc"));
+                       
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_description",sinfg::String(x.get()));
+                       
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else
+               if(column==model.active.index())
+               {
+                       sinfg::Layer::Handle layer((*iter)[model.layer]);
+                       
+                       if(!layer)return;
+
+                       Glib::Value<bool> x;
+                       g_value_init(x.gobj(),model.active.type());
+                       g_value_copy(value.gobj(),x.gobj());
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_activate"));
+                       
+                       if(!action)
+                               return;
+                       
+                       action->set_param("canvas",canvas_interface()->get_canvas());
+                       action->set_param("canvas_interface",canvas_interface());
+                       action->set_param("layer",layer);
+                       action->set_param("new_status",bool(x.get()));
+                       
+                       canvas_interface()->get_instance()->perform_action(action);
+                       return;
+               }
+               else
+                       Gtk::TreeStore::set_value_impl(iter,column, value);
+
+       }
+       catch(std::exception x)
+       {
+               g_warning(x.what());
+       }       
+}
+
+
+
+
+bool
+LayerTreeStore::row_draggable_vfunc (const TreeModel::Path& path)const
+{
+       //if(!get_iter(path)) return false;
+//     Gtk::TreeModel::Row row(*get_iter(path));
+       
+       return true;
+//     return (bool)true;
+}
+
+bool
+LayerTreeStore::drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const
+{
+       if(!const_cast<LayerTreeStore*>(this)->get_iter(path)) return false;
+       //sinfg::info("Dragged data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("Dragged data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("Dragged selection=\"%s\"",gdk_atom_name(selection_data->selection));
+
+       Gtk::TreeModel::Row row(*const_cast<LayerTreeStore*>(this)->get_iter(path));
+
+       if((bool)true)
+       {
+               Layer* layer(((Layer::Handle)row[model.layer]).get());
+               assert(layer);
+               bool included(false);
+               
+               //gtk_selection_data_set (selection_data, gdk_atom_intern("LAYER",false), 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+
+               std::vector<Layer*> layers;
+               // The following is a hack for multiple row DND
+               {
+                       sinfgapp::SelectionManager::LayerList bleh(get_canvas_interface()->get_selection_manager()->get_selected_layers());
+                       if(bleh.empty())
+                       {
+                               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layer), sizeof(layer));
+                               return true;
+                       }
+                       while(!bleh.empty())
+                       {
+                               if(bleh.back().get()==layer)
+                                       included=true;
+                               layers.push_back(bleh.back().get());
+                               bleh.pop_back();
+                       }
+               }
+               if(!included)
+                       layers.push_back(layer);
+               selection_data.set("LAYER", 8, reinterpret_cast<const guchar*>(&layers.front()), sizeof(void*)*layers.size());
+               
+               return true;
+       }
+       return false;
+}
+
+bool
+LayerTreeStore::drag_data_delete_vfunc (const TreeModel::Path& path)
+{
+       return true;
+}
+
+bool
+LayerTreeStore::row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const
+{
+       //if(!const_cast<LayerTreeStore*>(this)->get_iter(dest)) return false;
+
+       //sinfg::info("possible_drop -- data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("possible_drop -- data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("possible_drop -- selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       
+       //Gtk::TreeModel::Row row(*get_iter(dest));
+
+       if(sinfg::String(selection_data.get_data_type())=="LAYER" && (bool)true)
+       {
+               //Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+               //assert(src);
+
+               //return true;
+               TreeModel::Path dest_parent(dest);
+               if(!dest_parent.up() || dest.get_depth()==1)
+               {
+                       //row=(*get_iter(dest));
+                       //dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                       return true;
+               }
+               else
+               {
+                       if((bool)const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))
+                               return (bool)(Canvas::Handle)(*const_cast<LayerTreeStore*>(this)->get_iter(dest_parent))[model.contained_canvas];
+                       else
+                               return false;
+               }
+       }
+       return false;
+}
+
+bool
+LayerTreeStore::drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
+{
+       
+       //if(!dest_parent.up() || !get_iter(dest)) return false;
+               
+       bool ret=false;
+       int i(0);
+       
+
+       //sinfg::info("Dropped data of type \"%s\"",selection_data.get_data_type());
+       //sinfg::info("Dropped data of target \"%s\"",gdk_atom_name(selection_data->target));
+       //sinfg::info("Dropped selection=\"%s\"",gdk_atom_name(selection_data->selection));
+       sinfgapp::Action::PassiveGrouper passive_grouper(canvas_interface()->get_instance().get(),_("Move Layers"));
+       
+       // Save the selection data
+       sinfgapp::SelectionManager::LayerList selected_layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       if ((selection_data.get_length() >= 0) && (selection_data.get_format() == 8))
+       {
+               Gtk::TreeModel::Row row;
+               Canvas::Handle dest_canvas;
+               
+               int dest_layer_depth=dest.back();
+               
+               TreeModel::Path dest_parent(dest);
+               if(!dest_parent.up() || !get_iter(dest_parent))
+               {
+                       TreeModel::Path dest(dest);
+                       if(!get_iter(dest))
+                               dest.prev();
+
+                       if(!get_iter(dest))
+                               return false;
+
+                       {
+                               row=(*get_iter(dest));
+                               dest_canvas=(Canvas::Handle)(row[model.canvas]);
+                       }
+               }
+               else
+               {
+                       row=(*get_iter(dest_parent));
+                       dest_canvas=row[model.contained_canvas];
+               }
+               
+               assert(dest_canvas);
+               
+               Layer::Handle dest_layer(row[model.layer]);
+
+               if(sinfg::String(selection_data.get_data_type())=="LAYER")for(unsigned int i=0;i<selection_data.get_length()/sizeof(void*);i++)
+               {
+                       //sinfg::info("dest_layer_depth=%d",dest_layer_depth);
+                       
+                       Layer::Handle src(reinterpret_cast<Layer**>(const_cast<guint8*>(selection_data.get_data()))[i]);
+                       assert(src);
+                       if(dest_layer==src)
+                               continue;
+                       
+                       if(dest_canvas==src->get_canvas() && src->get_depth()<dest_layer_depth)
+                       {
+                               dest_layer_depth--;
+                       }
+                       
+                       // In this case, we are just moving.
+//                     if(dest_canvas==src->get_canvas())
+                       {
+                               //if(dest_canvas==src->get_canvas() && dest_layer_depth && dest_layer_depth>src->get_depth())
+                               //      dest_layer_depth--;
+                               if(dest_canvas==src->get_canvas() && dest_layer_depth==src->get_depth())
+                                       continue;
+                               
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_move"));
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               action->set_param("new_index",dest_layer_depth);
+                               action->set_param("dest_canvas",dest_canvas);
+                               if(canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       //DEBUGPOINT();
+                                       ret=true;
+                               }
+                               else
+                               {
+                                       //DEBUGPOINT();
+                                       passive_grouper.cancel();
+                                       return false;
+                               }
+                               continue;
+                       }
+                       /*else // In this case we need to remove and then add
+                       {                               
+                               
+                               sinfgapp::Action::Handle action;
+                               action=sinfgapp::Action::create("layer_remove");
+                               action->set_param("canvas",Canvas::Handle(src->get_canvas()));
+                               if(!action->set_param("canvas_interface",App::get_instance(src->get_canvas())->find_canvas_interface(src->get_canvas())))
+                                       action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("layer",src);
+                               if(!canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       passive_grouper.cancel();
+                                       ret=false;
+                                       return false;
+                               }
+
+                               action=sinfgapp::Action::create("layer_add");
+                               action->set_param("canvas",dest_canvas);
+                               action->set_param("canvas_interface",canvas_interface());
+                               action->set_param("new",src);
+                               if(!canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       passive_grouper.cancel();
+                                       ret=false;
+                                       return false;
+                               }
+
+                               if(dest_layer_depth!=0)
+                               {
+                                       action=sinfgapp::Action::create("layer_move");
+                                       action->set_param("canvas",dest_canvas);
+                                       action->set_param("canvas_interface",canvas_interface());
+                                       action->set_param("layer",src);
+                                       action->set_param("new_index",dest_layer_depth);
+                                       if(!canvas_interface()->get_instance()->perform_action(action))
+                                       {
+                                               passive_grouper.cancel();
+                                               ret=false;
+                                               return false;
+                                       }
+                               }                               
+                               ret=true;
+                       }
+                       */
+               }
+       }
+       sinfg::info("I suposidly moved %d layers",i);
+
+       // Reselect the previously selected layers
+       canvas_interface()->get_selection_manager()->set_selected_layers(selected_layer_list);
+       
+       return ret;
+}
+
+
+
+
+
+
+
+void
+LayerTreeStore::rebuild()
+{
+       //etl::clock timer;timer.reset();
+
+       //sinfg::warning("---------rebuilding layer table---------");
+       // Save the selection data
+       sinfgapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+
+       // Clear out the current list
+       clear();
+               
+       // Go ahead and and add all the layers
+       std::for_each(
+               canvas_interface()->get_canvas()->rbegin(), canvas_interface()->get_canvas()->rend(),
+               sigc::mem_fun(*this, &studio::LayerTreeStore::on_layer_added)
+       );
+
+       // Reselect the previously selected layers
+       if(!layer_list.empty())
+               canvas_interface()->get_selection_manager()->set_selected_layers(layer_list);
+
+       //sinfg::info("LayerTreeStore::rebuild() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh()
+{
+       etl::clock timer;timer.reset();
+
+       Gtk::TreeModel::Children children_(children());
+       
+       Gtk::TreeModel::Children::iterator iter;
+       
+       if(!children_.empty())
+               for(iter = children_.begin(); iter && iter != children_.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+       //sinfg::info("LayerTreeStore::refresh() took %f seconds",float(timer()));
+}
+
+void
+LayerTreeStore::refresh_row(Gtk::TreeModel::Row &row)
+{
+       Layer::Handle layer=row[model.layer];
+       /*
+       {
+               row[model.name] = layer->get_local_name();      
+               if(layer->get_description().empty())
+               {
+                       row[model.label] = layer->get_local_name();
+                       row[model.tooltip] = Glib::ustring("Layer");
+               }
+               else
+               {
+                       row[model.label] = layer->get_description();    
+                       row[model.tooltip] = layer->get_local_name();
+               }
+       }
+       */
+       
+       if(layer->dynamic_param_list().count("z_depth"))
+               row[model.z_depth]=Time::begin();
+       //      row_changed(get_path(row),row);                 
+       
+       Gtk::TreeModel::Children children = row.children();
+       Gtk::TreeModel::Children::iterator iter;
+
+       if(!children.empty())
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       Gtk::TreeRow row=*iter;
+                       refresh_row(row);
+               }
+}
+
+
+void
+LayerTreeStore::set_row_layer(Gtk::TreeRow &row,sinfg::Layer::Handle &handle)
+{
+       //row[model.id] = handle->get_name();
+       //row[model.name] = handle->get_local_name();   
+       /*if(handle->get_description().empty())
+       {
+               //row[model.label] = handle->get_local_name();
+               row[model.tooltip] = Glib::ustring("Layer");
+       }
+       else
+       {
+               //row[model.label] = handle->get_description(); 
+               row[model.tooltip] = handle->get_local_name();
+       }*/
+       
+       //row[model.active] = handle->active();
+       row[model.layer] = handle;
+       //row[model.canvas] = handle->get_canvas();
+       //row[model.icon] = layer_icon; 
+
+       sinfg::Layer::ParamList paramlist=handle->get_param_list();
+
+       sinfg::Layer::Vocab vocab=handle->get_param_vocab();
+       sinfg::Layer::Vocab::iterator iter;
+       
+       for(iter=vocab.begin();iter!=vocab.end();++iter)
+       {
+               if(iter->get_hidden())
+                       continue;
+               if(handle->get_param(iter->get_name()).get_type()!=ValueBase::TYPE_CANVAS)
+                       continue;
+               
+               {
+                       Canvas::Handle canvas;
+                       canvas=handle->get_param(iter->get_name()).get(canvas);
+                       if(!canvas)
+                               continue;
+               
+                       Canvas::reverse_iterator iter;
+                       row[model.contained_canvas]=canvas;
+                       
+                       for(iter=canvas->rbegin();iter!=canvas->rend();++iter)
+                       {
+                               Gtk::TreeRow row_(*(prepend(row.children())));
+                               set_row_layer(row_,*iter);
+                       }                       
+                       continue;
+               }
+               
+               
+               /*
+               etl::handle<ValueNode> value_node;
+               if(handle.constant()->dynamic_param_list().count(iter->get_name()))
+                       value_node=handle->dynamic_param_list()[iter->get_name()];
+
+               Gtk::TreeRow child_row = *(append(row.children()));
+               set_row_param(
+                       child_row,
+                       handle,
+                       iter->get_name(),
+                       iter->get_local_name(),
+                       paramlist[iter->get_name()],
+                       value_node,
+                       &*iter
+               );
+               */
+       }
+}
+
+void
+LayerTreeStore::on_layer_added(sinfg::Layer::Handle layer)
+{
+       assert(layer);
+       Gtk::TreeRow row;
+       if(canvas_interface()->get_canvas()==layer->get_canvas())
+       {
+               row=*(prepend());
+       }
+       else
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(!find_canvas_row(layer->get_canvas(),iter))
+               {
+                       rebuild();
+                       return;
+               }
+               row=*(prepend(iter->children()));
+       }
+       set_row_layer(row,layer);
+}
+
+void
+LayerTreeStore::on_layer_removed(sinfg::Layer::Handle handle)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               erase(iter);
+       else
+       {
+               sinfg::error("LayerTreeStore::on_layer_removed():Unable to find layer to be removed, forced to rebuild...");
+               rebuild();
+       }
+}
+
+void
+LayerTreeStore::on_layer_inserted(sinfg::Layer::Handle handle,int depth)
+{              
+       if(depth==0)
+       {
+               on_layer_added(handle);
+               return;
+       }
+
+
+       Gtk::TreeModel::Children children_(children());
+       if(canvas_interface()->get_canvas()!=handle->get_canvas())
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(!find_canvas_row(handle->get_canvas(),iter))
+               {
+                       sinfg::error("LayerTreeStore::on_layer_inserted():Unable to find canvas row, forced to rebuild...");
+                       rebuild();
+                       return;
+               }
+               children_=iter->children();
+       }
+       
+       Gtk::TreeModel::Children::iterator iter(children_.begin());
+       while(depth-- && iter)
+       {
+               ++iter;
+               if(!iter || iter==children_.end())
+               {
+                       sinfg::error("LayerTreeStore::on_layer_inserted():Unable to achieve desired depth, forced to rebuild...");
+                       rebuild();
+                       return;
+               }
+       }
+       
+       Gtk::TreeModel::Row row(*insert(iter));
+       set_row_layer(row,handle);
+       
+}
+
+void
+LayerTreeStore::on_layer_status_changed(sinfg::Layer::Handle handle,bool x)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+               (*iter)[model.layer]=handle;
+       else
+       {
+               sinfg::warning("Couldn't find layer to be activated in layer list. Rebuilding index...");
+               rebuild();
+       }
+}
+
+void
+LayerTreeStore::on_layer_lowered(sinfg::Layer::Handle layer)
+{      
+       Gtk::TreeModel::Children::iterator iter, iter2;
+       if(find_layer_row(layer,iter))
+       {
+               // Save the selection data
+               //sinfgapp::SelectionManager::LayerList layer_list=canvas_interface()->get_selection_manager()->get_selected_layers();
+               iter2=iter;
+               iter2++;
+               if(!iter2)
+               {
+                       rebuild();
+                       return;
+               }
+               
+               //Gtk::TreeModel::Row row(*iter);
+               Gtk::TreeModel::Row row2 = *iter2;
+               sinfg::Layer::Handle layer2=row2[model.layer];
+               
+               erase(iter2);
+               row2=*insert(iter);
+               set_row_layer(row2,layer2);             
+               
+       }
+       else
+               rebuild();
+}
+
+void
+LayerTreeStore::on_layer_raised(sinfg::Layer::Handle layer)
+{
+       Gtk::TreeModel::Children::iterator iter, iter2;
+
+       Gtk::TreeModel::Children children_(children());
+
+       if(find_layer_row_(layer, canvas_interface()->get_canvas(), children_, iter,iter2))
+       {
+               if(iter!=iter2)
+               {       
+                       //Gtk::TreeModel::Row row = *iter;
+                       Gtk::TreeModel::Row row2 = *iter2;
+                       sinfg::Layer::Handle layer2=row2[model.layer];
+               
+                       erase(iter2);
+                       iter++;
+                       row2=*insert(iter);
+                       set_row_layer(row2,layer2);
+                       
+                       return;
+               }
+       }
+       
+       rebuild();
+}
+
+void
+LayerTreeStore::on_layer_moved(sinfg::Layer::Handle layer,int depth, sinfg::Canvas::Handle canvas)
+{
+       on_layer_removed(layer);
+       on_layer_inserted(layer,depth);
+}
+
+void
+LayerTreeStore::on_layer_param_changed(sinfg::Layer::Handle handle,sinfg::String param_name)
+{
+       if(param_name=="z_depth")
+       {
+               Gtk::TreeModel::Children::iterator iter;
+               if(find_layer_row(handle,iter))
+               {
+                       (*iter)[model.z_depth]=Time::begin();
+               }
+       }
+
+       /*
+       //DEBUGPOINT();
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               //DEBUGPOINT();
+               Gtk::TreeModel::Children children(iter->children());
+               
+               for(iter = children.begin(); iter && iter != children.end(); ++iter)
+               {
+                       if((Glib::ustring)(*iter)[model.param_name]==param_name)
+                       {
+                               //DEBUGPOINT();
+                               Gtk::TreeRow row=*iter;
+                               refresh_row(row);
+                               return;                         
+                       }
+               }
+       }
+       //DEBUGPOINT();
+       rebuild();
+       */
+}
+
+void
+LayerTreeStore::on_layer_new_description(sinfg::Layer::Handle handle,sinfg::String desc)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(find_layer_row(handle,iter))
+       {
+               Gtk::TreeRow row(*iter);
+               
+               Layer::Handle layer(row[model.layer]);          
+               
+               if(desc.empty())
+               {
+                       //row[model.label]=layer->get_local_name();
+                       row[model.tooltip]=Glib::ustring(_("Layer"));
+               }
+               else
+                       //row[model.label]=layer->get_description();
+                       row[model.tooltip]=layer->get_local_name();
+       }
+       else    
+       {
+               rebuild();
+       }
+}
+
+bool
+LayerTreeStore::find_canvas_row_(sinfg::Canvas::Handle canvas, sinfg::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter)
+{      
+       if(canvas==parent)
+               return false;
+
+       {
+               for(iter=layers.begin(); iter && iter != layers.end(); ++iter)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if(canvas==(sinfg::Canvas::Handle)row[model.contained_canvas])
+                               return true;
+               }
+               
+               iter=children().end();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+       //Gtk::TreeModel::Children::iterator iter3;
+       
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+               
+               if(row.children().empty())
+                       continue;
+               
+               Canvas::Handle sub_canvas((*row.children().begin())[model.canvas]);
+               if(!sub_canvas)
+                       continue;
+
+               if(find_canvas_row_(canvas,sub_canvas,iter2->children(),iter))
+                       return true;
+       }
+       
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerTreeStore::find_canvas_row(sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter)
+{
+       return find_canvas_row_(canvas,canvas_interface()->get_canvas(),children(),iter);
+}
+
+
+bool
+LayerTreeStore::find_layer_row_(const sinfg::Layer::Handle &layer, sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev)
+{
+       assert(layer);
+       
+       //if(layer->get_canvas()==canvas)
+       {
+               for(iter=prev=layers.begin(); iter && iter != layers.end(); prev=iter++)
+               {
+                       Gtk::TreeModel::Row row = *iter;
+                       if(layer==(sinfg::Layer::Handle)row[model.layer])
+                               return true;
+               }
+               
+               iter=children().end();
+               //DEBUGPOINT();
+               //return false;
+       }
+
+       Gtk::TreeModel::Children::iterator iter2;
+       
+       for(iter2 = layers.begin(); iter2 && iter2 != layers.end(); ++iter2)
+       {
+               Gtk::TreeModel::Row row = *iter2;
+               assert((bool)true);
+               
+               if(row.children().empty())
+                       continue;
+               
+               Canvas::Handle canvas((*row.children().begin())[model.canvas]);
+               if(!canvas)
+                       continue;
+               
+               if(find_layer_row_(layer,canvas,iter2->children(),iter,prev))
+                       return true;
+       }
+       
+       iter=children().end();
+       return false;
+}
+
+bool
+LayerTreeStore::find_layer_row(const sinfg::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &iter)
+{
+       Gtk::TreeModel::Children::iterator prev;
+       return find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev);
+}
+
+bool
+LayerTreeStore::find_prev_layer_row(const sinfg::Layer::Handle &layer, Gtk::TreeModel::Children::iterator &prev)
+{
+       Gtk::TreeModel::Children::iterator iter;
+       if(!find_layer_row_(layer,canvas_interface()->get_canvas(),children(),iter,prev))
+               return false;
+       if(iter==children().begin())
+               return false;
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/layertreestore.h b/synfig-studio/trunk/src/gtkmm/layertreestore.h
new file mode 100644 (file)
index 0000000..555caf1
--- /dev/null
@@ -0,0 +1,218 @@
+/* === S I N F G =========================================================== */
+/*!    \file layertreestore.h
+**     \brief Template Header
+**
+**     $Id: layertreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_LAYERTREESTORE_H
+#define __SINFG_STUDIO_LAYERTREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/value.h>
+#include <sinfg/valuenode.h>
+#include <gtkmm/treeview.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class LayerTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+               Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
+               Gtk::TreeModelColumn<Glib::ustring> label;
+               Gtk::TreeModelColumn<Glib::ustring> name;
+               Gtk::TreeModelColumn<Glib::ustring> id;
+
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle> canvas;
+
+               Gtk::TreeModelColumn<Glib::ustring> tooltip;
+
+
+               Gtk::TreeModelColumn<bool>                                              active;
+               Gtk::TreeModelColumn<sinfg::Layer::Handle>              layer;
+               Gtk::TreeModelColumn<sinfg::Canvas::Handle>                     contained_canvas;
+
+               Gtk::TreeModelColumn<bool>                                              children_lock;
+
+               Gtk::TreeModelColumn<float> z_depth;
+               Gtk::TreeModelColumn<int> index;
+
+               Model()
+               {
+                       add(icon);
+                       add(label);
+                       add(name);
+                       add(id);
+                       add(canvas);
+                       add(tooltip);
+                       add(active);
+                       add(layer);
+                       add(contained_canvas);
+                       add(z_depth);
+                       add(index);
+                       add(children_lock);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       //! TreeModel for the layers
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       Glib::RefPtr<Gdk::Pixbuf> layer_icon;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+private:
+
+       virtual void set_value_impl (const Gtk::TreeModel::iterator& row, int column, const Glib::ValueBase& value);
+       virtual void  get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+
+       virtual bool  row_draggable_vfunc (const TreeModel::Path& path)const;
+       virtual bool  drag_data_get_vfunc (const TreeModel::Path& path, Gtk::SelectionData& selection_data)const;
+       virtual bool  drag_data_delete_vfunc (const TreeModel::Path& path);
+       virtual bool  drag_data_received_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data);
+       virtual bool  row_drop_possible_vfunc (const TreeModel::Path& dest, const Gtk::SelectionData& selection_data)const;
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       bool on_layer_tree_event(GdkEvent *event);
+
+       void on_layer_new_description(sinfg::Layer::Handle handle,sinfg::String desc);
+
+       void on_layer_added(sinfg::Layer::Handle handle);
+
+       void on_layer_removed(sinfg::Layer::Handle handle);
+
+       void on_layer_inserted(sinfg::Layer::Handle handle,int depth);
+
+       void on_layer_moved(sinfg::Layer::Handle handle,int depth, sinfg::Canvas::Handle canvas);
+
+       void on_layer_status_changed(sinfg::Layer::Handle handle,bool);
+
+       void on_layer_lowered(sinfg::Layer::Handle handle);
+
+       void on_layer_raised(sinfg::Layer::Handle handle);
+
+       void on_layer_param_changed(sinfg::Layer::Handle handle,sinfg::String param_name);
+
+       //void on_value_node_added(sinfg::ValueNode::Handle value_node);
+
+       //void on_value_node_deleted(sinfg::ValueNode::Handle value_node);
+
+       //void on_value_node_changed(sinfg::ValueNode::Handle value_node);
+
+       //void on_value_node_replaced(sinfg::ValueNode::Handle replaced_value_node,sinfg::ValueNode::Handle new_value_node);
+
+       bool find_layer_row_(const sinfg::Layer::Handle &handle, sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter, Gtk::TreeModel::Children::iterator &prev);
+
+       bool find_canvas_row_(sinfg::Canvas::Handle canvas, sinfg::Canvas::Handle parent, Gtk::TreeModel::Children layers, Gtk::TreeModel::Children::iterator &iter);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       LayerTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+       ~LayerTreeStore();
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const sinfgapp::CanvasInterface> canvas_interface()const { return canvas_interface_; }
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       bool find_canvas_row(sinfg::Canvas::Handle canvas, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_layer_row(const sinfg::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       bool find_prev_layer_row(const sinfg::Layer::Handle &handle, Gtk::TreeModel::Children::iterator &iter);
+
+       void rebuild();
+
+       void refresh();
+
+       void refresh_row(Gtk::TreeModel::Row &row);
+
+       void set_row_layer(Gtk::TreeRow &row,sinfg::Layer::Handle &handle);
+
+       static int z_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+       static int index_sorter(const Gtk::TreeModel::iterator &rhs,const Gtk::TreeModel::iterator &lhs);
+
+       //void set_row_param(Gtk::TreeRow &row,sinfg::Layer::Handle &handle,const std::string& name, const std::string& local_name, const sinfg::ValueBase &value, etl::handle<sinfg::ValueNode> value_node,sinfg::ParamDesc *param_desc);
+
+       //virtual void set_row(Gtk::TreeRow row,sinfgapp::ValueDesc value_desc);
+       static bool search_func(const Glib::RefPtr<TreeModel>&,int,const Glib::ustring&,const TreeModel::iterator&);
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+       
+       static Glib::RefPtr<LayerTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_);
+
+
+}; // END of class LayerTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/main.cpp b/synfig-studio/trunk/src/gtkmm/main.cpp
new file mode 100644 (file)
index 0000000..c7a312c
--- /dev/null
@@ -0,0 +1,121 @@
+/* === S I N F G =========================================================== */
+/*!    \file main.cpp
+**     \brief Sinfg Studio Entrypoint
+**
+**     $Id: main.cpp,v 1.2 2005/01/13 18:37:30 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "app.h"
+#include <iostream>
+#include "ipc.h"
+#include <stdexcept>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+int main(int argc, char **argv)
+{
+       {
+               SmartFILE file(IPC::make_connection());
+               if(file)
+               {
+                       fprintf(file.get(),"F\n");
+
+                       // Hey, another copy of us is open!
+                       // don't bother opening us, just go ahead and
+                       // tell the other copy to load it all up
+                       if(argc>=1)
+                       {
+                               for(;argc>=1;(argc)--)
+                                       if((argv)[argc] && (argv)[argc][0]!='-')
+                                       {
+                                               fprintf(file.get(),"O %s\n",etl::absolute_path((argv)[argc]).c_str());
+                                       }
+                       }
+                       
+                       fprintf(file.get(),"F\n");
+
+                       return 0;
+               }
+       }
+
+       try
+       {
+               studio::App app(&argc, &argv);
+
+               app.run();
+       }
+       catch(sinfg::SoftwareExpired)
+       {
+               cerr<<"FATAL: Software Expired"<<endl;
+               return 39;
+       }
+       catch(int ret)
+       {
+               std::cerr<<"Application shutdown with errors ("<<ret<<')'<<std::endl;
+               return ret;
+       }
+       catch(string str)
+       {
+               std::cerr<<"Uncaught Exception:string: "<<str<<std::endl;
+               throw;
+       }
+       catch(std::exception x)
+       {
+               std::cerr<<"Standard Exception: "<<x.what()<<std::endl;
+               throw;
+       }
+       catch(Glib::Exception& x)
+       {
+               std::cerr<<"GLib Exception: "<<x.what()<<std::endl;
+               throw;
+       }
+       catch(...)
+       {
+               std::cerr<<"Uncaught Exception"<<std::endl;
+               throw;
+       }
+
+       std::cerr<<"Application appears to have terminated successfuly"<<std::endl;
+       
+       return 0;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/metadatatreestore.cpp b/synfig-studio/trunk/src/gtkmm/metadatatreestore.cpp
new file mode 100644 (file)
index 0000000..3f737ea
--- /dev/null
@@ -0,0 +1,148 @@
+/* === S I N F G =========================================================== */
+/*!    \file metadatatreestore.cpp
+**     \brief Template File
+**
+**     $Id: metadatatreestore.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "metadatatreestore.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+static MetaDataTreeStore::Model& ModelHack()
+{
+       static MetaDataTreeStore::Model* model(0);
+       if(!model)model=new MetaDataTreeStore::Model;
+       return *model;
+}
+
+MetaDataTreeStore::MetaDataTreeStore(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_):
+       Gtk::TreeStore  (ModelHack()),
+       canvas_interface_               (canvas_interface_)
+{
+       // Connect the signal
+       get_canvas()->signal_meta_data_changed().connect(sigc::mem_fun(*this,&MetaDataTreeStore::meta_data_changed));
+       
+       rebuild();
+}
+
+MetaDataTreeStore::~MetaDataTreeStore()
+{
+       sinfg::info("MetaDataTreeStore::~MetaDataTreeStore(): Deleted");
+
+}
+
+Glib::RefPtr<MetaDataTreeStore>
+MetaDataTreeStore::create(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_)
+{
+       return Glib::RefPtr<MetaDataTreeStore>(new MetaDataTreeStore(canvas_interface_));
+}
+
+void
+MetaDataTreeStore::meta_data_changed(sinfg::String key)
+{
+       rebuild();
+}
+
+void
+MetaDataTreeStore::rebuild()
+{
+       clear();
+       
+       std::list<String> keys(get_canvas()->get_meta_data_keys());
+       
+       for(;!keys.empty();keys.pop_front())
+       {
+               Gtk::TreeRow row(*append());
+               row[model.key]=keys.front();
+       }
+}
+
+void
+MetaDataTreeStore::get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(column==model.data.index())
+       {
+               sinfg::String key((Glib::ustring)(*iter)[model.key]);
+               g_value_init(value.gobj(),G_TYPE_STRING);
+               g_value_set_string(value.gobj(),get_canvas()->get_meta_data(key).c_str());
+               return;
+       }
+       else
+               Gtk::TreeStore::get_value_vfunc(iter,column,value);
+}
+
+void
+MetaDataTreeStore::set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value)
+{
+       if(column>=get_n_columns_vfunc())
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad column (%d)",column);
+               return;
+       }
+
+       if(!g_value_type_compatible(G_VALUE_TYPE(value.gobj()),get_column_type_vfunc(column)))
+       {
+               g_warning("KeyframeTreeStore::set_value_impl: Bad value type");
+               return;
+       }
+
+       if(column==model.data.index())
+       {
+               Glib::Value<Glib::ustring> x;
+               g_value_init(x.gobj(),model.data.type());
+               g_value_copy(value.gobj(),x.gobj());
+               
+               sinfg::String key((Glib::ustring)(*iter)[model.key]);
+               sinfg::String new_data(x.get());
+               
+               get_canvas_interface()->set_meta_data(key,new_data);
+       }
+       else
+               Gtk::TreeStore::set_value_impl(iter,column, value);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/metadatatreestore.h b/synfig-studio/trunk/src/gtkmm/metadatatreestore.h
new file mode 100644 (file)
index 0000000..f783d3d
--- /dev/null
@@ -0,0 +1,132 @@
+/* === S I N F G =========================================================== */
+/*!    \file metadatatreestore.h
+**     \brief Template Header
+**
+**     $Id: metadatatreestore.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_METADATATREESTORE_H
+#define __SINFG_STUDIO_METADATATREESTORE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/treestore.h>
+#include <sinfgapp/canvasinterface.h>
+#include <gdkmm/pixbuf.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp { class CanvasInterface; }
+
+namespace studio {
+       
+class MetaDataTreeStore : virtual public Gtk::TreeStore
+{
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       class Model : public Gtk::TreeModel::ColumnRecord
+       {
+       public:
+       public:
+               Gtk::TreeModelColumn<Glib::ustring> key;
+               Gtk::TreeModelColumn<Glib::ustring> data;
+
+               Model()
+               {
+                       add(key);
+                       add(data);
+               }
+       };
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       const Model model;
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       void meta_data_changed(sinfg::String key);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       
+       ~MetaDataTreeStore();
+
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface() { return canvas_interface_; }
+       etl::loose_handle<const sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+       sinfg::Canvas::Handle get_canvas()const { return canvas_interface_->get_canvas(); }
+       sinfg::Canvas::Handle get_canvas() { return canvas_interface_->get_canvas(); }
+
+       void rebuild();
+
+       void refresh() { rebuild(); }
+
+       /*
+ -- ** -- P R O T E C T E D   M E T H O D S -----------------------------------
+       */
+
+protected:
+       MetaDataTreeStore(etl::loose_handle<sinfgapp::CanvasInterface>);
+       void get_value_vfunc (const Gtk::TreeModel::iterator& iter, int column, Glib::ValueBase& value)const;
+       void set_value_impl(const Gtk::TreeModel::iterator& iter, int column, const Glib::ValueBase& value);
+
+public:
+
+       static Glib::RefPtr<MetaDataTreeStore> create(etl::loose_handle<sinfgapp::CanvasInterface>);
+       
+}; // END of class MetaDataTreeStore
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.cpp b/synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.cpp
new file mode 100644 (file)
index 0000000..7d9042c
--- /dev/null
@@ -0,0 +1,65 @@
+/* === S I N F G =========================================================== */
+/*!    \file mod_mirror.cpp
+**     \brief Template File
+**
+**     $Id: mod_mirror.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "mod_mirror.h"
+#include "state_mirror.h"
+
+#include "../app.h"
+#include "../statemanager.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+bool
+studio::ModMirror::start_vfunc()
+{
+       App::get_state_manager()->add_state(&state_mirror);
+       return true;
+}
+
+bool
+studio::ModMirror::stop_vfunc()
+{
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.h b/synfig-studio/trunk/src/gtkmm/mod_mirror/mod_mirror.h
new file mode 100644 (file)
index 0000000..f9bebfe
--- /dev/null
@@ -0,0 +1,58 @@
+/* === S I N F G =========================================================== */
+/*!    \file mod_mirror.h
+**     \brief Template Header
+**
+**     $Id: mod_mirror.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_MOD_MIRROR_H
+#define __SINFG_MOD_MIRROR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include "../module.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class State_Mirror;
+       
+class ModMirror : public Module
+{
+       friend class State_Mirror;
+                       
+protected:
+       virtual bool start_vfunc();
+       virtual bool stop_vfunc();
+
+public:
+       virtual ~ModMirror() { stop(); }
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.cpp b/synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.cpp
new file mode 100644 (file)
index 0000000..3d709f4
--- /dev/null
@@ -0,0 +1,310 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_mirror.cpp
+**     \brief Template File
+**
+**     $Id: state_mirror.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_mirror.h"
+#include "../canvasview.h"
+#include "../workarea.h"
+#include "../app.h"
+
+#include <sinfgapp/action.h>
+#include "../event_mouse.h"
+#include "../event_layerclick.h"
+#include "../toolbox.h"
+#include "../dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "../duck.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+enum Axis {
+       AXIS_X,
+       AXIS_Y
+} ;
+
+/* === G L O B A L S ======================================================= */
+
+StateMirror studio::state_mirror;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class DuckDrag_Mirror : public DuckDrag_Base
+{
+       sinfg::Vector center;
+
+       std::vector<sinfg::Vector> positions;
+       
+       
+public:
+       Axis axis;
+
+       DuckDrag_Mirror();
+       void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin);
+       bool end_duck_drag(Duckmatic* duckmatic);
+       void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector);
+};
+
+
+class studio::StateMirror_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+               
+       sinfgapp::Settings& settings;
+
+       etl::handle<DuckDrag_Mirror> duck_dragger_;
+
+       Gtk::Table options_table;
+       
+       
+       Gtk::CheckButton checkbutton_axis_x;
+       Gtk::CheckButton checkbutton_axis_y;
+       
+public:
+
+       Axis get_axis()const { return checkbutton_axis_x.get_active()?AXIS_X:AXIS_Y; }
+       void set_axis(Axis a)
+       {
+               if(a==AXIS_X)
+               {
+                       checkbutton_axis_x.set_active(true);
+                       checkbutton_axis_y.set_active(false);
+               }
+               else
+               {
+                       checkbutton_axis_y.set_active(true);
+                       checkbutton_axis_x.set_active(false);
+               }
+                       
+               duck_dragger_->axis=get_axis();
+       }
+       
+       void update_axis_y()
+       {
+               checkbutton_axis_x.set_active(!checkbutton_axis_y.get_active());
+               duck_dragger_->axis=get_axis();
+       }
+       void update_axis_x()
+       {
+               checkbutton_axis_y.set_active(!checkbutton_axis_x.get_active());
+               duck_dragger_->axis=get_axis();
+       }
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+
+       StateMirror_Context(CanvasView* canvas_view);
+
+       ~StateMirror_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       void load_settings();
+       void save_settings();
+};     // END of class StateMirror_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateMirror::StateMirror():
+       Smach::state<StateMirror_Context>("mirror")
+{
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateMirror_Context::event_refresh_tool_options));
+}      
+
+StateMirror::~StateMirror()
+{
+}
+
+void
+StateMirror_Context::load_settings()
+{      
+       String value;
+
+       settings.get_value("mirror.axis",value);
+       set_axis((Axis)atoi(value.c_str()));
+}
+
+void
+StateMirror_Context::save_settings()
+{      
+       settings.set_value("mirror.lock_aspect",strprintf("%d",(int)get_axis()));
+}
+
+StateMirror_Context::StateMirror_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       duck_dragger_(new DuckDrag_Mirror()),
+       checkbutton_axis_x(_("Horizontal")),
+       checkbutton_axis_y(_("Vertical"))
+{      
+       // Set up the tool options dialog
+       options_table.attach(*manage(new Gtk::Label(_("Mirror Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+       options_table.attach(checkbutton_axis_x, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(checkbutton_axis_y, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       checkbutton_axis_x.signal_toggled().connect(sigc::mem_fun(*this,&StateMirror_Context::update_axis_x));
+       checkbutton_axis_y.signal_toggled().connect(sigc::mem_fun(*this,&StateMirror_Context::update_axis_y));
+               
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+       
+       get_work_area()->allow_layer_clicks=true;
+       get_work_area()->set_duck_dragger(duck_dragger_);
+
+//     get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::toolbox->refresh();
+
+       set_axis(AXIS_X);
+       load_settings();
+}
+
+void
+StateMirror_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Mirror Tool"));
+       App::dialog_tool_options->set_name("mirror");
+}
+
+Smach::event_result
+StateMirror_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateMirror_Context::~StateMirror_Context()
+{
+       save_settings();
+
+       get_work_area()->clear_duck_dragger();
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       App::toolbox->refresh();
+}
+
+
+
+
+DuckDrag_Mirror::DuckDrag_Mirror():
+       axis(AXIS_X)
+{
+}
+
+#ifndef EPSILON
+#define EPSILON        0.0000001
+#endif
+
+void
+DuckDrag_Mirror::begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& offset)
+{
+
+
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       positions.clear();
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               Point p((*iter)->get_trans_point());
+               positions.push_back(p);
+       }
+
+}
+
+
+void
+DuckDrag_Mirror::duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)
+{
+       center=vector;
+       int i;
+       
+               const DuckList selected_ducks(duckmatic->get_selected_ducks());
+               DuckList::const_iterator iter;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+
+               Vector p(positions[i]);
+               //Point p((*iter)->get_trans_point());
+               
+               if(axis==AXIS_X)
+                       p[0]=-(p[0]-center[0])+center[0];
+               if(axis==AXIS_Y)
+                       p[1]=-(p[1]-center[1])+center[1];
+               
+               (*iter)->set_trans_point(p);
+       }
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+
+               Vector p(positions[i]);
+               //Point p((*iter)->get_trans_point());
+               
+               if(axis==AXIS_X)
+                       p[0]=-(p[0]-center[0])+center[0];
+               if(axis==AXIS_Y)
+                       p[1]=-(p[1]-center[1])+center[1];
+               
+               (*iter)->set_trans_point(p);
+       }
+}
+
+bool
+DuckDrag_Mirror::end_duck_drag(Duckmatic* duckmatic)
+{
+       duckmatic->signal_edited_selected_ducks();
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.h b/synfig-studio/trunk/src/gtkmm/mod_mirror/state_mirror.h
new file mode 100644 (file)
index 0000000..424d298
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_mirror.h
+**     \brief Template Header
+**
+**     $Id: state_mirror.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_MIRROR_H
+#define __SINFG_STUDIO_STATE_MIRROR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "../smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateMirror_Context;
+
+class StateMirror : public Smach::state<StateMirror_Context>
+{
+public:
+       StateMirror();
+       ~StateMirror();
+}; // END of class StateMirror
+
+extern StateMirror state_mirror;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.cpp b/synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.cpp
new file mode 100644 (file)
index 0000000..ee5b11b
--- /dev/null
@@ -0,0 +1,59 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_palette.cpp
+**     \brief Template File
+**
+**     $Id: dock_palbrowse.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_palbrowse.h"
+#include "dock_paledit.h"
+#include "mod_palette.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_PalBrowse::Dock_PalBrowse():
+       Dockable("pal_browse",_("Palette Browser")/*,Gtk::StockID("gtk-select-color")*/)
+{      
+}
+
+Dock_PalBrowse::~Dock_PalBrowse()
+{
+}
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.h b/synfig-studio/trunk/src/gtkmm/mod_palette/dock_palbrowse.h
new file mode 100644 (file)
index 0000000..b5736a3
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_palette.h
+**     \brief Template Header
+**
+**     $Id: dock_palbrowse.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_PAL_BROWSE_H
+#define __SINFG_STUDIO_DOCK_PAL_BROWSE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "../dockable.h"
+#include <sinfg/palette.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+class CanvasInterface;
+};
+
+namespace studio {
+
+class Dock_PalBrowse : public Dockable
+{
+public:
+       Dock_PalBrowse();
+       ~Dock_PalBrowse();
+}; // END of Dock_PalBrowse
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.cpp b/synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.cpp
new file mode 100644 (file)
index 0000000..6b5e0a0
--- /dev/null
@@ -0,0 +1,380 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_palette.cpp
+**     \brief Template File
+**
+**     $Id: dock_paledit.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "dock_paledit.h"
+#include "../widget_color.h"
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <sinfg/general.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/value_desc.h>
+#include "../widget_color.h"
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/menu.h>
+#include <sinfgapp/main.h>
+#include "../app.h"
+#include "../dialog_color.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+/*
+class studio::PaletteSettings : public sinfgapp::Settings
+{
+       Dock_PalEdit* dialog_palette;
+       sinfg::String name;
+public:
+       PaletteSettings(Dock_PalEdit* window,const sinfg::String& name):
+               dialog_palette(window),
+               name(name)
+       {
+               dialog_palette->dialog_settings.add_domain(this,name);
+       }
+       
+       virtual ~PaletteSettings()
+       {
+               dialog_palette->dialog_settings.remove_domain(name);
+       }
+
+       virtual bool get_value(const sinfg::String& key, sinfg::String& value)const
+       {
+               int i(atoi(key.c_str()));
+               if(i<0 || i>=dialog_palette->size())
+                       return false;
+               Color c(dialog_palette->get_color(i));
+               value=strprintf("%f %f %f %f",c.get_r(),c.get_g(),c.get_b(),c.get_a());
+               return true;
+       }
+       
+       virtual bool set_value(const sinfg::String& key,const sinfg::String& value)
+       {
+               int i(atoi(key.c_str()));
+               if(i<0)
+                       return false;
+               if(i>=dialog_palette->size())
+                       dialog_palette->palette_.resize(i+1);
+               float r,g,b,a;
+               if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
+                       return false;
+               dialog_palette->set_color(Color(r,g,b,a),i);
+               return true;
+       }
+       
+       virtual KeyList get_key_list()const
+       {
+               sinfgapp::Settings::KeyList ret(sinfgapp::Settings::get_key_list());
+       
+               int i;
+               for(i=0;i<dialog_palette->size();i++)
+                       ret.push_back(strprintf("%03d",i));
+               return ret;
+       }
+};
+*/
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Dock_PalEdit::Dock_PalEdit():
+       Dockable("pal_edit",_("Palette Editor"),Gtk::StockID("gtk-select-color")),
+       //palette_settings(new PaletteSettings(this,"colors")),
+       table(2,2,false)
+{      
+       action_group=Gtk::ActionGroup::create();
+       DEBUGPOINT();
+       action_group->add(Gtk::Action::create(
+               "palette-add-color",
+               Gtk::StockID("gtk-add"),
+               _("Add Color"),
+               _("Add current foreground color\nto the palette")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &Dock_PalEdit::on_add_pressed
+               )
+       );
+               
+       App::ui_manager()->insert_action_group(action_group);
+
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-palette'>"
+       "       <toolitem action='palette-add-color' />"
+       "       </toolbar>"
+       "</ui>"
+       ;
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-palette")));
+       
+       /*
+       add_button(
+               Gtk::StockID("gtk-add"),
+               _("Add current foreground color\nto the palette")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Dock_PalEdit::on_add_pressed
+               )
+       );
+       */
+       
+       add(table);
+       table.set_homogeneous(true);
+       
+       set_default_palette();
+       
+       show_all_children();
+}
+
+Dock_PalEdit::~Dock_PalEdit()
+{
+       //delete palette_settings;
+}
+
+void
+Dock_PalEdit::set_palette(const sinfg::Palette& x)
+{
+       palette_=x;
+       refresh();
+}
+
+void
+Dock_PalEdit::on_add_pressed()
+{
+       add_color(sinfgapp::Main::get_foreground_color());
+}
+
+void
+Dock_PalEdit::show_menu(int i)
+{
+       Gtk::Menu* menu(manage(new Gtk::Menu()));
+
+       menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-select-color"),
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::Dock_PalEdit::edit_color),
+                       i
+               )
+       ));
+
+       menu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("gtk-delete"),
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::Dock_PalEdit::erase_color),
+                       i
+               )
+       ));
+
+       menu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Load Default Palette"),
+               sigc::mem_fun(*this,&studio::Dock_PalEdit::set_default_palette)
+       ));
+
+       menu->popup(3,gtk_get_current_event_time());
+}
+
+int
+Dock_PalEdit::add_color(const sinfg::Color& x)
+{
+       palette_.push_back(x);
+       signal_changed()();
+       refresh();
+       return size()-1;
+}
+
+void
+Dock_PalEdit::set_color(sinfg::Color x, int i)
+{
+       palette_[i].color=x;
+       signal_changed()();
+       refresh();
+}
+
+Color
+Dock_PalEdit::get_color(int i)const
+{
+       return palette_[i].color;
+}
+
+void
+Dock_PalEdit::erase_color(int i)
+{
+       palette_.erase(palette_.begin()+i);
+       signal_changed()();
+       refresh();
+}
+
+void
+Dock_PalEdit::refresh()
+{
+       const int width(12);
+       
+       // Clear the table
+       table.foreach(sigc::mem_fun(table,&Gtk::Table::remove));
+       
+       for(int i=0;i<size();i++)
+       {
+               Widget_Color* widget_color(manage(new Widget_Color()));
+               widget_color->set_value(get_color(i));
+               widget_color->set_size_request(12,12);
+               widget_color->signal_activate().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::Dock_PalEdit::select_color),
+                               i
+                       )
+               );
+               widget_color->signal_secondary().connect(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::Dock_PalEdit::show_menu),
+                               i
+                       )
+               );
+               int c(i%width),r(i/width);
+               table.attach(*widget_color, c, c+1, r, r+1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+       }
+       table.show_all();
+       queue_draw();
+}
+
+
+void
+Dock_PalEdit::edit_color(int i)
+{
+       App::dialog_color->reset();
+       App::dialog_color->set_color(get_color(i));
+       App::dialog_color->signal_edited().connect(
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::Dock_PalEdit::set_color),
+                       i
+               )
+       );
+       App::dialog_color->present();
+}
+
+void
+Dock_PalEdit::select_color(int i)
+{
+       sinfgapp::Main::set_foreground_color(get_color(i));
+}
+               
+void
+Dock_PalEdit::set_default_palette()
+{
+       int width=12;
+       
+       palette_.clear();
+
+       // Greys
+       palette_.push_back(Color::alpha());
+       for(int i=0;i<width-1;i++)
+       {
+               Color c(
+                       float(i)/(float)(width-2),
+                       float(i)/(float)(width-2),
+                       float(i)/(float)(width-2)
+               );
+               palette_.push_back(c);
+       }
+
+       // Tans
+       for(int i=0;i<width;i++)
+       {
+               float x(float(i)/(float)(width-1));
+               const Color tan1(0.2,0.05,0);
+               const Color tan2(0.85,0.64,0.20);
+               
+               palette_.push_back(Color::blend(tan2,tan1,x));
+       }
+
+       // Solids
+       palette_.push_back(Color::red());
+       palette_.push_back(Color(1.0f,0.25f,0.0f));     // Orange
+       palette_.push_back(Color::yellow());
+       palette_.push_back(Color(0.25f,1.00f,0.0f));    // yellow-green
+       palette_.push_back(Color::green());
+       palette_.push_back(Color(0.0f,1.00f,0.25f));    // green-blue
+       palette_.push_back(Color::cyan());
+       palette_.push_back(Color(0.0f,0.25f,1.0f));     // Sea Blue
+       palette_.push_back(Color::blue());
+       palette_.push_back(Color(0.25f,0.0f,1.0f));
+       palette_.push_back(Color::magenta());
+       palette_.push_back(Color(1.0f,0.0f,0.25f));
+
+       
+       const int levels(3);
+
+       // Colors
+       for(int j=0;j<levels;j++)
+       for(int i=0;i<width;i++)
+       {
+               Color c(Color::red());
+               c.set_hue(c.get_hue()-Angle::rot(float(i)/(float)(width)));
+               c=c.clamped();
+               float s(float(levels-j)/float(levels));
+               s*=s;
+               c.set_r(c.get_r()*s);
+               c.set_g(c.get_g()*s);
+               c.set_b(c.get_b()*s);
+               palette_.push_back(c);
+       }
+
+       
+       /*
+       const int levels(3);
+       
+       for(int i=0;i<levels*levels*levels;i++)
+       {
+               Color c(
+                       float(i%levels)/(float)(levels-1),
+                       float(i/levels%levels)/(float)(levels-1),
+                       float(i/(levels*levels))/(float)(levels-1)
+               );
+               palette_.push_back(c);
+       }
+       */
+       refresh();
+}
+
+int
+Dock_PalEdit::size()const
+{
+       return palette_.size();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.h b/synfig-studio/trunk/src/gtkmm/mod_palette/dock_paledit.h
new file mode 100644 (file)
index 0000000..9ae505a
--- /dev/null
@@ -0,0 +1,112 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_palette.h
+**     \brief Template Header
+**
+**     $Id: dock_paledit.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_DOCK_PAL_EDIT_H
+#define __SINFG_STUDIO_DOCK_PAL_EDIT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtk/gtk.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/checkbutton.h>
+
+#include <sinfg/gamma.h>
+#include <sinfg/time.h>
+
+#include "../widget_coloredit.h"
+
+#include <sinfgapp/value_desc.h>
+#include <sinfg/time.h>
+
+#include "../dockable.h"
+#include <vector>
+#include <gtkmm/actiongroup.h>
+
+#include <sinfg/palette.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+class CanvasInterface;
+};
+
+namespace studio {
+
+class Widget_Color;
+class PaletteSettings;
+       
+class Dock_PalEdit : public Dockable
+{
+       friend class PaletteSettings;
+
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+
+       sinfg::Palette palette_;
+       
+       Gtk::Table table;
+       
+       void on_add_pressed();
+       
+       void show_menu(int i);
+
+       sigc::signal<void> signal_changed_;
+
+
+private:
+       int add_color(const sinfg::Color& x);
+       void set_color(sinfg::Color x, int i);
+       void erase_color(int i);
+
+       void select_color(int i);
+       sinfg::Color get_color(int i)const;
+       void edit_color(int i);
+public:
+       void set_palette(const sinfg::Palette& x);
+       const sinfg::Palette& get_palette()const { return palette_; }
+
+       int size()const;
+
+       void set_default_palette();
+       
+       void refresh();
+
+       const sigc::signal<void>& signal_changed() { return signal_changed_; }
+               
+       Dock_PalEdit();
+       ~Dock_PalEdit();
+}; // END of Dock_PalEdit
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.cpp b/synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.cpp
new file mode 100644 (file)
index 0000000..fbb509c
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file mod_palette.cpp
+**     \brief Template File
+**
+**     $Id: mod_palette.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "mod_palette.h"
+#include "dock_paledit.h"
+#include "dock_palbrowse.h"
+
+#include "../app.h"
+#include "../dockmanager.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+bool
+studio::ModPalette::start_vfunc()
+{
+       dock_pal_edit=new Dock_PalEdit();
+       App::get_dock_manager()->register_dockable(*dock_pal_edit);
+
+       dock_pal_browse=new Dock_PalBrowse();
+       App::get_dock_manager()->register_dockable(*dock_pal_browse);
+       
+       return true;
+}
+
+bool
+studio::ModPalette::stop_vfunc()
+{
+       App::get_dock_manager()->unregister_dockable(*dock_pal_browse);
+       App::get_dock_manager()->unregister_dockable(*dock_pal_edit);
+
+       delete dock_pal_edit;
+       delete dock_pal_browse;
+
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.h b/synfig-studio/trunk/src/gtkmm/mod_palette/mod_palette.h
new file mode 100644 (file)
index 0000000..7be196c
--- /dev/null
@@ -0,0 +1,63 @@
+/* === S I N F G =========================================================== */
+/*!    \file mod_palette.h
+**     \brief Template Header
+**
+**     $Id: mod_palette.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_MOD_PALETTE_H
+#define __SINFG_MOD_PALETTE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include "../module.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dock_PalEdit;
+class Dock_PalBrowse;
+       
+class ModPalette : public Module
+{
+       friend class Dock_PalEdit;
+       friend class Dock_PalBrowse;
+               
+       Dock_PalEdit*   dock_pal_edit;
+       Dock_PalBrowse* dock_pal_browse;
+       
+protected:
+       virtual bool start_vfunc();
+       virtual bool stop_vfunc();
+
+public:
+       virtual ~ModPalette() { stop(); }
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/module.cpp b/synfig-studio/trunk/src/gtkmm/module.cpp
new file mode 100644 (file)
index 0000000..8902303
--- /dev/null
@@ -0,0 +1,82 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: module.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "module.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+//using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Module::Module():status_(false)
+{
+}
+       
+Module::~Module()
+{
+       stop();
+}
+
+bool
+Module::get_status()const
+{
+       return status_;
+}
+
+bool
+Module::start()
+{
+       if(!get_status())
+               status_=start_vfunc();
+       return get_status();
+}
+
+bool
+Module::stop()
+{
+       if(get_status() && count()<=1 && stop_vfunc())
+       {
+               status_=false;
+               return true;
+       }
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/module.h b/synfig-studio/trunk/src/gtkmm/module.h
new file mode 100644 (file)
index 0000000..77d5de3
--- /dev/null
@@ -0,0 +1,66 @@
+/* === S I N F G =========================================================== */
+/*!    \file module.h
+**     \brief Template Header
+**
+**     $Id: module.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_MODULE_H
+#define __SINFG_MODULE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Module : public etl::shared_object
+{
+       bool status_;
+       
+protected:
+       Module();
+
+public:
+       virtual ~Module();
+
+       bool start();
+       
+       bool stop();
+       
+       bool get_status()const;
+
+protected:
+       
+       virtual bool start_vfunc()=0;
+       virtual bool stop_vfunc()=0;
+};
+
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/onemoment.cpp b/synfig-studio/trunk/src/gtkmm/onemoment.cpp
new file mode 100644 (file)
index 0000000..c1d245f
--- /dev/null
@@ -0,0 +1,114 @@
+/*! ========================================================================
+** Sinfg
+** Template File
+** $Id: onemoment.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include <ETL/stringf>
+
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+#include <gtkmm/fixed.h>
+
+#include <sinfg/general.h>
+
+#include "onemoment.h"
+#include "app.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef VERSION
+#define VERSION        "unknown"
+#define PACKAGE        "sinfgstudio"
+#endif
+
+#ifdef WIN32
+#      ifdef IMAGE_DIR
+#              undef IMAGE_DIR
+#              define IMAGE_DIR "share\\pixmaps"
+#      endif
+#endif
+
+#ifndef IMAGE_DIR
+#      define IMAGE_DIR "/usr/local/share/pixmaps"
+#endif
+
+#ifndef IMAGE_EXT
+#      define IMAGE_EXT        "png"
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+OneMoment::OneMoment():        Gtk::Window(Gtk::WINDOW_POPUP)
+{
+       
+       // Create the Copyright Label
+       Gtk::Label *label = manage(new class Gtk::Label(_("One Moment, Please...")));
+
+       set_title(_("One Moment, Please..."));
+       set_modal(false);
+       property_window_position().set_value(Gtk::WIN_POS_CENTER);
+       set_resizable(false);
+       add(*label);
+
+       Pango::AttrList attr_list;
+       Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*16));
+       pango_size.set_start_index(0);
+       pango_size.set_end_index(64);
+       attr_list.change(pango_size);
+
+       label->set_attributes(attr_list);
+
+       label->set_size_request(400,60);
+
+       get_root_window()->set_decorations(Gdk::DECOR_BORDER);
+
+       // show everything off
+       show_all();
+       
+       present();
+       while(studio::App::events_pending())studio::App::iteration(false);
+}
+
+OneMoment::~OneMoment()
+{
+       hide();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/onemoment.h b/synfig-studio/trunk/src/gtkmm/onemoment.h
new file mode 100644 (file)
index 0000000..2fbf2d8
--- /dev/null
@@ -0,0 +1,52 @@
+/*! ========================================================================
+** Sinfg
+** Template Header File
+** $Id: onemoment.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_ONEMOMENT_H
+#define __SINFG_GTKMM_ONEMOMENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/window.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class ProgressCallback; };
+
+namespace studio {
+
+class OneMoment : public Gtk::Window
+{
+public:
+       
+       OneMoment();
+       ~OneMoment();
+};
+
+}
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/preview.cpp b/synfig-studio/trunk/src/gtkmm/preview.cpp
new file mode 100644 (file)
index 0000000..944a111
--- /dev/null
@@ -0,0 +1,876 @@
+/* === S I N F G =========================================================== */
+/*!    \file preview.cpp
+**     \brief Preview implementation file
+**
+**     $Id: preview.cpp,v 1.2 2005/01/10 08:13:44 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "preview.h"
+#include "app.h"
+#include "audiocontainer.h"
+#include <gtkmm/stock.h>
+#include <gtkmm/separator.h>
+
+#include <sinfg/target_scanline.h>
+#include <sinfg/surface.h>
+
+#include <algorithm>
+#include "asyncrenderer.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+class studio::Preview::Preview_Target : public Target_Scanline
+{
+       Surface surface;
+       
+       sigc::signal<void, const Preview_Target *>              signal_frame_done_;
+       
+       int scanline;
+       
+       double  tbegin,tend;
+       
+       int             nframes,curframe;
+       
+public:
+
+       Preview_Target()
+       {
+               set_remove_alpha();
+               tbegin = tend = 0;
+               scanline = 0;
+               nframes = curframe = 0;
+       }
+
+       const RendDesc &get_rend_desc() const { return desc; }
+
+       virtual bool set_rend_desc(RendDesc *r)
+       {
+               if(Target_Scanline::set_rend_desc(r))
+               {
+                       /*sinfg::warning("Succeeded in setting the desc to new one: %d x %d, %.2f fps [%.2f,%.2f]",
+                                                       desc.get_w(),desc.get_h(),desc.get_frame_rate(),
+                                       (float)desc.get_time_start(),(float)desc.get_time_end());*/
+                       
+                       surface.set_wh(desc.get_w(),desc.get_h());
+                       
+                       curframe = 0;                   
+                       nframes = (int)floor((desc.get_time_end() - desc.get_time_start())*desc.get_frame_rate());
+                       
+                       tbegin = desc.get_time_start();
+                       tend = tbegin + nframes/desc.get_frame_rate();
+                               
+                       return true;            
+               }
+               return false;
+       }
+       
+       virtual bool start_frame(ProgressCallback *cb=NULL)
+       {
+               return true;            
+       }
+       
+       virtual void end_frame()
+       {
+               //ok... notify our subscribers...
+               signal_frame_done_(this);
+               curframe += 1;
+               //sinfg::warning("Finished the frame stuff, and changed time to %.3f",t);
+       }
+       
+       virtual Color * start_scanline(int scanline)
+       {
+               return surface[scanline];
+       }
+       
+       virtual bool end_scanline() {return true;}
+       
+       sigc::signal<void, const Preview_Target *>      &signal_frame_done() {return signal_frame_done_;}
+       
+       const Surface &get_surface() const {return surface;}
+       
+       float get_time() const 
+       {
+               double time = ((nframes-curframe)/(double)nframes)*tbegin
+                                       + ((curframe)/(double)nframes)*tend;
+               return time;
+       }
+};
+
+studio::Preview::Preview(const studio::CanvasView::LooseHandle &h, float zoom, float f)
+:canvasview(h),zoom(zoom),fps(f)
+{
+       overbegin = false;
+       overend = false;
+}
+
+void studio::Preview::set_canvasview(const studio::CanvasView::LooseHandle &h)
+{
+       canvasview = h;
+       
+       if(canvasview)
+       {
+               //perhaps reset override values...
+               const RendDesc &r = canvasview->get_canvas()->rend_desc();
+               if(r.get_frame_rate())
+               {
+                       float rate = 1/r.get_frame_rate();
+                       overbegin = false; begintime = r.get_time_start() + r.get_frame_start()*rate;
+                       overend = false; endtime = r.get_time_start() + r.get_frame_end()*rate;
+               }
+       }
+}
+
+studio::Preview::~Preview()
+{
+       signal_destroyed_(this); //tell anything that attached to us, we're dying
+}
+
+void studio::Preview::render()
+{
+       if(canvasview)
+       {
+               //render using the preview target
+               etl::handle<Preview_Target>     target = new Preview_Target;
+               
+               //connect our information to his...
+               //sinfg::warning("Connecting to the end frame function...");
+               target->signal_frame_done().connect(sigc::mem_fun(*this,&Preview::frame_finish));
+               
+               //set the options
+               //sinfg::warning("Setting Canvas");
+               target->set_canvas(get_canvas());
+               target->set_quality(quality);
+               
+               //render description
+               RendDesc desc = get_canvas()->rend_desc();
+               
+               //set the global fps of the preview
+               set_global_fps(desc.get_frame_rate());
+               
+               desc.clear_flags();
+               
+               int neww = (int)floor(desc.get_w()*zoom+0.5),
+                       newh = (int)floor(desc.get_h()*zoom+0.5);
+               float newfps = fps;
+               
+               /*sinfg::warning("Setting the render description: %d x %d, %f fps, [%f,%f]",
+                                               neww,newh,newfps, overbegin?begintime:(float)desc.get_time_start(),
+                                               overend?endtime:(float)desc.get_time_end());*/
+               
+               desc.set_w(neww);
+               desc.set_h(newh);
+               desc.set_frame_rate(newfps);
+               
+               if(overbegin)
+               {
+                       desc.set_time_start(std::max(begintime,(float)desc.get_time_start()));
+                       //sinfg::warning("Set start time to %.2f...",(float)desc.get_time_start());
+               }
+               if(overend)
+               {
+                       desc.set_time_end(std::min(endtime,(float)desc.get_time_end()));
+                       //sinfg::warning("Set end time to %.2f...",(float)desc.get_time_end());
+               }
+                       
+               //setting the description
+               
+               //HACK - BECAUSE THE RENDERER CAN'T RENDER INCLUDING THE LAST FRAME
+               desc.set_time_end(desc.get_time_end() + 1.3/fps);
+               
+               target->set_rend_desc(&desc);
+               
+               //... first we must clear our current selves of space
+               frames.resize(0);
+               
+               //now tell it to go... with inherited prog. reporting...
+               //sinfg::info("Rendering Asynchronously...");
+               if(renderer) renderer->stop();
+               renderer = new AsyncRenderer(target);
+               renderer->start();
+       }
+}
+
+static void free_guint8(const guint8 *mem)
+{
+       free((void*)mem);
+}
+
+void studio::Preview::frame_finish(const Preview_Target *targ)
+{
+       //copy image with time to next frame (can just push back)
+       FlipbookElem    fe;
+       float time = targ->get_time();
+       const Surface &surf = targ->get_surface();
+       const RendDesc& r = targ->get_rend_desc();
+       
+       //sinfg::warning("Finished a frame at %f s",time);
+       
+       //copy EVERYTHING!
+       PixelFormat pf(PF_RGB);
+       const int total_bytes(r.get_w()*r.get_h()*sinfg::channels(pf));
+       
+       //sinfg::warning("Creating a buffer");
+       unsigned char *buffer((unsigned char*)malloc(total_bytes));
+
+       if(!buffer)
+               return;
+
+       //convert all the pixles to the pixbuf... buffer... thing...
+       //sinfg::warning("Converting...");      
+       convert_color_format(buffer, surf[0], surf.get_w()*surf.get_h(), pf, App::gamma);
+       
+       //load time
+       fe.t = time;    
+       //uses and manages the memory for the buffer...
+       //sinfg::warning("Create a pixmap...");
+       fe.buf = 
+       Gdk::Pixbuf::create_from_data(
+               buffer, // pointer to the data
+               Gdk::COLORSPACE_RGB, // the colorspace
+               ((pf&PF_A)==PF_A), // has alpha?
+               8, // bits per sample
+               surf.get_w(),   // width
+               surf.get_h(),   // height
+               surf.get_w()*sinfg::channels(pf), // stride (pitch)
+               sigc::ptr_fun(free_guint8)
+       );
+       
+       //add the flipbook element to the list (assume time is correct)
+       //sinfg::info("Prev: Adding %f s to the list", time);
+       frames.push_back(fe);
+       
+       signal_changed()();
+}
+
+#define IMAGIFY_BUTTON(button,stockid) \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::ICON_SIZE_BUTTON));       \
+       button->add(*icon);     \
+       icon->set_padding(0,0);\
+       icon->show();   
+
+Widget_Preview::Widget_Preview()
+:Gtk::Table(5,5,false),
+adj_time_scrub(0,0,1000,1,10,0),
+scr_time_scrub(adj_time_scrub),
+b_loop(/*_("Loop")*/),
+adj_sound(0,0,4),
+l_lasttime("0s"),
+playing(false)
+{
+       //connect to expose events
+       //signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Preview::redraw));
+       
+       //manage all the change in values etc...
+       adj_time_scrub.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_Preview::slider_move));
+       scr_time_scrub.signal_event().connect(sigc::mem_fun(*this,&Widget_Preview::scroll_move_event));
+       draw_area.signal_expose_event().connect(sigc::mem_fun(*this,&Widget_Preview::redraw));
+       
+       disp_sound.set_time_adjustment(&adj_sound);
+       timedisp = -1;
+       
+       //Set up signals to modify time value as it should be...
+       disp_sound.signal_start_scrubbing().connect(sigc::mem_fun(*this,&Widget_Preview::scrub_updated));
+       disp_sound.signal_scrub().connect(sigc::mem_fun(*this,&Widget_Preview::scrub_updated));
+               
+       /*
+       ---------------------------------
+       |                                                               |
+       |                                                               |
+       |                                                               |
+       |                                                               |
+       |                                                               |
+       |                                                               |
+       |                                                               |
+       ---------------------------------
+       |loop|play|stop                                 | hbox
+       |lastl|lastt|rerender|haltrend  | hbox
+       |       
+       |sound                                                  |
+       */
+       
+       Gtk::HBox *hbox = 0;
+       Gtk::Button *button = 0;
+       Gtk::Image *icon = 0;
+       
+       //should set up the dialog using attach etc.    
+       attach(draw_area, 0, 1, 0, 1);
+       attach(scr_time_scrub, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK);
+       
+       #if 1
+       
+       //2nd row
+       hbox = manage(new Gtk::HBox);
+       
+       button = &b_loop;
+       IMAGIFY_BUTTON(button,Gtk::Stock::REFRESH);
+       hbox->pack_start(b_loop,Gtk::PACK_SHRINK,0);
+       //attach(b_loop,0,1,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       button = manage(new Gtk::Button(/*_("Play")*/));
+       button->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Preview::play));
+       IMAGIFY_BUTTON(button,Gtk::Stock::GO_FORWARD);
+       hbox->pack_start(*button,Gtk::PACK_SHRINK,0);
+       //attach(*button,1,2,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       button = manage(new Gtk::Button(/*_("Stop")*/));
+       button->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Preview::stop));
+       IMAGIFY_BUTTON(button,Gtk::Stock::NO);
+       hbox->pack_start(*button,Gtk::PACK_SHRINK,0);
+       //attach(*button,2,3,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       //attack the stop render and erase all buttons to same line...
+       {
+               Gtk::VSeparator *vsep = manage(new Gtk::VSeparator);
+               hbox->pack_start(*vsep,Gtk::PACK_SHRINK,0);
+       }
+       
+       button = manage(new Gtk::Button(/*_("Halt Render")*/));
+       button->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Preview::stoprender));
+       IMAGIFY_BUTTON(button,Gtk::Stock::STOP);
+       hbox->pack_start(*button,Gtk::PACK_SHRINK,0);
+       //attach(*button,2,3,3,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       button = manage(new Gtk::Button(/*_("Re-Preview")*/));
+       button->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Preview::repreview));
+       IMAGIFY_BUTTON(button,Gtk::Stock::CONVERT);
+       hbox->pack_start(*button,Gtk::PACK_SHRINK,0);
+       //attach(*button,0,2,4,5,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       button = manage(new Gtk::Button(/*_("Erase All")*/));
+       button->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Preview::eraseall));
+       //IMAGIFY_BUTTON(button,Gtk::Stock::DELETE);
+       hbox->pack_start(*button,Gtk::PACK_SHRINK,0);
+       //attach(*button,2,3,4,5,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       hbox->show_all();
+       attach(*hbox,0,1,2,3,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK|Gtk::FILL);
+       
+       //3rd row
+       hbox = manage(new Gtk::HBox);
+       {
+               Gtk::Label *label = manage(new Gtk::Label("Last Rendered: "));
+               //label->show();
+               hbox->pack_start(*label,Gtk::PACK_SHRINK,10);
+               //attach(*manage(new Gtk::Label("Last Rendered: ")),0,1,3,4,Gtk::SHRINK,Gtk::SHRINK);
+       }
+       //l_lasttime.show();
+       hbox->pack_start(l_lasttime,Gtk::PACK_SHRINK,0);
+       hbox->show_all();
+       attach(*hbox,0,1,3,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       //attach(l_lasttime,0,1,3,4,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+               
+       //5th row
+       disp_sound.set_size_request(-1,32);
+       attach(disp_sound,0,1,4,5,Gtk::EXPAND|Gtk::FILL,Gtk::SHRINK);
+       
+       show_all();
+       
+       //if(draw_area.get_window()) gc_area = Gdk::GC::create(draw_area.get_window());
+       #endif
+}
+
+studio::Widget_Preview::~Widget_Preview()
+{
+}
+
+void studio::Widget_Preview::update()
+{
+       //the meat goes in this locker...
+       double time = adj_time_scrub.get_value();
+       
+       //find the frame and display it...
+       if(preview)
+       {
+               //sinfg::warning("Updating at %.3f s",time);            
+               
+               //use time to find closest frame...
+               studio::Preview::FlipBook::const_iterator       beg = preview->begin(),end = preview->end();
+               studio::Preview::FlipBook::const_iterator       i;
+               
+               i = beg;
+               
+               //go to current hint if need be...
+               if(currentindex >= 0 && currentindex < (int)preview->numframes())
+               {
+                       i = beg+currentindex;
+               }
+               
+               //we can't have a picture if there are none to get
+               if(beg != end)
+               {                       
+                       //don't bother with binary search it will just be slower...
+                       
+                       //sinfg::info("Search for time %f",time);
+                       
+                       //incrementally go in either direction 
+                       //(bias downward towards beg, because that's what we want)
+                       for(;i != end;++i)
+                       {
+                               //sinfg::info("Look at %f",i->t);
+                               if(i->t > time) break;
+                               //sinfg::info("Go past...");
+                       }
+                       
+                       //if(i!=beg)--i; 
+                       
+                       //bias down, so we can't be at end... and it still is valid...          
+                       for(;i != beg;)
+                       {
+                               --i;
+                               //sinfg::info("Look at %f",i->t);
+                               if(i->t <= time) break;
+                               //sinfg::info("Go past...");
+                       }
+                       
+                       /*i = preview->begin(); end = preview->end();
+                       if(i == end) return;
+                       
+                       j = i;
+                       for(;i != end; j = i++)
+                       {
+                               if(i->t > time) break;
+                       }*/
+                       
+                       //we should be at a valid edge since we biased downward
+                       
+                       //don't get the closest, round down... (if we can)
+                       if(i == end)
+                       {
+                               sinfg::error("i == end....");
+                               //assert(0);
+                               currentbuf.clear();
+                               currentindex = 0;
+                               timedisp = -1;
+                       }else
+                       {
+                               currentbuf = i->buf;
+                               currentindex = i-beg;
+                               if(timedisp != i->t)
+                               {
+                                       timedisp = i->t;
+                                       //sinfg::warning("Update at: %f seconds (%f s)",time,timedisp);
+                                       preview_draw();
+                                       //sinfg::warning("success!");                   
+                               }
+                       }
+               }
+       }
+       
+       if(disp_sound.get_profile() && adj_sound.get_value() != time)
+       {
+               //timeupdate = time;
+               
+               //Set the position of the sound (short circuited for sound modifying the time)
+               
+               disp_sound.set_position(time);
+               disp_sound.queue_draw();
+       }
+}
+void studio::Widget_Preview::preview_draw()
+{
+       draw_area.queue_draw();//on_expose_event();
+}
+
+bool studio::Widget_Preview::redraw(GdkEventExpose *heh)
+{      
+       //And render the drawing area
+       Glib::RefPtr<Gdk::Pixbuf> pxnew, px = currentbuf;
+       
+       if(!px || draw_area.get_height() == 0 
+               || px->get_height() == 0 || px->get_width() == 0 /*|| is_visible()*/) //made not need this line
+               return true;
+       
+       //figure out the scaling factors...
+       float sx, sy;
+       int nw,nh;
+
+       sx = draw_area.get_width() / (float)px->get_width();
+       sy = draw_area.get_height() / (float)px->get_height();
+       
+       //sinfg::info("widget_preview redraw: now to scale the bitmap: %.3f x %.3f",sx,sy);
+       
+       //round to smallest scale (fit entire thing in window without distortion)
+       if(sx > sy) sx = sy;
+       //else sy = sx;
+       
+       //scale to a new pixmap and then copy over to the window
+       nw = (int)(px->get_width()*sx);
+       nh = (int)(px->get_height()*sx);
+       
+       if(nw == 0 || nh == 0)return true;
+               
+       pxnew = px->scale_simple(nw,nh,Gdk::INTERP_NEAREST);
+               
+       //sinfg::info("Now to draw to the window...");
+       //copy to window
+       Glib::RefPtr<Gdk::Window>       wind = draw_area.get_window();
+       Glib::RefPtr<Gdk::Drawable> surf = Glib::RefPtr<Gdk::Drawable>::cast_static(wind);
+       Glib::RefPtr<Gdk::GC>           gc = Gdk::GC::create(wind);
+
+       {
+               Gdk::Rectangle r(0,0,draw_area.get_width(),draw_area.get_height());
+               draw_area.get_window()->begin_paint_rect(r);
+       }
+
+       if(!wind) sinfg::warning("The destination window is broken...");
+       if(!surf) sinfg::warning("The destination is not drawable...");
+       
+       if(surf)
+       {
+               /* Options for drawing...
+                       1) store with alpha, then clear and render with alpha every frame
+                               - more time consuming
+                               + more expandable
+                       2) store with just pixel info
+                               - less expandable
+                               + faster
+                               + better memory footprint
+               */
+               //px->composite(const Glib::RefPtr<Gdk::Pixbuf>& dest, int dest_x, int dest_y, int dest_width, int dest_height, double offset_x, double offset_y, double scale_x, double scale_y, InterpType interp_type, int overall_alpha) const
+               
+               surf->draw_pixbuf(
+                       gc, //GC
+                       pxnew, //pixbuf
+                       0, 0,   // Source X and Y
+                       0, 0,   // Dest X and Y
+                       -1,-1,  // Width and Height
+                       Gdk::RGB_DITHER_NONE, // RgbDither
+                       0, 0 // Dither offset X and Y
+               );
+               
+               if(timedisp >= 0)
+               {
+                       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_pango_context()));         
+                       Glib::ustring timecode(Time((double)timedisp).round(preview->get_global_fps())
+                                                                                                                       .get_string(preview->get_global_fps(),
+                                                                                                                                                       App::get_time_format()));
+                       //sinfg::info("Time for preview draw is: %s for time %g", timecode.c_str(), adj_time_scrub.get_value());
+                                                                                                                                               
+                       gc->set_rgb_fg_color(Gdk::Color("#FF0000"));
+                       layout->set_text(timecode);
+                       surf->draw_layout(gc,4,4,layout);
+               }
+       }
+
+       draw_area.get_window()->end_paint();
+       
+       //sinfg::warning("Refresh the draw area");
+       //make sure the widget refreshes
+       
+       return false;
+}
+
+bool studio::Widget_Preview::play_update()
+{
+       float diff = timer.pop_time();
+       //sinfg::info("Play update: diff = %.2f",diff);
+       
+       if(playing)
+       {
+               //we go to the next one...
+               double time = adj_time_scrub.get_value() + diff;
+               
+               //adjust it to be synced with the audio if it can...
+               {
+                       double newtime = audiotime;
+                       if(audio && audio->is_playing()) audio->get_current_time(newtime);
+                               
+                       if(newtime != audiotime)
+                       {
+                               //sinfg::info("Adjusted time from %.3lf to %.3lf", time,newtime);
+                               time = audiotime = newtime;
+                       }
+               }
+               
+               //Looping conditions...
+               if(time >= adj_time_scrub.get_upper())
+               {
+                       if(get_loop_flag())
+                       {
+                               time = adj_time_scrub.get_lower();// + time-adj_time_scrub.get_upper();
+                               currentindex = 0;
+                       }else
+                       {
+                               time = adj_time_scrub.get_upper();
+                               adj_time_scrub.set_value(time);
+                               play_stop();
+                               update();
+                               
+                               //sinfg::info("Play Stopped: time set to %f",adj_time_scrub.get_value());
+                               return false;
+                       }
+               }
+               
+               //set the new time...
+               adj_time_scrub.set_value(time);
+               adj_time_scrub.value_changed();
+               
+               //update the window to the correct image we might want to do this later...
+               //update();
+               //sinfg::warning("Did update pu");
+       }
+       return true;
+}
+
+void studio::Widget_Preview::slider_move()
+{
+       //if(!playing)
+       {
+               update();
+               //sinfg::warning("Did update sm");
+       }
+}
+
+//for other things updating the value changed signal...
+void studio::Widget_Preview::scrub_updated(double t)
+{
+       stop();
+       
+       //Attempt at being more accurate... the time is adjusted to be exactly where the sound says it is
+       //double oldt = t;
+       if(audio)
+       {
+               if(!audio->isPaused()) 
+               {
+                       audio->get_current_time(t);
+               }
+       }
+       
+       //sinfg::info("Scrubbing to %.3f, setting adj to %.3f",oldt,t);
+                       
+       if(adj_time_scrub.get_value() != t)
+       {
+               adj_time_scrub.set_value(t);
+               adj_time_scrub.value_changed();
+       }
+}
+       
+void studio::Widget_Preview::disconnect_preview(Preview *prev)
+{
+       if(prev == preview)
+       {
+               preview = 0;
+               prevchanged.disconnect();
+       }
+}
+
+void studio::Widget_Preview::set_preview(handle<Preview>       prev)
+{
+       preview = prev;
+       
+       sinfg::info("Setting preview");
+       
+       //stop playing the mini animation...
+       stop();
+       
+       if(preview)
+       {
+               //set the internal values
+               float rate = preview->get_fps();
+               sinfg::info("   FPS = %f",rate);
+               if(rate)
+               {
+                       float start = preview->get_begintime();
+                       float end = preview->get_endtime();
+                       
+                       rate = 1/rate;
+                       
+                       adj_time_scrub.set_lower(start);
+                       adj_time_scrub.set_upper(end);
+                       adj_time_scrub.set_value(start);
+                       adj_time_scrub.set_step_increment(rate);
+                       adj_time_scrub.set_page_increment(10*rate);
+                       
+                       //if the begin time and the end time are the same there is only a single frame
+                       singleframe = end==start;
+               }else
+               {
+                       adj_time_scrub.set_lower(0);
+                       adj_time_scrub.set_upper(0);
+                       adj_time_scrub.set_value(0);
+                       adj_time_scrub.set_step_increment(0);
+                       adj_time_scrub.set_page_increment(0);                   
+                       singleframe = true;
+               }
+               
+               //connect so future information will be found...
+               prevchanged = prev->signal_changed().connect(sigc::mem_fun(*this,&Widget_Preview::whenupdated));
+               prev->signal_destroyed().connect(sigc::mem_fun(*this,&Widget_Preview::disconnect_preview));
+               update();
+               //sinfg::warning("Did update sp");
+               queue_draw();
+       }
+}
+
+void studio::Widget_Preview::whenupdated()
+{
+       l_lasttime.set_text((Time((double)(--preview->end())->t)
+                                                       .round(preview->get_global_fps())
+                                                       .get_string(preview->get_global_fps(),App::get_time_format())));
+       update();
+}
+
+void studio::Widget_Preview::clear()
+{
+       preview = 0;
+       prevchanged.disconnect();
+}
+
+void studio::Widget_Preview::play()
+{
+       if(preview && !playing)
+       {
+               //sinfg::info("Playing at %lf",adj_time_scrub.get_value());
+               //audiotime = adj_time_scrub.get_value();
+               playing = true;
+
+               //adj_time_scrub.set_value(adj_time_scrub.get_lower());         
+               update(); //we don't want to call play update because that will try to advance the timer
+               //sinfg::warning("Did update p");
+               
+               //approximate length of time in seconds, right?
+               double rate = /*std::min(*/adj_time_scrub.get_step_increment()/*,1/30.0)*/;
+               int timeout = (int)floor(1000*rate);
+               
+               //sinfg::info(" rate = %.3lfs = %d ms",rate,timeout);
+               
+               signal_play_(adj_time_scrub.get_value());
+               
+               //play the audio...
+               if(audio) audio->play(adj_time_scrub.get_value());
+                               
+               timecon = Glib::signal_timeout().connect(sigc::mem_fun(*this,&Widget_Preview::play_update),timeout);            
+               timer.reset();          
+       }
+       
+}
+
+void studio::Widget_Preview::play_stop()
+{
+       playing = false;
+       signal_stop()();
+       if(audio) audio->stop(); //!< stop the audio
+       //sinfg::info("Stopping...");
+}
+
+void studio::Widget_Preview::stop()
+{
+       //sinfg::warning("stopping");
+       play_stop();
+       timecon.disconnect();
+}
+
+bool studio::Widget_Preview::scroll_move_event(GdkEvent *event)
+{
+       switch(event->type)
+       {
+               case GDK_BUTTON_PRESS:
+               {
+                       if(event->button.button == 1 || event->button.button == 3)
+                       {
+                               stop();
+                       }
+               }
+               
+               default: break;
+       }
+       
+       return false;
+}
+
+void studio::Widget_Preview::set_audioprofile(etl::handle<AudioProfile> p)
+{
+       disp_sound.set_profile(p);
+}
+
+void studio::Widget_Preview::set_audio(etl::handle<AudioContainer> a)
+{
+       audio = a;
+       
+       //disconnect any previous signals
+       scrstartcon.disconnect(); scrstopcon.disconnect(); scrubcon.disconnect();
+               
+       //connect the new signals
+       scrstartcon = disp_sound.signal_start_scrubbing().connect(sigc::mem_fun(*a,&AudioContainer::start_scrubbing));
+       scrstopcon = disp_sound.signal_stop_scrubbing().connect(sigc::mem_fun(*a,&AudioContainer::stop_scrubbing));
+       scrubcon = disp_sound.signal_scrub().connect(sigc::mem_fun(*a,&AudioContainer::scrub));
+}
+
+void studio::Widget_Preview::seek(float t)
+{
+       stop();
+       adj_time_scrub.set_value(t);
+}
+
+void studio::Widget_Preview::repreview()
+{
+       if(preview)
+       {
+               stoprender();
+               stop();
+               preview->get_canvasview()->preview_option();
+       }
+}
+
+void studio::Widget_Preview::stoprender()
+{
+       if(preview)
+       {
+               preview->renderer.detach();
+       }
+}
+       
+void studio::Widget_Preview::eraseall()
+{
+       stop();
+       stoprender();
+       
+       currentbuf.clear();
+       currentindex = 0;
+       timedisp = 0;
+       queue_draw();
+       
+       if(preview)
+       {
+               preview->clear();
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/preview.h b/synfig-studio/trunk/src/gtkmm/preview.h
new file mode 100644 (file)
index 0000000..780f689
--- /dev/null
@@ -0,0 +1,257 @@
+/* === S I N F G =========================================================== */
+/*!    \file preview.h
+**     \brief Previews an animation
+**
+**     $Id: preview.h,v 1.2 2005/01/10 08:13:44 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_PREVIEW_H
+#define __SINFG_PREVIEW_H
+
+/* === H E A D E R S ======================================================= */
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/table.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbuf.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/scrollbar.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/canvasview.h>
+
+#include <sinfg/time.h>
+#include <sinfg/vector.h>
+#include <sinfg/general.h>
+#include <sinfg/renddesc.h>
+#include <sinfg/canvas.h>
+
+#include "widget_sound.h"
+
+#include <ETL/handle>
+#include <ETL/clock>
+
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class AsyncRenderer;
+       
+class Preview : public sigc::trackable, public etl::shared_object
+{
+public:
+       struct FlipbookElem
+       {
+               float                                           t;
+               Glib::RefPtr<Gdk::Pixbuf>       buf; //at whatever resolution they are rendered at (resized at run time)
+       };
+
+       etl::handle<studio::AsyncRenderer>      renderer;
+       
+       sigc::signal<void, Preview *>   signal_destroyed_;      //so things can reference us without fear
+       
+       typedef std::vector<FlipbookElem>        FlipBook;
+private:
+       
+       FlipBook                        frames;
+       
+       studio::CanvasView::LooseHandle canvasview;
+
+       //sinfg::RendDesc               description; //for rendering the preview...
+       float   zoom,fps;
+       float   begintime,endtime;
+       bool    overbegin,overend;
+       int             quality;
+
+       float   global_fps;
+
+       //expose the frame information etc.
+       class Preview_Target;
+       void frame_finish(const Preview_Target *);
+       
+       sigc::signal0<void>     sig_changed;
+       
+public:
+               
+       Preview(const studio::CanvasView::LooseHandle &h = studio::CanvasView::LooseHandle(), 
+                               float zoom = 0.5f, float fps = 15);
+       ~Preview();
+       
+       float   get_zoom() const {return zoom;}
+       void    set_zoom(float z){zoom = z;}
+       
+       float   get_fps() const {return fps;}
+       void    set_fps(float f){fps = f;}
+       
+       float   get_global_fps() const {return global_fps;}
+       void    set_global_fps(float f){global_fps = f;}
+       
+       float   get_begintime() const   
+       {
+               if(overbegin)
+                       return begintime;
+               else if(canvasview)
+                       return get_canvas()->rend_desc().get_time_start();
+               else return -1;
+       }
+       
+       float   get_endtime() const
+       {
+               if(overend)
+                       return endtime;
+               else if(canvasview)
+                       return get_canvas()->rend_desc().get_time_end();
+               else return -1;
+       }
+       
+       void    set_begintime(float t)  {begintime = t;}
+       void    set_endtime(float t)    {endtime = t;}
+       
+       bool get_overbegin() const {return overbegin;}
+       void set_overbegin(bool b) {overbegin = b;}
+       
+       bool get_overend() const {return overend;}
+       void set_overend(bool b) {overend = b;}
+       
+       int             get_quality() const {return quality;}
+       void    set_quality(int i)      {quality = i;}
+       
+       sinfg::Canvas::Handle   get_canvas() const {return canvasview->get_canvas();}
+       studio::CanvasView::Handle      get_canvasview() const {return canvasview;}
+       
+       void set_canvasview(const studio::CanvasView::LooseHandle &h);
+       
+       //signal interface
+       sigc::signal<void, Preview *> & signal_destroyed() { return signal_destroyed_; }
+       //sigc::signal<void, const sinfg::RendDesc &>   &signal_desc_change() {return signal_desc_change_;}
+       
+       //functions for exposing iterators through the preview
+       FlipBook::iterator      begin()         {return frames.begin();}
+       FlipBook::iterator      end()           {return frames.end();}
+       
+       FlipBook::const_iterator        begin() const {return frames.begin();}
+       FlipBook::const_iterator        end() const       {return frames.end();}
+       
+       void clear() {frames.clear();}
+       
+       unsigned int                            numframes() const  {return frames.size();}
+       
+       void render();
+       
+       sigc::signal0<void>     &signal_changed() { return sig_changed; }
+};
+
+class Widget_Preview : public Gtk::Table
+{
+       Gtk::DrawingArea        draw_area;
+       Gtk::Adjustment         adj_time_scrub; //the adjustment for the managed scrollbar
+       Gtk::HScrollbar         scr_time_scrub;
+       Gtk::ToggleButton       b_loop;
+               
+       //Glib::RefPtr<Gdk::GC>         gc_area;
+       Glib::RefPtr<Gdk::Pixbuf>       currentbuf;
+       int                                                     currentindex;
+       //double                                                timeupdate;
+       double                                          timedisp;
+       double                                          audiotime;
+       
+       //sound stuff
+       etl::handle<AudioContainer>     audio;
+       sigc::connection        scrstartcon;
+       sigc::connection        scrstopcon;
+       sigc::connection        scrubcon;
+       
+       //preview encapsulation
+       etl::handle<Preview>    preview;
+       sigc::connection                prevchanged;
+       
+       Widget_Sound                    disp_sound;
+       Gtk::Adjustment                 adj_sound;
+       
+       Gtk::Label                              l_lasttime;
+       
+       //only for internal stuff, doesn't set anything
+       bool    playing;
+       bool    singleframe;
+       
+       //for accurate time tracking
+       etl::clock      timer;
+       
+       //int           curindex; //for later   
+       SigC::Connection        timecon;
+       
+       void slider_move(); //later to be a time_slider that's cooler
+       bool play_update();
+       void play_stop();
+       //bool play_frameupdate();
+       void update();
+               
+       void scrub_updated(double t);
+       
+       void repreview();
+       
+       void whenupdated();
+       
+       void eraseall();
+       
+       bool scroll_move_event(GdkEvent *);
+       void disconnect_preview(Preview *);
+       
+       bool redraw(GdkEventExpose *heh = 0);
+       void preview_draw();
+       
+       sigc::signal<void,float>        signal_play_;
+       sigc::signal<void>                      signal_stop_;
+       sigc::signal<void,float>        signal_seek_;
+       
+public:
+       
+       Widget_Preview();
+       ~Widget_Preview();
+       
+       //sets a signal to identify disconnection (so we don't hold onto it)...
+       void set_preview(etl::handle<Preview> prev);
+       void set_audioprofile(etl::handle<AudioProfile> p);
+       void set_audio(etl::handle<AudioContainer> a);
+
+       void clear();
+
+       void play();
+       void stop();
+       void seek(float t);
+
+       void stoprender();
+
+       sigc::signal<void,float>        &signal_play() {return signal_play_;}
+       sigc::signal<void>      &signal_stop() {return signal_stop_;}
+       sigc::signal<void,float>        &signal_seek() {return signal_seek_;}
+
+       bool get_loop_flag() const {return b_loop.get_active();}
+       void set_loop_flag(bool b) {return b_loop.set_active(b);}
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renddesc.cpp b/synfig-studio/trunk/src/gtkmm/renddesc.cpp
new file mode 100644 (file)
index 0000000..8a709d7
--- /dev/null
@@ -0,0 +1,477 @@
+/* === S I N F G =========================================================== */
+/*!    \file renddesc.cpp
+**     \brief Template File
+**
+**     $Id: renddesc.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renddesc.h"
+#include <gtkmm/label.h>
+#include <gtkmm/frame.h>
+#include <ETL/misc>
+#include <sinfg/general.h>
+//#include <gtkmm/seperator.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef SINFG_MAX_PIXEL_WIDTH
+#define SINFG_MAX_PIXEL_WIDTH  (~(1<<31))
+#endif
+
+#ifndef SINFG_MAX_PIXEL_HEIGHT
+#define SINFG_MAX_PIXEL_HEIGHT (~(1<<31))
+#endif
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+#ifndef DPM2DPI
+#define DPM2DPI(x)     ((x)/39.3700787402)
+#define DPI2DPM(x)     ((x)*39.3700787402)
+#endif
+
+#ifndef METERS2INCHES
+#define METERS2INCHES(x)       ((x)*39.3700787402)
+#define INCHES2METERS(x)       ((x)/39.3700787402)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_RendDesc::Widget_RendDesc():
+       Gtk::Table(1,2,false),
+       adjustment_width(1,1,SINFG_MAX_PIXEL_WIDTH),
+       adjustment_height(1,1,SINFG_MAX_PIXEL_HEIGHT),
+       adjustment_xres(0,0,10000000),
+       adjustment_yres(0,0,10000000),
+       adjustment_phy_width(0,0,10000000),
+       adjustment_phy_height(0,0,10000000),
+       adjustment_fps(0,0,10000000),
+       adjustment_span(0,0,10000000)
+{
+       update_lock=0;
+       
+       Gtk::Frame *size_frame=manage(new Gtk::Frame(_("Image Size")));
+       Gtk::Frame *area_frame=manage(new Gtk::Frame(_("Image Area")));
+       time_frame=manage(new Gtk::Frame(_("Time")));
+       
+       Gtk::Table *size_table=manage(new Gtk::Table(2,2,false));
+       size_frame->add(*size_table);
+
+       Gtk::Table *area_table=manage(new Gtk::Table(2,2,false));
+       area_frame->add(*area_table);
+
+       time_table=manage(new Gtk::Table(2,2,false));
+       time_frame->add(*time_table);
+
+       Gtk::Frame *other_frame=manage(new Gtk::Frame(_("Other")));
+       Gtk::Table *other_table=manage(new Gtk::Table(2,2,false));
+       other_frame->add(*other_table);
+
+       Gtk::Frame *lock_frame=manage(new Gtk::Frame(_("Locks and Links")));
+       Gtk::Table *lock_table=manage(new Gtk::Table(2,2,false));
+       lock_frame->add(*lock_table);
+       
+       entry_width=manage(new Gtk::SpinButton(adjustment_width,1,0));
+       entry_height=manage(new Gtk::SpinButton(adjustment_height,1,0));        
+       entry_width->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_width_changed));
+       entry_height->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_height_changed));
+       size_table->attach(*manage(new Gtk::Label(_("Width"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       size_table->attach(*manage(new Gtk::Label(_("Height"))), 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       size_table->attach(*entry_width, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       size_table->attach(*entry_height, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       
+       entry_xres=manage(new Gtk::SpinButton(adjustment_xres,0.5,1));
+       entry_yres=manage(new Gtk::SpinButton(adjustment_yres,0.5,1));  
+       entry_xres->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_xres_changed));
+       entry_yres->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_yres_changed));
+       size_table->attach(*manage(new Gtk::Label(_("XRes"))), 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       size_table->attach(*manage(new Gtk::Label(_("YRes"))), 2, 3, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       size_table->attach(*entry_xres, 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       size_table->attach(*entry_yres, 3, 4, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+
+       entry_phy_width=manage(new Gtk::SpinButton(adjustment_phy_width,0.25,2));
+       entry_phy_height=manage(new Gtk::SpinButton(adjustment_phy_height,0.25,2));     
+       entry_phy_width->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_phy_width_changed));
+       entry_phy_height->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_phy_height_changed));
+       size_table->attach(*manage(new Gtk::Label(_("PhyWidth"))), 4, 5, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       size_table->attach(*manage(new Gtk::Label(_("PhyHeight"))), 4, 5, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       size_table->attach(*entry_phy_width, 5, 6, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       size_table->attach(*entry_phy_height, 5, 6, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+
+
+       entry_span=manage(new Gtk::SpinButton(adjustment_span,0.1,4));  
+       entry_span->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_span_changed));
+       size_table->attach(*manage(new Gtk::Label(_("Span"))), 0, 1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       size_table->attach(*entry_span, 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+
+       entry_tl=manage(new Widget_Vector());
+       entry_br=manage(new Widget_Vector());
+       entry_tl->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_tl_changed));
+       entry_br->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_br_changed));
+       area_table->attach(*manage(new Gtk::Label(_("Top-Left"))), 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       area_table->attach(*manage(new Gtk::Label(_("Bottom-Right"))), 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       area_table->attach(*entry_tl, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       area_table->attach(*entry_br, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+
+       entry_fps=manage(new Gtk::SpinButton(adjustment_fps,1,5));
+       entry_start_time=manage(new Widget_Time());
+       entry_end_time=manage(new Widget_Time());       
+       //entry_start_frame=manage(new Gtk::SpinButton(adjustment_start_frame,1,0));
+       //entry_end_frame=manage(new Gtk::SpinButton(adjustment_end_frame,1,0));        
+       entry_fps->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_fps_changed));
+       entry_start_time->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_start_time_changed));
+       entry_end_time->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_end_time_changed));
+       //entry_start_frame->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_start_frame_changed));
+       //entry_end_frame->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_end_frame_changed));
+       time_table->attach(*manage(new Gtk::Label(_("FPS"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       time_table->attach(*manage(new Gtk::Label(_("Start Time"))), 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       time_table->attach(*manage(new Gtk::Label(_("End Time"))), 2, 3, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       //time_table->attach(*manage(new Gtk::Label(_("Start Frame"))), 4, 5, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       //time_table->attach(*manage(new Gtk::Label(_("End Frame"))), 4, 5, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       time_table->attach(*entry_fps, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       time_table->attach(*entry_start_time, 3, 4, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       time_table->attach(*entry_end_time, 3, 4, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+       //time_table->attach(*entry_start_frame, 5, 6, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       //time_table->attach(*entry_end_frame, 5, 6, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+
+       entry_focus=manage(new Widget_Vector());
+       entry_focus->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_RendDesc::on_focus_changed));
+       other_table->attach(*manage(new Gtk::Label(_("Focus Point"))), 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       other_table->attach(*entry_focus, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+
+
+
+       toggle_px_aspect=manage(new Gtk::CheckButton(_("Pixel Aspect")));
+       toggle_px_width=manage(new Gtk::CheckButton(_("Pixel Width")));
+       toggle_px_height=manage(new Gtk::CheckButton(_("Pixel Height")));
+
+       toggle_im_aspect=manage(new Gtk::CheckButton(_("Image Aspect")));
+       toggle_im_width=manage(new Gtk::CheckButton(_("Image Width")));
+       toggle_im_height=manage(new Gtk::CheckButton(_("Image Height")));
+       toggle_im_span=manage(new Gtk::CheckButton(_("Image Span")));
+
+       toggle_px_aspect->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_px_width->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_px_height->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_im_aspect->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_im_width->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_im_height->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+       toggle_im_span->signal_toggled().connect(sigc::mem_fun(*this, &studio::Widget_RendDesc::on_lock_changed));
+
+       lock_table->attach(*toggle_px_aspect, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       lock_table->attach(*toggle_px_width, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       lock_table->attach(*toggle_px_height, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+
+       lock_table->attach(*toggle_im_aspect, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       lock_table->attach(*toggle_im_width, 1, 2, 1, 2, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       lock_table->attach(*toggle_im_height, 1, 2, 2, 3, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       lock_table->attach(*toggle_im_span, 1, 2, 3, 4, Gtk::SHRINK, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+
+
+       lock_frame->show_all();
+       other_frame->show_all();
+       size_frame->show_all();
+       area_frame->show_all();
+       time_frame->show_all();
+       attach(*size_frame, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       attach(*area_frame, 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       attach(*lock_frame, 0, 1, 2,3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+       attach(*time_frame, 0, 1, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       attach(*other_frame, 0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);   
+}
+
+Widget_RendDesc::~Widget_RendDesc()
+{
+}
+
+void Widget_RendDesc::set_rend_desc(const sinfg::RendDesc &rend_desc)
+{
+       if(update_lock)return;
+       
+       rend_desc_=rend_desc;
+       refresh();
+}
+
+void
+Widget_RendDesc::refresh()
+{
+       UpdateLock lock(update_lock);
+       adjustment_width.set_value(rend_desc_.get_w());
+       adjustment_height.set_value(rend_desc_.get_h());
+       adjustment_phy_width.set_value(METERS2INCHES(rend_desc_.get_physical_w()));
+       adjustment_phy_height.set_value(METERS2INCHES(rend_desc_.get_physical_h()));
+       adjustment_xres.set_value(DPM2DPI(rend_desc_.get_x_res()));
+       adjustment_yres.set_value(DPM2DPI(rend_desc_.get_y_res()));
+       entry_start_time->set_fps(rend_desc_.get_frame_rate());
+       entry_start_time->set_value(rend_desc_.get_time_start());
+       entry_end_time->set_fps(rend_desc_.get_frame_rate());
+       entry_end_time->set_value(rend_desc_.get_time_end());
+
+       adjustment_fps.set_value(rend_desc_.get_frame_rate());
+       adjustment_span.set_value(rend_desc_.get_span());
+       entry_tl->set_value(rend_desc_.get_tl());
+       entry_br->set_value(rend_desc_.get_br());
+       entry_focus->set_value(rend_desc_.get_focus());
+
+       toggle_px_aspect->set_active((bool)(rend_desc_.get_flags()&RendDesc::PX_ASPECT));
+       toggle_px_width->set_active((bool)(rend_desc_.get_flags()&RendDesc::PX_W));
+       toggle_px_height->set_active((bool)(rend_desc_.get_flags()&RendDesc::PX_H));
+
+       toggle_im_aspect->set_active((bool)(rend_desc_.get_flags()&RendDesc::IM_ASPECT));
+       toggle_im_width->set_active((bool)(rend_desc_.get_flags()&RendDesc::IM_W));
+       toggle_im_height->set_active((bool)(rend_desc_.get_flags()&RendDesc::IM_H));
+       toggle_im_span->set_active((bool)(rend_desc_.get_flags()&RendDesc::IM_SPAN));   
+}
+
+void Widget_RendDesc::apply_rend_desc(const sinfg::RendDesc &rend_desc)
+{
+       set_rend_desc(rend_desc);
+}
+
+const sinfg::RendDesc &
+Widget_RendDesc::get_rend_desc()
+{
+       return rend_desc_;
+}
+
+void
+Widget_RendDesc::on_width_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_w(round_to_int(adjustment_width.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_lock_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+
+#define DO_TOGGLE(x,y) if(toggle_ ## x->get_active()) \
+               rend_desc_.set_flags(rend_desc_.get_flags()|RendDesc:: y); \
+       else \
+               rend_desc_.set_flags(rend_desc_.get_flags()&~RendDesc:: y)
+
+       DO_TOGGLE(px_aspect,PX_ASPECT);
+       DO_TOGGLE(px_width,PX_W);
+       DO_TOGGLE(px_height,PX_H);
+
+       DO_TOGGLE(im_aspect,IM_ASPECT);
+       DO_TOGGLE(im_width,IM_W);
+       DO_TOGGLE(im_height,IM_H);
+       DO_TOGGLE(im_span,IM_SPAN);
+
+#undef DO_TOGGLE
+       
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_height_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_h(round_to_int(adjustment_height.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_phy_width_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_physical_w(INCHES2METERS(adjustment_phy_width.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_phy_height_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_physical_h(INCHES2METERS(adjustment_phy_height.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_xres_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_x_res(DPI2DPM(adjustment_xres.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_yres_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_y_res(DPI2DPM(adjustment_yres.get_value()));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_start_time_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_time_start(entry_start_time->get_value());
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_end_time_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_time_end(entry_end_time->get_value());
+       refresh();
+       signal_changed()();
+}
+
+/*
+void
+Widget_RendDesc::on_start_frame_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_frame_start((int)(adjustment_start_frame.get_value()+0.5));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_end_frame_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_frame_end((int)(adjustment_end_frame.get_value()+0.5));
+       refresh();
+       signal_changed()();
+}
+*/
+
+void
+Widget_RendDesc::on_fps_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_frame_rate((int)(adjustment_fps.get_value()+0.5));
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_tl_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_tl(entry_tl->get_value());
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_br_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_br(entry_br->get_value());
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_focus_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_focus(entry_focus->get_value());
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::on_span_changed()
+{
+       if(update_lock)return;
+       UpdateLock lock(update_lock);
+       rend_desc_.set_span(adjustment_span.get_value());
+       refresh();
+       signal_changed()();
+}
+
+void
+Widget_RendDesc::disable_time_section()
+{
+       time_frame->set_sensitive(false);
+       
+/*
+       Gtk::Table::TableList &list=time_table->children();
+       Gtk::Table::TableList::iterator iter;
+       for(iter=list.begin();iter!=list.end();iter++)
+               iter->get_widget()->set_sensitive(false);
+*/     
+}
+       
+void
+Widget_RendDesc::enable_time_section()
+{
+       time_frame->set_sensitive(true);
+
+/*
+       Gtk::Table::TableList &list=time_table->children();
+       Gtk::Table::TableList::iterator iter;
+       for(iter=list.begin();iter!=list.end();iter++)
+               iter->get_widget()->set_sensitive(true);
+
+*/
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renddesc.h b/synfig-studio/trunk/src/gtkmm/renddesc.h
new file mode 100644 (file)
index 0000000..5c0a4bd
--- /dev/null
@@ -0,0 +1,150 @@
+/*! ========================================================================
+** Sinfg
+** Template Header File
+** $Id: renddesc.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_RENDDESC_H
+#define __SINFG_GTKMM_RENDDESC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/table.h>
+#include <gtkmm/frame.h>
+#include <sinfg/renddesc.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/checkbutton.h>
+#include "widget_vector.h"
+#include "widget_time.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_RendDesc : public Gtk::Table
+{
+       sinfg::RendDesc rend_desc_;
+       sigc::signal<void> signal_changed_;
+
+       Gtk::Adjustment adjustment_width;
+       Gtk::Adjustment adjustment_height;
+       Gtk::Adjustment adjustment_xres;
+       Gtk::Adjustment adjustment_yres;
+       Gtk::Adjustment adjustment_phy_width;
+       Gtk::Adjustment adjustment_phy_height;
+       Gtk::Adjustment adjustment_fps;
+       //Gtk::Adjustment adjustment_start_time;
+       //Gtk::Adjustment adjustment_end_time;
+       //Gtk::Adjustment adjustment_start_frame;
+       //Gtk::Adjustment adjustment_end_frame;
+       Gtk::Adjustment adjustment_span;
+       
+       Gtk::SpinButton *entry_width;   
+       Gtk::SpinButton *entry_height;  
+       Gtk::SpinButton *entry_xres;    
+       Gtk::SpinButton *entry_yres;    
+       Gtk::SpinButton *entry_phy_width;       
+       Gtk::SpinButton *entry_phy_height;      
+       Gtk::SpinButton *entry_fps;     
+//     Gtk::SpinButton *entry_start_time;      
+//     Gtk::SpinButton *entry_end_time;        
+//     Gtk::SpinButton *entry_start_frame;     
+//     Gtk::SpinButton *entry_end_frame;       
+       Gtk::SpinButton *entry_span;    
+
+       Gtk::CheckButton *toggle_px_aspect;
+       Gtk::CheckButton *toggle_px_width;
+       Gtk::CheckButton *toggle_px_height;
+
+       Gtk::CheckButton *toggle_im_aspect;
+       Gtk::CheckButton *toggle_im_width;
+       Gtk::CheckButton *toggle_im_height;
+       Gtk::CheckButton *toggle_im_span;
+
+       Gtk::Table *time_table;
+       Gtk::Frame *time_frame;
+
+       Widget_Vector *entry_tl;
+       Widget_Vector *entry_br;
+
+       Widget_Vector *entry_focus;
+
+       Widget_Time *entry_start_time;
+       Widget_Time *entry_end_time;
+
+       mutable int update_lock;
+
+       struct UpdateLock
+       {
+               int &locked;
+               UpdateLock(int &locked):locked(locked){locked++;}
+               ~UpdateLock(){locked--;}
+       };
+       
+public:
+
+       sigc::signal<void> &signal_changed() { return signal_changed_; }
+
+       Widget_RendDesc();
+       ~Widget_RendDesc();
+       
+       //! Sets the RendDesc
+       void set_rend_desc(const sinfg::RendDesc &rend_desc);
+
+       //! Applies the given RendDesc to the current RendDesc
+       void apply_rend_desc(const sinfg::RendDesc &rend_desc);
+
+       //! Retrieves the current RendDesc
+       const sinfg::RendDesc &get_rend_desc();
+
+       void disable_time_section();
+       
+       void enable_time_section();
+       
+       void refresh();
+private:
+       
+       void on_width_changed();
+       void on_height_changed();
+       void on_xres_changed();
+       void on_yres_changed();
+       void on_phy_width_changed();
+       void on_phy_height_changed();
+       void on_tl_changed();
+       void on_br_changed();
+       void on_fps_changed();
+       void on_start_time_changed();
+       void on_end_time_changed();
+       //void on_start_frame_changed();
+       //void on_end_frame_changed();
+       void on_lock_changed();
+       void on_focus_changed();
+       void on_span_changed();
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/render.cpp b/synfig-studio/trunk/src/gtkmm/render.cpp
new file mode 100644 (file)
index 0000000..9328b2b
--- /dev/null
@@ -0,0 +1,283 @@
+/* === S I N F G =========================================================== */
+/*!    \file render.cpp
+**     \brief Template File
+**
+**     $Id: render.cpp,v 1.2 2005/01/10 08:13:44 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "render.h"
+#include "app.h"
+#include <gtkmm/frame.h>
+#include <sinfg/target_scanline.h>
+#include <sinfg/canvas.h>
+#include "asyncrenderer.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+RenderSettings::RenderSettings(Gtk::Window& parent,handle<sinfgapp::CanvasInterface> canvas_interface):
+       Gtk::Dialog(_("Render Settings"),parent,false,true),
+       canvas_interface_(canvas_interface),
+       adjustment_quality(3,0,9),
+       entry_quality(adjustment_quality,1,0),
+       adjustment_antialias(1,1,31),
+       entry_antialias(adjustment_antialias,1,0),
+       toggle_single_frame(_("Use Current Frame"))
+{
+       widget_rend_desc.show();
+       widget_rend_desc.signal_changed().connect(sigc::mem_fun(*this,&studio::RenderSettings::on_rend_desc_changed));
+       widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
+       
+       canvas_interface->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&RenderSettings::on_rend_desc_changed));
+       
+       menu_target=manage(new class Gtk::Menu());
+
+       menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Auto"),
+                       sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),String())
+               ));
+
+       sinfg::Target::Book::iterator iter;
+       sinfg::Target::Book book(sinfg::Target::book());
+       
+       for(iter=book.begin();iter!=book.end();iter++)
+       {
+               menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->first,
+                       sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),iter->first)
+               ));
+       }
+       optionmenu_target.set_menu(*menu_target);
+
+       optionmenu_target.set_history(0);
+       
+       
+       
+       
+
+       Gtk::Button *choose_button(manage(new class Gtk::Button(Gtk::StockID(_("Choose...")))));
+       choose_button->show();
+       choose_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_choose_pressed));
+       
+       Gtk::Frame *target_frame=manage(new Gtk::Frame(_("Target")));
+       Gtk::Table *target_table=manage(new Gtk::Table(2,2,false));
+       target_frame->add(*target_table);
+       target_table->attach(*manage(new Gtk::Label(_("Filename"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       target_table->attach(entry_filename, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       target_table->attach(*choose_button, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       target_table->attach(*manage(new Gtk::Label(_("Target"))), 3, 4, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       target_table->attach(optionmenu_target, 4, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       get_vbox()->pack_start(*target_frame);
+
+       toggle_single_frame.signal_toggled().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_single_frame_toggle));
+
+
+       Gtk::Frame *settings_frame=manage(new Gtk::Frame(_("Settings")));
+       Gtk::Table *settings_table=manage(new Gtk::Table(2,2,false));
+       settings_frame->add(*settings_table);
+       settings_table->attach(*manage(new Gtk::Label(_("Quality"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       settings_table->attach(entry_quality, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);  
+       settings_table->attach(*manage(new Gtk::Label(_("Anti-Alias"))), 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       settings_table->attach(entry_antialias, 3, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       settings_table->attach(toggle_single_frame, 4, 5, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       get_vbox()->pack_start(*settings_frame);
+       
+       
+
+
+       get_vbox()->pack_start(widget_rend_desc);
+       
+       
+       Gtk::Button *render_button(manage(new class Gtk::Button(Gtk::StockID("Render"))));
+       render_button->show();
+       add_action_widget(*render_button,1);
+       render_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_render_pressed));
+
+       Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))));
+       cancel_button->show();
+       add_action_widget(*cancel_button,0);
+       cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_cancel_pressed));
+
+       //set_default_response(1);
+       
+       set_title(_("Render Settings")+String(" - ")+canvas_interface_->get_canvas()->get_name());
+
+
+       toggle_single_frame.set_active(true);
+       widget_rend_desc.disable_time_section();
+       
+
+       try
+       {
+               entry_filename.set_text(Glib::build_filename(Glib::get_home_dir(),"Desktop/output.png"));
+       }
+       catch(...)
+       {
+               sinfg::warning("Averted crash!");
+               entry_filename.set_text("output.png");
+       }
+       
+       get_vbox()->show_all();
+}
+
+RenderSettings::~RenderSettings()
+{
+}
+
+void
+RenderSettings::on_rend_desc_changed()
+{
+       widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
+}
+
+void
+RenderSettings::set_target(sinfg::String name)
+{
+       target_name=name;
+}
+
+void
+RenderSettings::on_choose_pressed()
+{
+       String filename=entry_filename.get_text();
+       if(App::dialog_saveas_file("Save Render As",filename))
+               entry_filename.set_text(filename);
+}
+
+void
+RenderSettings::on_render_pressed()
+{
+       String filename=entry_filename.get_text();
+       
+       if(filename.empty())
+       {
+               canvas_interface_->get_ui_interface()->error(_("You must supply a filename!"));
+               return;
+       }
+
+       // If the target type is not yet defined,
+       // try to figure it out from the outfile.
+       if(target_name.empty())
+       {
+               try
+               {
+                       String ext=String(find(filename.begin(),filename.end(),'.')+1,filename.end());
+                       if(Target::ext_book().count(ext))
+                               target_name=Target::ext_book()[ext];
+                       else
+                               target_name=ext;
+               }
+               catch(std::runtime_error x)
+               {
+                       canvas_interface_->get_ui_interface()->error(_("Unable to determine proper target from filename."));
+                       return;                 
+               }
+       }
+
+       if(filename.empty() && target_name!="null")
+       {
+               canvas_interface_->get_ui_interface()->error(_("A filename is required for this target"));
+               return;
+       }
+
+       Target::Handle target=Target::create(target_name,filename);
+       if(!target)
+       {
+               canvas_interface_->get_ui_interface()->error(_("Unable to create target for ")+filename);
+               return;
+       }
+
+       hide();
+       
+       target->set_canvas(canvas_interface_->get_canvas());
+       RendDesc rend_desc(widget_rend_desc.get_rend_desc());
+       rend_desc.set_antialias((int)adjustment_antialias.get_value());
+       
+       // If we are to only render the current frame
+       if(toggle_single_frame.get_active())
+               rend_desc.set_time(canvas_interface_->get_time());
+
+       target->set_rend_desc(&rend_desc);
+       target->set_quality((int)adjustment_quality.get_value());
+
+       canvas_interface_->get_ui_interface()->task(_("Rendering ")+filename);
+
+       if(async_renderer)
+       {
+               async_renderer->stop();
+               async_renderer.detach();
+       }
+       async_renderer=new AsyncRenderer(target);
+       async_renderer->signal_finished().connect( sigc::mem_fun(*this,&RenderSettings::on_finished));
+       async_renderer->start();
+       /*
+       if(!target->render(canvas_interface_->get_ui_interface().get()))
+       {
+               canvas_interface_->get_ui_interface()->error(_("Render Failure"));
+               canvas_interface_->get_ui_interface()->amount_complete(0,10000);
+               return;
+       }
+       
+       // Success!
+       canvas_interface_->get_ui_interface()->task(filename+_(" rendered sucessfuly"));        
+       canvas_interface_->get_ui_interface()->amount_complete(0,10000);
+       */
+       return; 
+}
+
+void
+RenderSettings::on_finished()
+{
+       canvas_interface_->get_ui_interface()->task(_("File rendered sucessfuly"));     
+       canvas_interface_->get_ui_interface()->amount_complete(0,10000);
+}
+       
+void
+RenderSettings::on_cancel_pressed()
+{
+       hide();
+}
+
+void
+RenderSettings::on_single_frame_toggle()
+{
+       if(toggle_single_frame.get_active())
+               widget_rend_desc.disable_time_section();
+       else
+               widget_rend_desc.enable_time_section();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/render.h b/synfig-studio/trunk/src/gtkmm/render.h
new file mode 100644 (file)
index 0000000..aec2a2c
--- /dev/null
@@ -0,0 +1,101 @@
+/* === S I N F G =========================================================== */
+/*!    \file render.h
+**     \brief Template Header
+**
+**     $Id: render.h,v 1.2 2005/01/10 08:13:44 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_GTKMM_RENDER_H
+#define __SINFG_STUDIO_GTKMM_RENDER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/table.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/optionmenu.h>
+
+#include <sinfg/string.h>
+
+#include <sinfgapp/canvasinterface.h>
+
+#include "renddesc.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio
+{
+class AsyncRenderer;
+       
+class RenderSettings : public Gtk::Dialog
+{
+       Gtk::Tooltips tooltips;
+
+       etl::handle<sinfgapp::CanvasInterface> canvas_interface_;
+       Widget_RendDesc widget_rend_desc;
+
+       Gtk::Entry entry_filename;
+
+       Gtk::Adjustment adjustment_quality;
+       Gtk::SpinButton entry_quality;  
+
+       Gtk::Adjustment adjustment_antialias;
+       Gtk::SpinButton entry_antialias;        
+
+       Gtk::CheckButton toggle_single_frame;
+
+       Gtk::OptionMenu optionmenu_target;
+       Gtk::Menu *menu_target;
+
+       sinfg::String target_name;
+       
+       void set_target(sinfg::String name);
+
+       etl::handle<AsyncRenderer> async_renderer;
+
+public:
+       RenderSettings(Gtk::Window& parent,etl::handle<sinfgapp::CanvasInterface> canvas_interface);
+       ~RenderSettings();
+
+private:
+
+       void on_rend_desc_changed();
+       void on_single_frame_toggle();
+       void on_choose_pressed();
+       void on_render_pressed();
+       void on_cancel_pressed();
+       
+       void on_finished();
+}; // END of class RenderSettings
+       
+}; // END of namespace studio
+
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_bbox.cpp b/synfig-studio/trunk/src/gtkmm/renderer_bbox.cpp
new file mode 100644 (file)
index 0000000..b28d50a
--- /dev/null
@@ -0,0 +1,141 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_bbox.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_bbox.h"
+#include "workarea.h"
+#include "canvasview.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_BBox::Renderer_BBox()
+{
+}
+
+Renderer_BBox::~Renderer_BBox()
+{
+}
+
+const sinfg::Rect&
+Renderer_BBox::get_bbox()
+{
+       return get_work_area()->get_canvas_view()->get_bbox();
+}
+
+void
+Renderer_BBox::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+//     const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+//     std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+//     const sinfg::Vector::value_type
+//             x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+//             y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+//     const int
+//             tile_w(get_work_area()->get_tile_w()),
+//             tile_h(get_work_area()->get_tile_h());
+
+//     const int
+//             w(get_w()),
+//             h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       //const sinfg::Vector grid_size(get_grid_size());
+
+       const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+//     const sinfg::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
+       const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+//     const sinfg::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
+       const float pw(get_pw()),ph(get_ph());
+       
+       const sinfg::Point curr_point(get_bbox().get_min());
+       const sinfg::Point drag_point(get_bbox().get_max());
+       if(get_bbox().area()<10000000000000000.0)
+       {
+               gc->set_function(Gdk::INVERT);
+               gc->set_rgb_fg_color(Gdk::Color("#FFFFFF"));
+               //gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+               Point tl(std::min(drag_point[0],curr_point[0]),std::min(drag_point[1],curr_point[1]));
+               Point br(std::max(drag_point[0],curr_point[0]),std::max(drag_point[1],curr_point[1]));
+
+               tl[0]=(tl[0]-window_startx)/pw;
+               tl[1]=(tl[1]-window_starty)/ph;
+               br[0]=(br[0]-window_startx)/pw;
+               br[1]=(br[1]-window_starty)/ph;
+               if(tl[0]>br[0])
+                       swap(tl[0],br[0]);
+               if(tl[1]>br[1])
+                       swap(tl[1],br[1]);
+               
+               drawable->draw_rectangle(gc,false,
+                       round_to_int(tl[0]),
+                       round_to_int(tl[1]),
+                       round_to_int(br[0]-tl[0]),
+                       round_to_int(br[1]-tl[1])
+               );
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_bbox.h b/synfig-studio/trunk/src/gtkmm/renderer_bbox.h
new file mode 100644 (file)
index 0000000..7b39d77
--- /dev/null
@@ -0,0 +1,62 @@
+/* === S I N F G =========================================================== */
+/*!    \file renderer_bbox.h
+**     \brief Template Header
+**
+**     $Id: renderer_bbox.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_BBOX_H
+#define __SINFG_RENDERER_BBOX_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+#include <sinfg/vector.h>
+#include <sinfg/rect.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_BBox : public studio::WorkAreaRenderer
+{
+       sinfg::Rect bbox;
+       
+public:
+       Renderer_BBox();
+       ~Renderer_BBox();
+
+       const sinfg::Rect& get_bbox();
+
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+
+protected:
+       //bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_canvas.cpp b/synfig-studio/trunk/src/gtkmm/renderer_canvas.cpp
new file mode 100644 (file)
index 0000000..1f73c4a
--- /dev/null
@@ -0,0 +1,212 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_canvas.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_canvas.h"
+#include "workarea.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Canvas::~Renderer_Canvas()
+{
+}
+std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >&
+Renderer_Canvas::get_tile_book()
+{
+       return get_work_area()->get_tile_book();
+}
+
+bool
+Renderer_Canvas::get_full_frame()const
+{
+       return get_work_area()->get_full_frame();
+}
+
+int Renderer_Canvas::get_refreshes()const
+{
+       return get_work_area()->get_refreshes();
+}
+
+bool
+Renderer_Canvas::get_canceled()const
+{
+       return get_work_area()->get_canceled();
+}
+
+bool
+Renderer_Canvas::get_queued()const
+{
+       return get_work_area()->get_queued();
+}
+
+bool
+Renderer_Canvas::get_rendering()const
+{
+       return get_work_area()->get_rendering();
+}
+
+void
+Renderer_Canvas::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+//     const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+       std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+       const sinfg::Vector::value_type
+               x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+               y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+       const int
+               tile_w(get_work_area()->get_tile_w()),
+               tile_h(get_work_area()->get_tile_h());
+
+       const int
+               w(get_w()),
+               h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       if(!tile_book.empty())
+       if(get_full_frame())
+       {
+               if(tile_book[0].first)
+               {
+                       drawable->draw_pixbuf(
+                               gc, //GC
+                               tile_book[0].first, //pixbuf
+                               0, 0,   // Source X and Y
+                               round_to_int(x),round_to_int(y),        // Dest X and Y
+                               -1,-1,  // Width and Height
+                               Gdk::RGB_DITHER_MAX,            // RgbDither
+                               2, 2 // Dither offset X and Y
+                       );
+               }
+               if(tile_book[0].second!=get_refreshes() && get_canceled()==false && get_rendering()==false && get_queued()==false)
+                       get_work_area()->async_update_preview();
+       }
+       else
+       {
+               const int width_in_tiles(w/tile_w+(w%tile_w?1:0));
+               const int height_in_tiles(h/tile_h+(h%tile_h?1:0));
+                               
+               int u(0),v(0),tx,ty;
+               int u1(0),v1(0),u2(width_in_tiles), v2(height_in_tiles);
+
+               bool needs_refresh(false);
+               
+               u1=int(-x/tile_w);
+               v1=int(-y/tile_h);
+               u2=int((-x+drawable_w)/tile_w+1);
+               v2=int((-y+drawable_h)/tile_h+1);
+               if(u2>width_in_tiles)u2=width_in_tiles;
+               if(v2>height_in_tiles)v2=height_in_tiles;
+               if(u1<0)u1=0;
+               if(v1<0)v1=0;
+                       
+               for(v=v1;v<v2;v++)
+               {
+                       for(u=u1;u<u2;u++)
+                       {
+                               int index=v*width_in_tiles+u;
+                               if(tile_book.size()>index && tile_book[index].first)
+                               {
+                                       tx=u*tile_w;
+                                       ty=v*tile_w;
+
+                                       drawable->draw_pixbuf(
+                                               gc, //GC
+                                               tile_book[index].first, //pixbuf
+                                               0, 0,   // Source X and Y
+                                               round_to_int(x)+tx,round_to_int(y)+ty,  // Dest X and Y
+                                               -1,-1,  // Width and Height
+                                               Gdk::RGB_DITHER_MAX,            // RgbDither
+                                               2, 2 // Dither offset X and Y
+                                       );
+                               }
+                               if(tile_book[index].second!=get_refreshes())
+                                       needs_refresh=true;
+                       }
+               }
+               if(needs_refresh==true && get_canceled()==false && get_rendering()==false && get_queued()==false)
+               {
+                       //queue_render_preview();
+                       get_work_area()->async_update_preview();
+                       //update_preview();
+                       //return true;
+               }
+
+       }
+
+       // Draw the border around the rendered region
+       {
+               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);       
+               drawable->draw_rectangle(
+                       gc,
+                       false,  // Fill?
+                       round_to_int(x),round_to_int(y),        // x,y
+                       w,h     //w,h
+               );
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_canvas.h b/synfig-studio/trunk/src/gtkmm/renderer_canvas.h
new file mode 100644 (file)
index 0000000..d923343
--- /dev/null
@@ -0,0 +1,62 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_canvas.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_CANVAS_H
+#define __SINFG_RENDERER_CANVAS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Canvas : public studio::WorkAreaRenderer
+{
+       
+public:
+       ~Renderer_Canvas();
+
+       std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& get_tile_book();
+
+       bool get_full_frame()const;
+       
+       int get_refreshes()const;
+       bool get_canceled()const;
+       bool get_queued()const;
+       bool get_rendering()const;
+
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_dragbox.cpp b/synfig-studio/trunk/src/gtkmm/renderer_dragbox.cpp
new file mode 100644 (file)
index 0000000..c077dfc
--- /dev/null
@@ -0,0 +1,151 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_dragbox.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_dragbox.h"
+#include "workarea.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Dragbox::~Renderer_Dragbox()
+{
+}
+
+const sinfg::Point&
+Renderer_Dragbox::get_drag_point()const
+{
+       return get_work_area()->get_drag_point();
+}
+
+const sinfg::Point&
+Renderer_Dragbox::get_curr_point()const
+{
+       return get_work_area()->get_cursor_pos();
+}
+
+bool
+Renderer_Dragbox::get_enabled_vfunc()const
+{
+       return get_work_area()->get_dragging_mode()==WorkArea::DRAG_BOX;
+}
+
+
+void
+Renderer_Dragbox::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+       const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+//     std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+       const sinfg::Vector::value_type
+               x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+               y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+       const int
+               tile_w(get_work_area()->get_tile_w()),
+               tile_h(get_work_area()->get_tile_h());
+
+       const int
+               w(get_w()),
+               h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       //const sinfg::Vector grid_size(get_grid_size());
+
+       const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+       const sinfg::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
+       const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+       const sinfg::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
+       const float pw(get_pw()),ph(get_ph());
+       
+       const sinfg::Point& curr_point(get_curr_point());
+       const sinfg::Point& drag_point(get_drag_point());
+       
+       {
+               gc->set_function(Gdk::COPY);
+               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+               gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               //gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+               Point tl(std::min(drag_point[0],curr_point[0]),std::min(drag_point[1],curr_point[1]));
+               Point br(std::max(drag_point[0],curr_point[0]),std::max(drag_point[1],curr_point[1]));
+
+               tl[0]=(tl[0]-window_startx)/pw;
+               tl[1]=(tl[1]-window_starty)/ph;
+               br[0]=(br[0]-window_startx)/pw;
+               br[1]=(br[1]-window_starty)/ph;
+               if(tl[0]>br[0])
+                       swap(tl[0],br[0]);
+               if(tl[1]>br[1])
+                       swap(tl[1],br[1]);
+               
+               drawable->draw_rectangle(gc,false,
+                       round_to_int(tl[0]),
+                       round_to_int(tl[1]),
+                       round_to_int(br[0]-tl[0]),
+                       round_to_int(br[1]-tl[1])
+               );
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_dragbox.h b/synfig-studio/trunk/src/gtkmm/renderer_dragbox.h
new file mode 100644 (file)
index 0000000..0da3aa0
--- /dev/null
@@ -0,0 +1,60 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_dragbox.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_DRAGBOX_H
+#define __SINFG_RENDERER_DRAGBOX_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+#include <sinfg/vector.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Dragbox : public studio::WorkAreaRenderer
+{
+       
+public:
+       ~Renderer_Dragbox();
+       
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+
+       const sinfg::Point& get_drag_point()const;
+       const sinfg::Point& get_curr_point()const;
+
+protected:
+       bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp b/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp
new file mode 100644 (file)
index 0000000..90cf842
--- /dev/null
@@ -0,0 +1,452 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_ducks.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_ducks.h"
+#include "workarea.h"
+#include "duckmatic.h"
+#include <ETL/bezier>
+#include <ETL/misc>
+#include "widget_color.h"
+#include <sinfg/distance.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Ducks::~Renderer_Ducks()
+{
+}
+
+/*
+bool
+Renderer_Ducks::get_enabled_vfunc()const
+{
+       return get_work_area()->grid_status();
+}
+*/
+
+struct ScreenDuck
+{
+       sinfg::Point pos;
+       Gdk::Color color;
+       bool selected;
+       bool hover;
+       Real width;
+
+       ScreenDuck():width(0) { }
+};
+
+void
+Renderer_Ducks::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+
+       const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+       const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+
+       const float pw(get_pw()),ph(get_ph());
+
+       const std::list<etl::handle<Duckmatic::Bezier> >& bezier_list(get_work_area()->bezier_list());
+       const bool solid_lines(get_work_area()->solid_lines);
+
+       const std::list<handle<Duckmatic::Stroke> >& stroke_list(get_work_area()->stroke_list());
+
+       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_work_area()->get_pango_context()));
+
+       // Render the strokes
+       for(std::list<handle<Duckmatic::Stroke> >::const_iterator iter=stroke_list.begin();iter!=stroke_list.end();++iter)
+       {
+               Point window_start(window_startx,window_starty);
+               vector<Gdk::Point> points;
+               std::list<sinfg::Point>::iterator iter2;
+               Point holder;
+               
+               for(iter2=(*iter)->stroke_data->begin();iter2!=(*iter)->stroke_data->end();++iter2)
+               {
+                       holder=*iter2-window_start;
+                       holder[0]/=pw;holder[1]/=ph;
+                       points.push_back(Gdk::Point(round_to_int(holder[0]),round_to_int(holder[1])));
+               }
+               
+               gc->set_rgb_fg_color(colorconv_sinfg2gdk((*iter)->color));
+               gc->set_function(Gdk::COPY);
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+               // Draw the stroke
+               drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+       }
+
+
+
+       // Render the beziers
+       for(std::list<handle<Duckmatic::Bezier> >::const_iterator iter=bezier_list.begin();iter!=bezier_list.end();++iter)
+       {
+               Point window_start(window_startx,window_starty);
+               Point p1((*iter)->p1->get_trans_point()-window_start);
+               Point p2((*iter)->p2->get_trans_point()-window_start);
+               Point c1((*iter)->c1->get_trans_point()-window_start);
+               Point c2((*iter)->c2->get_trans_point()-window_start);
+               p1[0]/=pw;p1[1]/=ph;
+               p2[0]/=pw;p2[1]/=ph;
+               c1[0]/=pw;c1[1]/=ph;
+               c2[0]/=pw;c2[1]/=ph;
+               bezier<Point> curve(p1,c1,c2,p2);
+               vector<Gdk::Point> points;
+               
+               float f;
+               Point pt;
+               for(f=0;f<1.0;f+=1.0/17.0)
+               {
+                       pt=curve(f);
+                       points.push_back(Gdk::Point(round_to_int(pt[0]),round_to_int(pt[1])));
+               }
+               points.push_back(Gdk::Point(round_to_int(p2[0]),round_to_int(p2[1])));
+               
+               // Draw the curve
+/*             if(solid_lines)
+               {
+                       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                       gc->set_function(Gdk::COPY);
+                       gc->set_line_attributes(3,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+                       gc->set_rgb_fg_color(Gdk::Color("#afafaf"));
+                       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+               }
+               else
+*/
+               {
+//                     gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+//                     gc->set_function(Gdk::INVERT);
+//                     gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+//                     drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+                       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                       gc->set_function(Gdk::COPY);
+                       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+                       gc->set_rgb_fg_color(Gdk::Color("#afafaf"));
+                       gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points));                
+
+               }
+       }
+
+
+       const DuckList duck_list(get_work_area()->get_duck_list());
+       //Gtk::StateType state = Gtk::STATE_ACTIVE;
+       Gtk::ShadowType shadow=Gtk::SHADOW_OUT;
+       std::list<ScreenDuck> screen_duck_list;
+       const float radius((abs(pw)+abs(ph))*4);
+
+       etl::handle<Duck> hover_duck(get_work_area()->find_duck(get_work_area()->get_cursor_pos(),radius, get_work_area()->get_type_mask()));
+
+       // Render the ducks
+       for(std::list<handle<Duck> >::const_iterator iter=duck_list.begin();iter!=duck_list.end();++iter)
+       {
+               
+               // If this type of duck has been masked, then skip it
+               if((*iter)->get_type() && (!(get_work_area()->get_type_mask() & (*iter)->get_type())))
+                       continue;
+                               
+//             Real x,y;
+       //      Gdk::Rectangle area;
+               Point point((*iter)->get_trans_point());
+               Point origin((*iter)->get_trans_origin());
+
+               point[0]=(point[0]-window_startx)/pw;
+               point[1]=(point[1]-window_starty)/ph;
+
+               bool has_connect(false);
+               if((*iter)->get_tangent() || (*iter)->get_type()&Duck::TYPE_ANGLE)
+               {
+                       has_connect=true;
+               }
+               if((*iter)->get_connect_duck())
+               {
+                       has_connect=true;
+                       origin=(*iter)->get_connect_duck()->get_trans_point();                  
+               }
+
+               origin[0]=(origin[0]-window_startx)/pw;
+               origin[1]=(origin[1]-window_starty)/ph;
+
+               
+               bool selected(get_work_area()->duck_is_selected(*iter));
+               bool hover(*iter==hover_duck);
+               
+               shadow = selected?Gtk::SHADOW_IN:Gtk::SHADOW_OUT;
+                                               
+               if(get_work_area()->get_selected_value_node())
+               {
+                       sinfgapp::ValueDesc value_desc((*iter)->get_value_desc());
+                       if(value_desc.is_valid() && value_desc.is_value_node() && get_work_area()->get_selected_value_node()==value_desc.get_value_node())
+                       {
+                               gc->set_function(Gdk::COPY);
+                               gc->set_rgb_fg_color(Gdk::Color("#FF0000"));
+                               //gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               gc->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               
+                               drawable->draw_rectangle(gc,false,
+                                       round_to_int(point[0]-5),
+                                       round_to_int(point[1]-5),
+                                       10,
+                                       10
+                               );
+                       }
+                               
+               }
+
+               if((*iter)->get_box_duck())
+               {
+                       Point boxpoint((*iter)->get_box_duck()->get_trans_point());
+                       boxpoint[0]=(boxpoint[0]-window_startx)/pw;
+                       boxpoint[1]=(boxpoint[1]-window_starty)/ph;
+                       Point tl(min(point[0],boxpoint[0]),min(point[1],boxpoint[1]));
+
+                       gc->set_function(Gdk::COPY);
+                       gc->set_rgb_fg_color(Gdk::Color("#FFFFFF"));
+                       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_rectangle(gc,false,
+                               round_to_int(tl[0]),
+                               round_to_int(tl[1]),
+                               round_to_int(abs(boxpoint[0]-point[0])),
+                               round_to_int(abs(boxpoint[1]-point[1]))
+                       );                      
+                       gc->set_function(Gdk::COPY);
+                       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                       gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       drawable->draw_rectangle(gc,false,
+                               round_to_int(tl[0]),
+                               round_to_int(tl[1]),
+                               round_to_int(abs(boxpoint[0]-point[0])),
+                               round_to_int(abs(boxpoint[1]-point[1]))
+                       );                      
+               }
+
+               ScreenDuck screen_duck;
+               screen_duck.pos=point;
+               screen_duck.selected=selected;
+               screen_duck.hover=hover;
+
+               if(!(*iter)->get_editable())
+                       screen_duck.color=(Gdk::Color("#cfcfcf"));
+               else if((*iter)->get_tangent())
+                       screen_duck.color=((*iter)->get_scalar()<0?Gdk::Color("#ffff00"):Gdk::Color("#ff0000"));
+               else if((*iter)->get_type()&Duck::TYPE_VERTEX)
+                       screen_duck.color=Gdk::Color("#ff7f00");
+               else if((*iter)->get_type()&Duck::TYPE_RADIUS)
+                       screen_duck.color=Gdk::Color("#00ffff");
+               else if((*iter)->get_type()&Duck::TYPE_WIDTH)
+                       screen_duck.color=Gdk::Color("#ff00ff");
+               else if((*iter)->get_type()&Duck::TYPE_ANGLE)
+                       screen_duck.color=(Gdk::Color("#0000ff"));                              
+               else
+                       screen_duck.color=Gdk::Color("#00ff00");                                
+               
+               screen_duck_list.push_front(screen_duck);
+
+               if(has_connect)
+               {
+                       if(solid_lines)
+                       {
+                               gc->set_line_attributes(3,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                               gc->set_function(Gdk::COPY);
+                               drawable->draw_line(gc, (int)origin[0],(int)origin[1],(int)(point[0]),(int)(point[1]));                                         
+                               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               gc->set_rgb_fg_color(Gdk::Color("#9fefef"));
+                               drawable->draw_line(gc, (int)origin[0],(int)origin[1],(int)(point[0]),(int)(point[1]));                                         
+                       }
+                       else
+                       {
+//                             gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+//                             gc->set_function(Gdk::INVERT);
+//                             drawable->draw_line(gc, (int)origin[0],(int)origin[1],(int)(point[0]),(int)(point[1]));                                         
+                               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                               gc->set_function(Gdk::COPY);
+                               drawable->draw_line(gc, (int)origin[0],(int)origin[1],(int)(point[0]),(int)(point[1]));                                         
+                               gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               gc->set_rgb_fg_color(Gdk::Color("#9fefef"));
+                               drawable->draw_line(gc, (int)origin[0],(int)origin[1],(int)(point[0]),(int)(point[1]));                                         
+                       }
+               }
+
+               if((*iter)->is_radius())
+               {
+                       const Real mag((point-origin).mag());
+                       const int d(round_to_int(mag*2));
+                       const int x(round_to_int(origin[0]-mag));
+                       const int y(round_to_int(origin[1]-mag));
+
+                       if(solid_lines)
+                       {
+                               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                               gc->set_function(Gdk::COPY);
+                               gc->set_line_attributes(3,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                               drawable->draw_arc(
+                                       gc,
+                                       false,
+                                       x,
+                                       y,
+                                       d,
+                                       d,
+                                       0,
+                                       360*64
+                               );  
+                               gc->set_rgb_fg_color(Gdk::Color("#afafaf"));
+                       }
+                       else
+                       {
+                               gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+                               gc->set_function(Gdk::INVERT);
+                       }
+                       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+                       
+                       drawable->draw_arc(
+                               gc,
+                               false,
+                               x,
+                               y,
+                               d,
+                               d,
+                               0,
+                               360*64
+                       );  
+
+                       if(hover)
+                       {
+                               Distance real_mag(((*iter)->get_trans_point()-(*iter)->get_trans_origin()).mag(),Distance::SYSTEM_UNITS);
+                               real_mag.convert(App::distance_system,get_work_area()->get_rend_desc());
+                               layout->set_text(real_mag.get_string());                                        
+
+                               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                               drawable->draw_layout(
+                                       gc,
+                                       round_to_int(point[0])+1+6,
+                                       round_to_int(point[1])+1-8,
+                                       layout
+                               );
+                               gc->set_rgb_fg_color(Gdk::Color("#FF00FF"));
+                               drawable->draw_layout(
+                                       gc,
+                                       round_to_int(point[0])+6,
+                                       round_to_int(point[1])-8,
+                                       layout
+                               );
+                       }
+
+               }
+
+       }
+       
+
+       for(;screen_duck_list.size();screen_duck_list.pop_front())
+       {
+               int radius=4;
+               int outline=1;
+               Gdk::Color color(screen_duck_list.front().color);
+               
+               if(!screen_duck_list.front().selected)
+               {
+                       color.set_red(color.get_red()*2/3);
+                       color.set_green(color.get_green()*2/3);
+                       color.set_blue(color.get_blue()*2/3);
+               }
+               
+               if(screen_duck_list.front().hover && !screen_duck_list.back().hover && screen_duck_list.size()>1)
+               {
+                       screen_duck_list.push_back(screen_duck_list.front());
+                       continue;
+               }
+               
+               if(screen_duck_list.front().hover)
+               {
+                       radius+=2;
+                       outline++;
+               }
+               
+               gc->set_function(Gdk::COPY);
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               gc->set_rgb_fg_color(Gdk::Color("#000000"));
+               drawable->draw_arc(
+                       gc,
+                       true,
+                       round_to_int(screen_duck_list.front().pos[0]-radius),
+                       round_to_int(screen_duck_list.front().pos[1]-radius),
+                       radius*2,
+                       radius*2,
+                       0,
+                       360*64
+               );  
+
+
+               gc->set_rgb_fg_color(color);
+
+               drawable->draw_arc(
+                       gc,
+                       true,
+                       round_to_int(screen_duck_list.front().pos[0]-radius+outline),
+                       round_to_int(screen_duck_list.front().pos[1]-radius+outline),
+                       radius*2-outline*2,
+                       radius*2-outline*2,
+                       0,
+                       360*64
+               );  
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_ducks.h b/synfig-studio/trunk/src/gtkmm/renderer_ducks.h
new file mode 100644 (file)
index 0000000..a4be796
--- /dev/null
@@ -0,0 +1,56 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_ducks.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_DUCKS_H
+#define __SINFG_RENDERER_DUCKS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Ducks : public studio::WorkAreaRenderer
+{
+       
+public:
+       ~Renderer_Ducks();
+       
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+
+protected:
+//     bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_grid.cpp b/synfig-studio/trunk/src/gtkmm/renderer_grid.cpp
new file mode 100644 (file)
index 0000000..d648f93
--- /dev/null
@@ -0,0 +1,170 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_grid.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_grid.h"
+#include "workarea.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Grid::~Renderer_Grid()
+{
+}
+
+bool
+Renderer_Grid::get_enabled_vfunc()const
+{
+       return get_work_area()->grid_status();
+}
+
+sinfg::Vector
+Renderer_Grid::get_grid_size()const
+{
+       return get_work_area()->get_grid_size();
+}
+
+void
+Renderer_Grid::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+//     const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+//     std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+//     const sinfg::Vector::value_type
+//             x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+//             y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+//     const int
+//             tile_w(get_work_area()->get_tile_w()),
+//             tile_h(get_work_area()->get_tile_h());
+
+//     const int
+//             w(get_w()),
+//             h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       const sinfg::Vector grid_size(get_grid_size());
+
+       const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+       const sinfg::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
+       const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+       const sinfg::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
+       const float pw(get_pw()),ph(get_ph());
+       
+       // Draw out the grid
+       if(grid_size[0]>pw*3.5 && grid_size[1]>ph*3.5)
+       {
+               sinfg::Vector::value_type x,y;
+
+               x=floor(window_startx/grid_size[0])*grid_size[0];
+               y=floor(window_starty/grid_size[1])*grid_size[1];
+               
+               gc->set_function(Gdk::COPY);
+               gc->set_rgb_fg_color(Gdk::Color("#9f9f9f"));
+               gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+               if(x<window_endx)
+                       for(;x<window_endx;x+=grid_size[0])
+                       {
+                               drawable->draw_line(gc,
+                                       round_to_int((x-window_startx)/pw),
+                                       0,
+                                       round_to_int((x-window_startx)/pw),
+                                       drawable_h
+                               );
+                       }
+               else
+                       for(;x>window_endx;x-=grid_size[0])
+                       {
+                               drawable->draw_line(gc,
+                                       round_to_int((x-window_startx)/pw),
+                                       0,
+                                       round_to_int((x-window_startx)/pw),
+                                       drawable_h
+                               );
+                       }
+
+               if(y<window_endy)
+                       for(;y<window_endy;y+=grid_size[1])
+                       {
+                               drawable->draw_line(gc,
+                                       0,
+                                       round_to_int((y-window_starty)/ph),
+                                       drawable_w,
+                                       round_to_int((y-window_starty)/ph)
+                               );
+                       }
+               else
+                       for(;y>window_endy;y-=grid_size[1])
+                       {
+                               drawable->draw_line(gc,
+                                       0,
+                                       round_to_int((y-window_starty)/ph),
+                                       drawable_w,
+                                       round_to_int((y-window_starty)/ph)
+                               );
+                       }
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_grid.h b/synfig-studio/trunk/src/gtkmm/renderer_grid.h
new file mode 100644 (file)
index 0000000..2789727
--- /dev/null
@@ -0,0 +1,58 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_grid.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_GRID_H
+#define __SINFG_RENDERER_GRID_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Grid : public studio::WorkAreaRenderer
+{
+       
+public:
+       ~Renderer_Grid();
+       
+       sinfg::Vector get_grid_size()const;
+
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+
+protected:
+       bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_guides.cpp b/synfig-studio/trunk/src/gtkmm/renderer_guides.cpp
new file mode 100644 (file)
index 0000000..f13746b
--- /dev/null
@@ -0,0 +1,281 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_guides.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_guides.h"
+#include "workarea.h"
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Guides::Renderer_Guides():
+       dragging(false)
+{
+       
+}
+
+Renderer_Guides::~Renderer_Guides()
+{
+}
+
+bool
+Renderer_Guides::get_enabled_vfunc()const
+{
+       return get_work_area()->get_show_guides();
+}
+
+std::list<float>&
+Renderer_Guides::get_guide_list_x()
+{
+       return get_work_area()->get_guide_list_x();
+}
+
+std::list<float>&
+Renderer_Guides::get_guide_list_y()
+{
+       return get_work_area()->get_guide_list_y();
+}
+
+bool
+Renderer_Guides::event_vfunc(GdkEvent* event)
+{
+       sinfg::Point mouse_pos;
+    float bezier_click_pos;
+       const float radius((abs(get_pw())+abs(get_ph()))*4);
+       int button_pressed(0);
+       float pressure(0);
+       bool is_mouse(false);
+       Gdk::ModifierType modifier(Gdk::ModifierType(0));
+       
+       // Handle input stuff
+       if(
+               event->any.type==GDK_MOTION_NOTIFY ||
+               event->any.type==GDK_BUTTON_PRESS ||
+               event->any.type==GDK_2BUTTON_PRESS ||
+               event->any.type==GDK_3BUTTON_PRESS ||
+               event->any.type==GDK_BUTTON_RELEASE
+       )
+       {
+               GdkDevice *device;
+               if(event->any.type==GDK_MOTION_NOTIFY)
+               {
+                       device=event->motion.device;
+                       modifier=Gdk::ModifierType(event->motion.state);
+               }
+               else
+               {
+                       device=event->button.device;
+                       modifier=Gdk::ModifierType(event->button.state);
+               }
+                       
+               // Make sure we recognise the device
+               /*if(curr_input_device)
+               {
+                       if(curr_input_device!=device)
+                       {
+                               assert(device);
+                               curr_input_device=device;
+                               signal_input_device_changed()(curr_input_device);
+                       }
+               }               
+               else*/ if(device)
+               {
+                       //curr_input_device=device;
+                       //signal_input_device_changed()(curr_input_device);
+               }                       
+
+               //assert(curr_input_device);
+               
+               // Calculate the position of the
+               // input device in canvas coordinates
+               // and the buttons
+               if(!event->button.axes)
+               {
+                       mouse_pos=sinfg::Point(screen_to_comp_coords(sinfg::Point(event->button.x,event->button.y)));
+                       button_pressed=event->button.button;
+                       pressure=1.0f;
+                       is_mouse=true;
+                       if(isnan(event->button.x) || isnan(event->button.y))
+                               return false;
+               }
+               else
+               {
+                       double x(event->button.axes[0]);
+                       double y(event->button.axes[1]);
+                       if(isnan(x) || isnan(y))
+                               return false;
+
+                       pressure=event->button.axes[2];
+                       //sinfg::info("pressure=%f",pressure);
+                       pressure-=0.04f;
+                       pressure/=1.0f-0.04f;
+                       
+                       
+                       assert(!isnan(pressure));
+                       
+                       mouse_pos=sinfg::Point(screen_to_comp_coords(sinfg::Point(x,y)));
+                       
+                       button_pressed=event->button.button;
+                       
+                       if(button_pressed==1 && pressure<0 && (event->any.type!=GDK_BUTTON_RELEASE && event->any.type!=GDK_BUTTON_PRESS))
+                               button_pressed=0;
+                       if(pressure<0)
+                               pressure=0;
+
+                       //if(event->any.type==GDK_BUTTON_PRESS && button_pressed)
+                       //      sinfg::info("Button pressed on input device = %d",event->button.button);
+                       
+                       //if(event->button.axes[2]>0.1)
+                       //      button_pressed=1;
+                       //else
+                       //      button_pressed=0;                               
+               }
+       }
+       switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               break;
+       case GDK_MOTION_NOTIFY:
+               break;
+       case GDK_BUTTON_RELEASE:
+               break;
+       default:
+               break;
+       }
+       
+       return false;
+}
+
+void
+Renderer_Guides::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+       const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+       //std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+       const sinfg::Vector::value_type
+               x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+               y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+       const int
+               tile_w(get_work_area()->get_tile_w()),
+               tile_h(get_work_area()->get_tile_h());
+
+       const int
+               w(get_w()),
+               h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       //const sinfg::Vector grid_size(get_grid_size());
+
+       const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+       const sinfg::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
+       const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+       const sinfg::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
+       const float pw(get_pw()),ph(get_ph());
+
+       // Draw out the guides
+       {
+               gc->set_function(Gdk::COPY);
+               gc->set_rgb_fg_color(Gdk::Color("#9f9fff"));
+               gc->set_line_attributes(1,Gdk::LINE_ON_OFF_DASH,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               
+               Duckmatic::GuideList::const_iterator iter;
+               
+               // vertical
+               for(iter=get_guide_list_x().begin();iter!=get_guide_list_x().end();++iter)
+               {
+                       const float x((*iter-window_startx)/pw);
+                       
+                       if(iter==get_work_area()->curr_guide)
+                               gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
+                       else
+                               gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
+                               
+                       drawable->draw_line(gc,
+                               round_to_int(x),
+                               0,
+                               round_to_int(x),
+                               drawable_h
+                       );
+               }
+               // horizontal
+               for(iter=get_guide_list_y().begin();iter!=get_guide_list_y().end();++iter)
+               {
+                       const float y((*iter-window_starty)/ph);
+
+                       if(iter==get_work_area()->curr_guide)
+                               gc->set_rgb_fg_color(Gdk::Color("#ff6f6f"));
+                       else
+                               gc->set_rgb_fg_color(Gdk::Color("#6f6fff"));
+
+                       drawable->draw_line(gc,
+                               0,
+                               round_to_int(y),
+                               drawable_w,
+                               round_to_int(y)
+                       );
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_guides.h b/synfig-studio/trunk/src/gtkmm/renderer_guides.h
new file mode 100644 (file)
index 0000000..ac98b66
--- /dev/null
@@ -0,0 +1,61 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_guides.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_GUIDES_H
+#define __SINFG_RENDERER_GUIDES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Guides : public studio::WorkAreaRenderer
+{
+       bool dragging;
+public:
+       Renderer_Guides();
+       ~Renderer_Guides();
+
+       std::list<float>& get_guide_list_x();
+       std::list<float>& get_guide_list_y();
+
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+       bool event_vfunc(GdkEvent* event);
+
+protected:
+       bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_timecode.cpp b/synfig-studio/trunk/src/gtkmm/renderer_timecode.cpp
new file mode 100644 (file)
index 0000000..4c4d62a
--- /dev/null
@@ -0,0 +1,156 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: renderer_timecode.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "renderer_timecode.h"
+#include "workarea.h"
+#include <pangomm/layout.h>
+#include <pangomm/context.h>
+#include <pango/pango.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Renderer_Timecode::~Renderer_Timecode()
+{
+}
+
+bool
+Renderer_Timecode::get_enabled_vfunc()const
+{
+       Canvas::Handle canvas(get_work_area()->get_canvas());
+       return (canvas->rend_desc().get_time_start()!=canvas->rend_desc().get_time_end() ||
+               canvas->get_time()!=canvas->rend_desc().get_time_start());
+}
+
+sinfg::Vector
+Renderer_Timecode::get_grid_size()const
+{
+       return get_work_area()->get_grid_size();
+}
+
+void
+Renderer_Timecode::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& drawable,
+       const Gdk::Rectangle& expose_area
+)
+{
+       assert(get_work_area());
+       if(!get_work_area())
+               return;
+       
+       //const sinfg::RendDesc &rend_desc(get_work_area()->get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_work_area()->get_focus_point());
+
+       //std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& tile_book(get_tile_book());
+       
+       int drawable_w,drawable_h;
+       drawable->get_size(drawable_w,drawable_h);
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+//     const sinfg::Vector::value_type
+//             x(focus_point[0]/get_pw()+drawable_w/2-get_w()/2),
+//             y(focus_point[1]/get_ph()+drawable_h/2-get_h()/2);
+
+       /*const sinfg::Vector::value_type window_startx(window_tl[0]);
+       const sinfg::Vector::value_type window_endx(window_br[0]);
+       const sinfg::Vector::value_type window_starty(window_tl[1]);
+       const sinfg::Vector::value_type window_endy(window_br[1]);
+       */
+//     const int
+//             tile_w(get_work_area()->get_tile_w()),
+//             tile_h(get_work_area()->get_tile_h());
+
+//     const int
+//             w(get_w()),
+//             h(get_h());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(drawable));
+       
+       //const sinfg::Vector grid_size(get_grid_size());
+
+//     const sinfg::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
+//     const sinfg::Vector::value_type window_endx(get_work_area()->get_window_br()[0]);
+//     const sinfg::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
+//     const sinfg::Vector::value_type window_endy(get_work_area()->get_window_br()[1]);
+//     const float pw(get_pw()),ph(get_ph());
+
+       Canvas::Handle canvas(get_work_area()->get_canvas());
+       sinfg::Time cur_time(canvas->get_time());
+       
+       // Print out the timecode
+       {
+               Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_work_area()->get_pango_context()));
+               
+/*             Glib::ustring timecode(cur_time.get_string(rend_desc.get_frame_rate(),App::get_time_format()));
+
+               try
+               {
+                       timecode+="\n"+canvas->keyframe_list().find(cur_time)->get_description();
+                       gc->set_rgb_fg_color(Gdk::Color("#FF0000"));
+               }
+               catch(sinfg::Exception::NotFound)
+               {
+                       return;
+                       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+               }
+               
+               layout->set_text(timecode);             
+*/
+
+               gc->set_rgb_fg_color(Gdk::Color("#5f0000"));
+               try
+               {
+                       layout->set_text(canvas->keyframe_list().find(cur_time)->get_description());            
+               }
+               catch(sinfg::Exception::NotFound)
+               {
+                       return;
+               }
+               
+               drawable->draw_layout(gc, 4, 4, layout);
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/renderer_timecode.h b/synfig-studio/trunk/src/gtkmm/renderer_timecode.h
new file mode 100644 (file)
index 0000000..068aa10
--- /dev/null
@@ -0,0 +1,58 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: renderer_timecode.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_RENDERER_TIMECODE_H
+#define __SINFG_RENDERER_TIMECODE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "workarearenderer.h"
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Renderer_Timecode : public studio::WorkAreaRenderer
+{
+       
+public:
+       ~Renderer_Timecode();
+       
+       sinfg::Vector get_grid_size()const;
+
+       void render_vfunc(const Glib::RefPtr<Gdk::Drawable>& drawable,const Gdk::Rectangle& expose_area );
+
+protected:
+       bool get_enabled_vfunc()const;
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/smach.h b/synfig-studio/trunk/src/gtkmm/smach.h
new file mode 100644 (file)
index 0000000..e4cdf18
--- /dev/null
@@ -0,0 +1,48 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: smach.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_SMACH_H
+#define __SINFG_SMACH_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/smach>
+#include "eventkey.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class CanvasView;
+       
+typedef etl::smach<CanvasView,EventKey> Smach;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_bline.cpp b/synfig-studio/trunk/src/gtkmm/state_bline.cpp
new file mode 100644 (file)
index 0000000..0def107
--- /dev/null
@@ -0,0 +1,1220 @@
+/* === S I N F G =========================================================== */
+/*!    \file rotoscope_bline.cpp
+**     \brief Template File
+**
+**     $Id: state_bline.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include "state_bline.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+#include <sinfg/valuenode_bline.h>
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include <utility>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/spinbutton.h>
+#include <sinfg/transform.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateBLine studio::state_bline;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateBLine_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       bool prev_table_status;
+       bool loop_;
+       bool prev_workarea_layer_status_;
+
+       int depth;
+       Canvas::Handle canvas;
+
+       Gtk::Menu menu;
+
+       Duckmatic::Push duckmatic_push;
+       
+       etl::handle<Duck> curr_duck;
+
+       etl::handle<Duck> next_duck;
+       
+       std::list<sinfg::ValueNode_Const::Handle> bline_point_list;
+       sinfgapp::Settings& settings;
+       
+       bool on_vertex_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node);
+       bool on_tangent1_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node);
+       bool on_tangent2_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node);
+
+
+       void popup_handle_menu(sinfg::ValueNode_Const::Handle value_node);
+       void popup_vertex_menu(sinfg::ValueNode_Const::Handle value_node);
+       void popup_bezier_menu(float location, sinfg::ValueNode_Const::Handle value_node);
+
+       void bline_detach_handle(sinfg::ValueNode_Const::Handle value_node);
+       void bline_attach_handle(sinfg::ValueNode_Const::Handle value_node);
+       void bline_delete_vertex(sinfg::ValueNode_Const::Handle value_node);
+       void bline_insert_vertex(sinfg::ValueNode_Const::Handle value_node,float origin=0.5);
+       void loop_bline();
+
+       void refresh_ducks(bool x=true);
+       
+       Gtk::Table options_table;
+       Gtk::Entry entry_id;
+       Gtk::CheckButton checkbutton_layer_region;
+       Gtk::CheckButton checkbutton_layer_bline;
+       Gtk::CheckButton checkbutton_layer_curve_gradient;
+       Gtk::CheckButton checkbutton_auto_export;
+       Gtk::Button button_make;
+       Gtk::Button button_clear;
+       Gtk::Adjustment  adj_feather;
+       Gtk::SpinButton  spin_feather;
+       
+       
+       
+public:
+
+       int layers_to_create()const
+       {
+               return
+                       get_layer_region_flag()+
+                       get_layer_bline_flag()+
+                       get_layer_curve_gradient_flag();
+       }
+       
+       void sanity_check()
+       {
+               if(layers_to_create()==0)
+                       set_layer_region_flag(true);
+       }
+
+       bool get_auto_export_flag()const { return checkbutton_auto_export.get_active(); }
+       void set_auto_export_flag(bool x) { return checkbutton_auto_export.set_active(x); }
+       
+       bool get_layer_region_flag()const { return checkbutton_layer_region.get_active(); }
+       void set_layer_region_flag(bool x) { return checkbutton_layer_region.set_active(x); }
+       
+       bool get_layer_bline_flag()const { return checkbutton_layer_bline.get_active(); }
+       void set_layer_bline_flag(bool x) { return checkbutton_layer_bline.set_active(x); }
+       
+       bool get_layer_curve_gradient_flag()const { return checkbutton_layer_curve_gradient.get_active(); }
+       void set_layer_curve_gradient_flag(bool x) { return checkbutton_layer_curve_gradient.set_active(x); }
+
+       Real get_feather() const { return adj_feather.get_value(); }
+       void set_feather(Real x) { return adj_feather.set_value(x); }
+       sinfg::String get_id()const { return entry_id.get_text(); }
+       void set_id(const sinfg::String& x) { return entry_id.set_text(x); }
+
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_mouse_release_handler(const Smach::event& x);
+       Smach::event_result event_mouse_motion_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       Smach::event_result event_hijack(const Smach::event& x) { return Smach::RESULT_ACCEPT; }
+       
+       void refresh_tool_options();
+
+       StateBLine_Context(CanvasView* canvas_view);
+
+       ~StateBLine_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       const sinfg::TransformStack& get_transform_stack()const { return canvas_view_->get_curr_transform_stack(); }
+       
+       void load_settings();
+       void save_settings();
+       void reset();
+       void increment_id();
+       //void on_user_click(sinfg::Point point);
+
+       bool run_();
+       bool run();
+       
+       bool no_egress_on_selection_change;
+       Smach::event_result event_layer_selection_changed_handler(const Smach::event& x)
+       {
+               if(!no_egress_on_selection_change)
+                       throw Smach::egress_exception();
+               return Smach::RESULT_OK;
+       }
+       
+};     // END of class StateBLine_Context
+
+
+/* === M E T H O D S ======================================================= */
+
+StateBLine::StateBLine():
+       Smach::state<StateBLine_Context>("bline")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateBLine_Context::event_layer_selection_changed_handler));
+       insert(event_def(EVENT_STOP,&StateBLine_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateBLine_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateBLine_Context::event_hijack));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateBLine_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateBLine_Context::event_mouse_release_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_MOTION,&StateBLine_Context::event_mouse_motion_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateBLine_Context::event_mouse_motion_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateBLine_Context::event_refresh_tool_options));
+}      
+
+StateBLine::~StateBLine()
+{
+}
+
+void
+StateBLine_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("bline.layer_region",value) && value=="0")
+               set_layer_region_flag(false);
+       else
+               set_layer_region_flag(true);
+
+       if(settings.get_value("bline.layer_bline",value) && value=="0")
+               set_layer_bline_flag(false);
+       else
+               set_layer_bline_flag(true);
+
+       if(settings.get_value("bline.layer_curve_gradient",value) && value=="1")
+               set_layer_curve_gradient_flag(true);
+       else
+               set_layer_curve_gradient_flag(false);
+
+       if(settings.get_value("bline.auto_export",value) && value=="1")
+               set_auto_export_flag(true);
+       else
+               set_auto_export_flag(false);
+
+       if(settings.get_value("bline.id",value))
+               set_id(value);
+       else
+               set_id("NewBLine");
+
+       if(settings.get_value("bline.feather",value))
+       {
+               Real n = atof(value.c_str());
+               set_feather(n);
+       }
+
+       sanity_check();
+}
+
+void
+StateBLine_Context::save_settings()
+{      
+       sanity_check();
+       settings.set_value("bline.layer_bline",get_layer_bline_flag()?"1":"0");
+       settings.set_value("bline.layer_region",get_layer_region_flag()?"1":"0");
+       settings.set_value("bline.layer_curve_gradient",get_layer_curve_gradient_flag()?"1":"0");
+       settings.set_value("bline.auto_export",get_auto_export_flag()?"1":"0");
+       settings.set_value("bline.id",get_id().c_str());
+       settings.set_value("bline.feather",strprintf("%f",get_feather()));
+}
+
+void
+StateBLine_Context::reset()
+{
+       loop_=false;
+       bline_point_list.clear();
+       refresh_ducks();
+}
+
+void
+StateBLine_Context::increment_id()
+{
+       String id(get_id());
+       int number=1;
+       int digits=0;
+       
+       if(id.empty())
+               id="NewBLine";
+       
+       // If there is a number
+       // already at the end of the
+       // id, then remove it.
+       if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
+       {
+               // figure out how many digits it is
+               for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false);
+               
+               String str_number;
+               str_number=String(id,id.size()-digits,id.size());
+               id=String(id,0,id.size()-digits);
+               sinfg::info("---------------- \"%s\"",str_number.c_str());
+               
+               number=atoi(str_number.c_str());
+       }
+       else
+       {
+               number=1;
+               digits=3;
+       }
+       
+       number++;
+       
+       // Add the number back onto the id
+       {
+               const String format(strprintf("%%0%dd",digits));
+               id+=strprintf(format.c_str(),number);
+       }
+       
+       // Set the ID
+       set_id(id);
+}
+
+
+StateBLine_Context::StateBLine_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       loop_(false),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       duckmatic_push(get_work_area()),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       entry_id(),
+       checkbutton_layer_region(_("Fill")),
+       checkbutton_layer_bline(_("Outline")),
+       checkbutton_layer_curve_gradient(_("Gradient")),
+       checkbutton_auto_export(_("Auto Export")),
+       button_make(_("Make")),
+       button_clear(_("Clear")),
+       adj_feather(0,0,10000,0.01,0.1),
+       spin_feather(adj_feather,0.01,4)
+{
+       depth=-1;
+       no_egress_on_selection_change=false;
+       load_settings();
+               
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("BLine Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);       
+       options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(checkbutton_layer_region, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); 
+       options_table.attach(checkbutton_layer_bline, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  
+       options_table.attach(checkbutton_layer_curve_gradient, 0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); 
+       options_table.attach(*manage(new Gtk::Label(_("Feather"))), 0, 1, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  
+       options_table.attach(spin_feather, 1, 2, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(checkbutton_auto_export, 0, 2, 11, 12, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+       //options_table.attach(button_make, 0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       //button_make.signal_pressed().connect(sigc::mem_fun(*this,&StateBLine_Context::run));
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+       
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+       
+       // Hide the tables if they are showing
+       prev_table_status=get_canvas_view()->tables_are_visible();
+       if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateBLine_Context::on_user_click));
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+
+       App::toolbox->refresh();
+}
+
+void
+StateBLine_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("BLine Tool"));
+       App::dialog_tool_options->set_name("bline");
+
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-execute"),
+               _("Make BLine and/or Region")
+       )->signal_clicked().connect(
+               sigc::hide_return(sigc::mem_fun(
+                       *this,
+                       &StateBLine_Context::run
+               ))
+       );
+
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-clear"),
+               _("Clear current BLine")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &StateBLine_Context::reset
+               )
+       );
+}
+
+Smach::event_result
+StateBLine_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateBLine_Context::~StateBLine_Context()
+{
+       run();
+
+       save_settings();
+       App::dialog_tool_options->clear();
+
+       get_canvas_view()->work_area->reset_cursor();
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       if(prev_table_status)get_canvas_view()->show_tables();
+
+//     get_canvas_view()->get_smach().process_event(EVENT_REFRESH_DUCKS);
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateBLine_Context::event_stop_handler(const Smach::event& x)
+{
+       sinfg::info("STATE RotoBLine: Received Stop Event");
+//     run();
+       reset();
+//     throw Smach::egress_exception();
+//     get_canvas_view()->get_smach().pop_state();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateBLine_Context::event_refresh_handler(const Smach::event& x)
+{
+       sinfg::info("STATE RotoBLine: Received Refresh Event");
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+bool
+StateBLine_Context::run()
+{
+       sanity_check();
+
+       String err;
+       bool success(false);
+       for(int i=5;i>0 && !success;i--)try
+       {
+               success=run_();
+       }
+       catch(String s)
+       {
+               err=s;
+       }
+       if(!success && !err.empty())
+       {
+               get_canvas_view()->get_ui_interface()->error(err);
+       }
+       return success;
+}
+
+bool
+StateBLine_Context::run_()
+{
+       curr_duck=0;
+       next_duck=0;
+
+       // Now we need to generate it
+       
+       if(bline_point_list.empty())
+       {
+               return false;
+       }
+       if(bline_point_list.size()<2)
+       {
+               //get_canvas_view()->get_ui_interface()->error(_("You need at least two (2) points to create a BLine"));
+               return false;
+       }
+       
+       do
+       {                       
+               
+               // Create the action group
+               sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New BLine"));
+
+               std::vector<BLinePoint> new_list;
+               std::list<sinfg::ValueNode_Const::Handle>::iterator iter;
+               const sinfg::TransformStack& transform(get_transform_stack());
+               
+               for(iter=bline_point_list.begin();iter!=bline_point_list.end();++iter)
+               {
+                       BLinePoint bline_point((*iter)->get_value().get(BLinePoint()));
+                       Point new_vertex(transform.unperform(bline_point.get_vertex()));
+                       
+                       bline_point.set_tangent1(
+                               transform.unperform(
+                                       bline_point.get_tangent1()+bline_point.get_vertex()
+                               ) -new_vertex
+                       );
+
+                       bline_point.set_tangent2(
+                               transform.unperform(
+                                       bline_point.get_tangent2()+bline_point.get_vertex()
+                               ) -new_vertex
+                       );
+                       
+                       bline_point.set_vertex(new_vertex);
+                       
+                       new_list.push_back(bline_point);
+               }
+                       
+               ValueNode_BLine::Handle value_node_bline(ValueNode_BLine::create(new_list));
+               
+               assert(value_node_bline);
+               
+               // Set the looping flag
+               value_node_bline->set_loop(loop_);
+               
+               // Add the BLine to the canvas
+               if(get_auto_export_flag() && !get_canvas_interface()->add_value_node(value_node_bline,get_id()))
+               {
+                       //get_canvas_view()->get_ui_interface()->error(_("Unable to add value node"));
+                       group.cancel();
+                       increment_id();
+                       throw String(_("Unable to add value node"));
+                       return false;
+               }
+               
+               Layer::Handle layer;
+                               
+               // we are temporarily using the layer to hold something
+               layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+
+               if(layer)
+               {
+                       if(depth<0)
+                               depth=layer->get_depth();
+                       if(!canvas)
+                               canvas=layer->get_canvas();
+               }
+               else
+                       depth=0;
+               
+               if(!canvas)
+                       canvas=get_canvas_view()->get_canvas();
+
+               sinfgapp::SelectionManager::LayerList layer_selection;
+               
+               // If we were asked to create a region layer, go ahead and do so
+               if(get_layer_region_flag())
+               {
+                       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+                       Layer::Handle layer(get_canvas_interface()->add_layer_to("region",canvas,depth));
+                       layer_selection.push_back(layer);
+                       assert(layer);
+                       layer->set_description(get_id()+_(" Region"));
+                       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+
+                       if(get_feather())
+                       {
+                               layer->set_param("feather",get_feather());
+                               get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
+                       }
+                       
+                       if(get_layer_bline_flag())
+                               layer->set_param("color",sinfgapp::Main::get_background_color());
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+                       
+                       assert(action);
+                       
+                       action->set_param("canvas",get_canvas());                       
+                       action->set_param("canvas_interface",get_canvas_interface());                   
+                       action->set_param("layer",layer);
+                       if(!action->set_param("param",String("bline")))
+                               sinfg::error("LayerParamConnect didn't like \"param\"");
+                       if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
+                               sinfg::error("LayerParamConnect didn't like \"value_node\"");
+
+                       if(!get_canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               //get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
+                               group.cancel();
+                               throw String(_("Unable to create Region layer"));
+                               return false;
+                       }
+               }
+
+               // If we were asked to create a BLine layer, go ahead and do so
+               if(get_layer_bline_flag())
+               {
+                       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+                       Layer::Handle layer(get_canvas_interface()->add_layer_to("outline",canvas,depth));
+                       layer_selection.push_back(layer);
+                       layer->set_description(get_id()+_(" Outline"));
+                       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+                       if(get_feather())
+                       {
+                               layer->set_param("feather",get_feather());
+                               get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
+                       }
+                       
+                       assert(layer);
+
+
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+
+                       assert(action);
+                       
+                       action->set_param("canvas",get_canvas());                       
+                       action->set_param("canvas_interface",get_canvas_interface());                   
+                       action->set_param("layer",layer);                       
+                       if(!action->set_param("param",String("bline")))
+                               sinfg::error("LayerParamConnect didn't like \"param\"");
+                       if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
+                               sinfg::error("LayerParamConnect didn't like \"value_node\"");
+
+                       if(!get_canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               //get_canvas_view()->get_ui_interface()->error(_("Unable to create BLine layer"));
+                               group.cancel();
+                               throw String(_("Unable to create Outline layer"));
+                               return false;
+                       }                       
+
+                       /*if(get_layer_region_flag() && !get_auto_export_flag())
+                       {
+                               get_canvas_interface()->auto_export(sinfgapp::ValueDesc(layer,"bline"));
+                       }*/
+               }
+
+
+               
+               // If we were asked to create a CurveGradient layer, go ahead and do so
+               if(get_layer_curve_gradient_flag())
+               {
+                       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+                       Layer::Handle layer(get_canvas_interface()->add_layer_to("curve_gradient",canvas,depth));
+                       layer_selection.push_back(layer);
+                       layer->set_description(get_id()+_(" Gradient"));
+                       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+                       
+                       assert(layer);
+
+
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+
+                       assert(action);
+                       
+                       action->set_param("canvas",get_canvas());                       
+                       action->set_param("canvas_interface",get_canvas_interface());                   
+                       action->set_param("layer",layer);                       
+                       if(!action->set_param("param",String("bline")))
+                               sinfg::error("LayerParamConnect didn't like \"param\"");
+                       if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
+                               sinfg::error("LayerParamConnect didn't like \"value_node\"");
+
+                       if(!get_canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               //get_canvas_view()->get_ui_interface()->error(_("Unable to create BLine layer"));
+                               group.cancel();
+                               throw String(_("Unable to create Gradient layer"));
+                               return false;
+                       }                       
+
+                       /*if(get_layer_region_flag() && !get_auto_export_flag())
+                       {
+                               get_canvas_interface()->auto_export(sinfgapp::ValueDesc(layer,"bline"));
+                       }*/
+               }
+
+               no_egress_on_selection_change=true;
+               get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+               get_canvas_interface()->get_selection_manager()->set_selected_layers(layer_selection);
+               no_egress_on_selection_change=false;
+               
+               //if(finish_bline_dialog.get_region_flag() || finish_bline_dialog.get_bline_flag())
+               //      get_canvas_interface()->signal_dirty_preview()();
+                       
+       } while(0);
+
+       reset();
+       increment_id();
+       return true;
+}
+
+Smach::event_result
+StateBLine_Context::event_mouse_motion_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       
+       if(curr_duck)
+       {
+               //sinfg::info("Moved Duck");
+               Point p(get_work_area()->snap_point_to_grid(event.pos));
+               curr_duck->set_trans_point(p);
+               if(next_duck)
+                       next_duck->set_trans_point(p);
+               get_work_area()->queue_draw();
+               return Smach::RESULT_ACCEPT;
+       }
+       
+       return Smach::RESULT_OK;
+}
+
+Smach::event_result
+StateBLine_Context::event_mouse_release_handler(const Smach::event& x)
+{
+       if(curr_duck)
+       {
+               //sinfg::info("Released current duck");
+               curr_duck->signal_edited()(curr_duck->get_point());
+               if(next_duck)
+               {
+                       //sinfg::info("grabbing next duck");
+                       curr_duck=next_duck;
+                       next_duck=0;
+               }
+               return Smach::RESULT_ACCEPT;
+       }
+       return Smach::RESULT_OK;
+}
+
+Smach::event_result
+StateBLine_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       sinfg::info("STATE BLINE: Received mouse button down Event");
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               {
+                       // If we are already looped up, then don't try to add anything else
+                       if(loop_)
+                               return Smach::RESULT_OK;
+       
+                       BLinePoint bline_point;
+                       
+                       bline_point.set_vertex(get_work_area()->snap_point_to_grid(event.pos));
+                       //bline_point.set_width(sinfgapp::Main::get_bline_width());
+                       bline_point.set_width(1.0f);
+                       bline_point.set_origin(0.5f);
+                       bline_point.set_split_tangent_flag(false);
+                       bline_point.set_tangent1(Vector(0,0));
+                       
+                       // set the tangent
+                       /*
+                       if(bline_point_list.empty())
+                       {
+                               bline_point.set_tangent1(Vector(1,1));
+                       }
+                       else
+                       {
+                               const Vector t(event.pos-bline_point_list.back()->get_value().get(BLinePoint()).get_vertex());
+                               bline_point.set_tangent1(t);
+                       }
+                       
+                       if(bline_point_list.size()>1)
+                       {
+                               std::list<sinfg::ValueNode_Const::Handle>::iterator iter;
+                               iter=bline_point_list.end();
+                               iter--;iter--;
+                               BLinePoint prev(bline_point_list.back()->get_value().get(BLinePoint()));
+                               prev.set_tangent1(event.pos-(*iter)->get_value().get(BLinePoint()).get_vertex());
+                               bline_point_list.back()->set_value(prev);
+                       };
+                       */
+                       
+                       bline_point_list.push_back(ValueNode_Const::create(bline_point));
+               
+                       refresh_ducks();
+                       return Smach::RESULT_ACCEPT;
+               }
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
+
+void
+StateBLine_Context::refresh_ducks(bool button_down)
+{
+       get_work_area()->clear_ducks();
+       get_work_area()->queue_draw();
+       
+       if(bline_point_list.empty())
+               return;
+
+       list<ValueNode_Const::Handle>::iterator iter;
+
+       handle<WorkArea::Bezier> bezier;
+       handle<WorkArea::Duck> duck,tduck;
+       BLinePoint bline_point;
+       
+       for(iter=bline_point_list.begin();iter!=bline_point_list.end();++iter)
+       {
+               ValueNode_Const::Handle value_node(*iter);
+               bline_point=(value_node->get_value().get(BLinePoint()));
+               assert(value_node);
+
+
+               // First add the duck associated with this vertex               
+               duck=new WorkArea::Duck(bline_point.get_vertex());
+               duck->set_editable(true);
+               duck->set_type(Duck::TYPE_VERTEX);
+               duck->set_name(strprintf("%x-vertex",value_node.get()));
+               duck->signal_edited().connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_vertex_change),value_node)
+               );
+               duck->signal_user_click(2).connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::popup_vertex_menu),value_node)
+               );
+               duck->set_guid(value_node->get_guid()^GUID::hasher(0));
+
+               get_work_area()->add_duck(duck);                        
+
+               // Add the tangent1 duck
+               tduck=new WorkArea::Duck(bline_point.get_tangent1());
+               tduck->set_editable(true);
+               tduck->set_name(strprintf("%x-tangent1",value_node.get()));
+               tduck->set_origin(duck);
+               tduck->set_scalar(-0.33333333333333333);
+               tduck->set_tangent(true);
+               tduck->set_guid(value_node->get_guid()^GUID::hasher(3));
+               tduck->signal_edited().connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_tangent1_change),value_node)
+               );
+               tduck->signal_user_click(2).connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::popup_handle_menu),value_node)
+               );
+               
+               // See if we need to add that duck to the previous bezier
+               if(bezier)
+               {
+                       get_work_area()->add_duck(tduck);                       
+                       bezier->p2=duck;
+                       bezier->c2=tduck;
+
+                       bezier->signal_user_click(2).connect(
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &studio::StateBLine_Context::popup_bezier_menu
+                                       ),
+                                       value_node
+                               )
+                       );
+
+                       //get_work_area()->add_duck(bezier->c1);                        
+                       //get_work_area()->add_duck(bezier->c2);                        
+                       get_work_area()->add_bezier(bezier);
+
+                       bezier=0;
+               }
+               
+               // Now we see if we need to create a bezier
+               list<ValueNode_Const::Handle>::iterator next(iter);
+               next++;
+               
+               // If our next iterator is the end, then we don't need
+               // to add a bezier.
+               //if(next==bline_point_list.end() && !loop_)
+               //      continue;
+               
+               bezier=new WorkArea::Bezier();
+
+               // Add the tangent2 duck
+               tduck=new WorkArea::Duck(bline_point.get_tangent2());
+               tduck->set_editable(true);
+               tduck->set_origin(duck);
+               tduck->set_scalar(0.33333333333333333);
+               tduck->set_tangent(true);
+               if(bline_point.get_split_tangent_flag())
+               {
+                       tduck->set_name(strprintf("%x-tangent2",value_node.get()));
+                       tduck->signal_edited().connect(
+                               sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_tangent2_change),value_node)
+                       );
+               }
+               else
+               {
+                       tduck->set_name(strprintf("%x-tangent1",value_node.get()));
+                       tduck->signal_edited().connect(
+                               sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_tangent1_change),value_node)
+                       );
+               }
+               tduck->set_guid(value_node->get_guid()^GUID::hasher(4));
+               tduck->signal_user_click(2).connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::popup_handle_menu),value_node)
+               );
+               
+               // Setup the next bezier
+               bezier->p1=duck;
+               bezier->c1=tduck;
+
+               get_work_area()->add_duck(tduck);                       
+               curr_duck=tduck;
+       }
+       
+       // Add the loop, if requested
+       if(bezier && loop_)
+       {
+               curr_duck=0;
+               BLinePoint bline_point(bline_point_list.front()->get_value().get(BLinePoint()));
+
+               duck=new WorkArea::Duck(bline_point.get_vertex());
+               duck->set_editable(true);
+               duck->set_name(strprintf("%x-vertex",bline_point_list.front().get()));
+               duck->signal_edited().connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_vertex_change),bline_point_list.front())
+               );
+               duck->signal_user_click(2).connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::popup_vertex_menu),bline_point_list.front())
+               );
+               get_work_area()->add_duck(duck);                        
+
+               // Add the tangent1 duck
+               tduck=new WorkArea::Duck(bline_point.get_tangent1());
+               tduck->set_editable(true);
+               tduck->set_name(strprintf("%x-tangent1",bline_point_list.front().get()));
+               tduck->set_origin(duck);
+               tduck->set_scalar(-0.33333333333333333);
+               tduck->set_tangent(true);
+               tduck->signal_edited().connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::on_tangent1_change),bline_point_list.front())
+               );
+               tduck->signal_user_click(2).connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StateBLine_Context::popup_handle_menu),bline_point_list.front())
+               );
+               get_work_area()->add_duck(tduck);                       
+               
+               bezier->p2=duck;
+               bezier->c2=tduck;
+
+               bezier->signal_user_click(2).connect(
+                       sigc::bind(
+                               sigc::mem_fun(
+                                       *this,
+                                       &studio::StateBLine_Context::popup_bezier_menu
+                               ),
+                               bline_point_list.front()
+                       )
+               );
+
+               //get_work_area()->add_duck(bezier->c1);                        
+               get_work_area()->add_bezier(bezier);
+       }
+       if(bezier && !loop_)
+       {
+               duck=new WorkArea::Duck(bline_point.get_vertex());
+               duck->set_editable(false);
+               duck->set_name("temp");
+
+               // Add the tangent1 duck
+               tduck=new WorkArea::Duck(Vector(0,0));
+               tduck->set_editable(false);
+               tduck->set_name("ttemp");
+               tduck->set_origin(duck);
+               tduck->set_scalar(-0.33333333333333333);
+
+               tduck->set_tangent(true);
+               bezier->p2=duck;
+               bezier->c2=tduck;
+
+               get_work_area()->add_duck(bezier->p2);                  
+               //get_work_area()->add_duck(bezier->c2);                        
+               get_work_area()->add_bezier(bezier);
+
+               duck->set_guid(GUID());
+               tduck->set_guid(GUID());
+               
+               next_duck=duck;
+       }
+       
+       if(!button_down)
+       {
+               if(curr_duck)
+               {
+                       if(next_duck)
+                       {
+                               curr_duck=next_duck;
+                               next_duck=0;
+                       }
+               }
+       }
+       get_work_area()->queue_draw();                  
+}
+
+
+bool
+StateBLine_Context::on_vertex_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node)
+{
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+       bline_point.set_vertex(point);
+       value_node->set_value(bline_point);
+       //refresh_ducks();
+       return true;
+}
+
+bool
+StateBLine_Context::on_tangent1_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node)
+{
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+       bline_point.set_tangent1(point);
+       value_node->set_value(bline_point);
+       //refresh_ducks();
+       return true;
+}
+
+bool
+StateBLine_Context::on_tangent2_change(const sinfg::Point &point, sinfg::ValueNode_Const::Handle value_node)
+{
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+       bline_point.set_tangent2(point);
+       value_node->set_value(bline_point);
+       //refresh_ducks();
+       return true;
+}
+
+void
+StateBLine_Context::loop_bline()
+{
+       loop_=true;
+
+       refresh_ducks(false);
+}
+
+void
+StateBLine_Context::popup_vertex_menu(sinfg::ValueNode_Const::Handle value_node)
+{
+       menu.items().clear();
+
+       if(!loop_ && value_node==bline_point_list.front())
+       {
+               menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Loop BLine",
+                               sigc::mem_fun(*this,&studio::StateBLine_Context::loop_bline)
+               ));
+       }
+       
+       menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Delete Vertex",
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::StateBLine_Context::bline_delete_vertex),
+                       value_node
+               )
+       ));
+
+       menu.popup(0,0);
+}
+
+void
+StateBLine_Context::popup_bezier_menu(float location, sinfg::ValueNode_Const::Handle value_node)
+{
+       menu.items().clear();
+
+       menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Insert Vertex",
+               sigc::bind(
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::StateBLine_Context::bline_insert_vertex),
+                               location
+                       ),
+                       value_node
+               )
+       ));
+
+       menu.popup(0,0);
+}
+
+void
+StateBLine_Context::bline_insert_vertex(sinfg::ValueNode_Const::Handle value_node, float origin)
+{
+       list<ValueNode_Const::Handle>::iterator iter;
+       
+       for(iter=bline_point_list.begin();iter!=bline_point_list.end();++iter)
+               if(*iter==value_node)
+               {
+                       list<ValueNode_Const::Handle>::iterator prev(iter);
+                       --prev;
+
+                       BLinePoint bline_point;
+                       
+                       BLinePoint next_bline_point((*iter)->get_value().get(BLinePoint()));
+                       BLinePoint prev_bline_point;
+                       
+                       if(iter!=bline_point_list.begin())
+                       {
+                               prev_bline_point=(*prev)->get_value().get(BLinePoint());
+                       }
+                       else
+                       {
+                               prev_bline_point.set_vertex(Point(0,0));
+                               prev_bline_point.set_width(next_bline_point.get_width());
+                               prev_bline_point.set_origin(0.5);
+                               prev_bline_point.set_split_tangent_flag(false);
+                       }
+
+                       etl::hermite<Vector> curve(prev_bline_point.get_vertex(),next_bline_point.get_vertex(),prev_bline_point.get_tangent2(),next_bline_point.get_tangent1());
+                       etl::derivative< etl::hermite<Vector> > deriv(curve);
+
+                       bline_point.set_vertex(curve(origin));
+                       bline_point.set_width((next_bline_point.get_width()-prev_bline_point.get_width())*origin+prev_bline_point.get_width());
+#ifdef ETL_FIXED_DERIVATIVE
+                       bline_point.set_tangent1(deriv(origin)*std::min(1.0f-origin,origin));
+#else
+                       bline_point.set_tangent1(-deriv(origin)*std::min(1.0f-origin,origin));
+#endif
+                       bline_point.set_tangent2(bline_point.get_tangent1());
+                       bline_point.set_split_tangent_flag(false);
+                       bline_point.set_origin(origin);
+                       
+/*
+                       bline_point.set_vertex((next_bline_point.get_vertex()+prev_bline_point.get_vertex())*0.5);
+                       bline_point.set_width((next_bline_point.get_width()+prev_bline_point.get_width())*0.5);
+                       bline_point.set_origin(origin);
+                       bline_point.set_split_tangent_flag(false);
+                       bline_point.set_tangent1((next_bline_point.get_vertex()-prev_bline_point.get_vertex())*0.5);
+*/
+
+                       bline_point_list.insert(iter,ValueNode_Const::create(bline_point));
+                       break;
+               }
+
+       if(iter==bline_point_list.end())
+       {
+               get_canvas_view()->get_ui_interface()->error("Unable to find where to insert vertex, internal error, please report this bug");
+       }
+
+       refresh_ducks(false);   
+}
+
+void
+StateBLine_Context::bline_delete_vertex(sinfg::ValueNode_Const::Handle value_node)
+{
+       list<ValueNode_Const::Handle>::iterator iter;
+       
+       for(iter=bline_point_list.begin();iter!=bline_point_list.end();++iter)
+               if(*iter==value_node)
+               {
+                       bline_point_list.erase(iter);
+                       break;
+               }
+       if(iter==bline_point_list.end())
+       {
+               get_canvas_view()->get_ui_interface()->error("Unable to remove vertex, internal error, please report this bug");
+       }
+
+       refresh_ducks(false);   
+}
+
+void
+StateBLine_Context::popup_handle_menu(sinfg::ValueNode_Const::Handle value_node)
+{
+       menu.items().clear();
+
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+
+       if(bline_point.get_split_tangent_flag())
+               menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Merge Tangents",
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::StateBLine_Context::bline_attach_handle),
+                               value_node
+                       )
+               ));
+       else
+               menu.items().push_back(Gtk::Menu_Helpers::MenuElem("Split Tangents",
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::StateBLine_Context::bline_detach_handle),
+                               value_node
+                       )
+               ));
+
+       menu.popup(0,0);
+}
+
+void
+StateBLine_Context::bline_detach_handle(sinfg::ValueNode_Const::Handle value_node)
+{
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+       bline_point.set_split_tangent_flag(true);
+       bline_point.set_tangent2(bline_point.get_tangent1());
+       value_node->set_value(bline_point);
+       refresh_ducks(false);
+}
+
+void
+StateBLine_Context::bline_attach_handle(sinfg::ValueNode_Const::Handle value_node)
+{
+       BLinePoint bline_point(value_node->get_value().get(BLinePoint()));
+       bline_point.set_tangent1((bline_point.get_tangent1()+bline_point.get_tangent2())*0.5);
+       bline_point.set_split_tangent_flag(false);
+       value_node->set_value(bline_point);
+       refresh_ducks(false);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_bline.h b/synfig-studio/trunk/src/gtkmm/state_bline.h
new file mode 100644 (file)
index 0000000..03b0b39
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file rotoscope_bline.h
+**     \brief Template Header
+**
+**     $Id: state_bline.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_ROTOSCOPE_BLINE_H
+#define __SINFG_STUDIO_ROTOSCOPE_BLINE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateBLine_Context;
+
+class StateBLine : public Smach::state<StateBLine_Context>
+{
+public:
+       StateBLine();
+       ~StateBLine();
+}; // END of class StateBLine
+
+extern StateBLine state_bline;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_circle.cpp b/synfig-studio/trunk/src/gtkmm/state_circle.cpp
new file mode 100644 (file)
index 0000000..3969a6f
--- /dev/null
@@ -0,0 +1,500 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_circle.cpp
+**     \brief Template File
+**
+**     $Id: state_circle.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_circle.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+#include "widget_enum.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+enum CircleFalloff
+{
+       CIRCLE_SQUARED  =0,
+       CIRCLE_INTERPOLATION_LINEAR     =1,
+       CIRCLE_COSINE   =2,
+       CIRCLE_SIGMOND  =3,
+       CIRCLE_SQRT             =4,
+       CIRCLE_NUM_FALLOFF
+};
+
+/* === G L O B A L S ======================================================= */
+
+StateCircle studio::state_circle;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateCircle_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       Duckmatic::Push duckmatic_push;
+       
+       Point point_holder;
+       
+       etl::handle<Duck> point2_duck;
+
+       void refresh_ducks();
+       
+       bool prev_workarea_layer_status_;
+               
+       //Toolbox settings
+       sinfgapp::Settings& settings;
+       
+       //Toolbox display
+       Gtk::Table options_table;
+       
+       Gtk::Entry              entry_id; //what to name the layer
+       
+       Widget_Enum             enum_falloff;
+       Widget_Enum             enum_blend;
+       
+       Gtk::Adjustment adj_feather;
+       Gtk::SpinButton spin_feather;
+       
+       Gtk::CheckButton check_invert;
+       
+public:
+
+       sinfg::String get_id()const { return entry_id.get_text(); }
+       void set_id(const sinfg::String& x) { return entry_id.set_text(x); }
+
+       int get_falloff()const { return enum_falloff.get_value(); }
+       void set_falloff(int x) { return enum_falloff.set_value(x); }
+       
+       int get_blend()const { return enum_blend.get_value(); }
+       void set_blend(int x) { return enum_blend.set_value(x); }
+       
+       Real get_feather()const { return adj_feather.get_value(); }
+       void set_feather(Real f) { adj_feather.set_value(f); }
+       
+       bool get_invert()const { return check_invert.get_active(); }
+       void set_invert(bool i) { check_invert.set_active(i); }
+       
+       void refresh_tool_options(); //to refresh the toolbox   
+
+       //events
+       Smach::event_result event_stop_handler(const Smach::event& x);
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       //constructor destructor
+       StateCircle_Context(CanvasView* canvas_view);
+       ~StateCircle_Context();
+
+       //Canvas interaction
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //Modifying settings etc.
+       void load_settings();
+       void save_settings();
+       void reset();
+       void increment_id();
+       bool no_egress_on_selection_change;
+       Smach::event_result event_layer_selection_changed_handler(const Smach::event& x)
+       {
+               if(!no_egress_on_selection_change)
+                       throw Smach::egress_exception();
+               return Smach::RESULT_OK;
+       }
+
+       void make_circle(const Point& p1, const Point& p2);
+       
+};     // END of class StateGradient_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateCircle::StateCircle():
+       Smach::state<StateCircle_Context>("circle")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateCircle_Context::event_layer_selection_changed_handler));
+       insert(event_def(EVENT_STOP,&StateCircle_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateCircle_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateCircle_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateCircle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateCircle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateCircle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateCircle_Context::event_refresh_tool_options));
+}      
+
+StateCircle::~StateCircle()
+{
+}
+
+void
+StateCircle_Context::load_settings()
+{      
+       String value;
+       
+       //parse the arguments yargh!
+       if(settings.get_value("circle.id",value))
+               set_id(value);
+       else
+               set_id("Circle");
+
+       if(settings.get_value("circle.fallofftype",value) && value != "")
+               set_falloff(atoi(value.c_str()));
+       else
+               set_falloff(2);
+       
+       if(settings.get_value("circle.blend",value) && value != "")
+               set_blend(atoi(value.c_str()));
+       else
+               set_blend(0);//(int)Color::BLEND_COMPOSITE); //0 should be blend composites value
+       
+       if(settings.get_value("circle.feather",value))
+               set_feather(atof(value.c_str()));
+       else
+               set_feather(0);
+       
+       if(settings.get_value("circle.invert",value) && value != "0")
+               set_invert(true);
+       else
+               set_invert(false);
+}
+
+void
+StateCircle_Context::save_settings()
+{      
+       settings.set_value("circle.id",get_id());
+       settings.set_value("circle.fallofftype",strprintf("%d",get_falloff()));
+       settings.set_value("circle.blend",strprintf("%d",get_blend()));
+       settings.set_value("circle.feather",strprintf("%f",(float)get_feather()));
+       settings.set_value("circle.invert",get_invert()?"1":"0");
+}
+
+void
+StateCircle_Context::reset()
+{
+       refresh_ducks();
+}
+
+void
+StateCircle_Context::increment_id()
+{
+       String id(get_id());
+       int number=1;
+       int digits=0;
+       
+       if(id.empty())
+               id="Circle";
+       
+       // If there is a number
+       // already at the end of the
+       // id, then remove it.
+       if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
+       {
+               // figure out how many digits it is
+               for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false);
+               
+               String str_number;
+               str_number=String(id,id.size()-digits,id.size());
+               id=String(id,0,id.size()-digits);
+               
+               number=atoi(str_number.c_str());
+       }
+       else
+       {
+               number=1;
+               digits=3;
+       }
+       
+       number++;
+       
+       // Add the number back onto the id
+       {
+               const String format(strprintf("%%0%dd",digits));
+               id+=strprintf(format.c_str(),number);
+       }
+       
+       // Set the ID
+       set_id(id);
+}
+
+StateCircle_Context::StateCircle_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       duckmatic_push(get_work_area()),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       entry_id(),
+       adj_feather(0,0,1,0.01,0.1),
+       spin_feather(adj_feather,0.1,3),
+       check_invert(_("Invert"))
+{
+       no_egress_on_selection_change=false;
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Circle Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);      
+       options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       enum_falloff.set_param_desc(ParamDesc("falloff")
+               .set_local_name(_("Falloff"))
+               .set_description(_("Determines the falloff function for the feather"))
+               .set_hint("enum")
+               .add_enum_value(CIRCLE_INTERPOLATION_LINEAR,"linear",_("Linear"))
+               .add_enum_value(CIRCLE_SQUARED,"squared",_("Squared"))
+               .add_enum_value(CIRCLE_SQRT,"sqrt",_("Square Root"))
+               .add_enum_value(CIRCLE_SIGMOND,"sigmond",_("Sigmond"))
+               .add_enum_value(CIRCLE_COSINE,"cosine",_("Cosine")));
+       
+       enum_blend.set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method")
+               .set_local_name(_("Blend Method"))
+               .set_description(_("Defines the blend method to be used for circles")));
+       
+       load_settings();
+
+       //feather stuff
+       options_table.attach(*manage(new Gtk::Label(_("Feather:"))), 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(spin_feather, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(enum_falloff, 0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(enum_blend, 0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       //invert flag
+       options_table.attach(check_invert, 0, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       options_table.show_all();
+       
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+       
+       // Hide the tables if they are showing
+       //prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateCircle_Context::on_user_click));
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+
+       App::toolbox->refresh();
+}
+
+void
+StateCircle_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Circle Tool"));
+       App::dialog_tool_options->set_name("circle");
+}
+
+Smach::event_result
+StateCircle_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateCircle_Context::~StateCircle_Context()
+{
+       save_settings();
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       //if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateCircle_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateCircle_Context::event_refresh_handler(const Smach::event& x)
+{
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StateCircle_Context::make_circle(const Point& _p1, const Point& _p2)
+{
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Circle"));
+       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+       Layer::Handle layer;
+       
+       Canvas::Handle canvas(get_canvas_view()->get_canvas());
+       int depth(0);
+       
+       // we are temporarily using the layer to hold something
+       layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+       if(layer)
+       {
+               depth=layer->get_depth();
+               canvas=layer->get_canvas();
+       }
+
+       const sinfg::TransformStack& transform(get_canvas_view()->get_curr_transform_stack());
+       const Point p1(transform.unperform(_p1));
+       const Point p2(transform.unperform(_p2));
+       
+       if(get_falloff() >= 0 && get_falloff() < CIRCLE_NUM_FALLOFF)
+       {
+               
+               layer=get_canvas_interface()->add_layer_to("circle",canvas,depth);
+               
+               layer->set_param("pos",p1);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"pos");
+               
+               layer->set_param("radius",(p2-p1).mag());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
+               
+               layer->set_param("falloff",get_falloff());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"falloff");
+               
+               layer->set_param("feather",get_feather());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
+
+               layer->set_param("invert",get_invert());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
+               
+               layer->set_param("blend_method",get_blend());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
+               
+               layer->set_description(get_id());
+               get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+
+               no_egress_on_selection_change=true;
+               get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+               get_canvas_interface()->get_selection_manager()->set_selected_layer(layer);
+               no_egress_on_selection_change=false;
+       }
+       
+       reset();
+       increment_id();
+}
+
+Smach::event_result
+StateCircle_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DOWN && event.button==BUTTON_LEFT)
+       {
+               point_holder=get_work_area()->snap_point_to_grid(event.pos);
+               etl::handle<Duck> duck=new Duck();
+               duck->set_point(point_holder);
+               duck->set_name("p1");
+               duck->set_type(Duck::TYPE_POSITION);
+               duck->set_editable(false);
+               get_work_area()->add_duck(duck);
+
+               point2_duck=new Duck();
+               point2_duck->set_point(Vector(0,0));
+               point2_duck->set_name("radius");
+               point2_duck->set_origin(duck);
+               point2_duck->set_radius(true);
+               point2_duck->set_scalar(-1);
+               point2_duck->set_type(Duck::TYPE_RADIUS);
+               get_work_area()->add_duck(point2_duck);
+
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DRAG && event.button==BUTTON_LEFT)
+       {
+               point2_duck->set_point(point_holder-get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->queue_draw();                  
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button==BUTTON_LEFT)
+       {
+               make_circle(point_holder, get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->clear_ducks();
+               return Smach::RESULT_ACCEPT;
+       }
+
+       return Smach::RESULT_OK;
+}
+
+
+void
+StateCircle_Context::refresh_ducks()
+{
+       get_work_area()->clear_ducks();
+       get_work_area()->queue_draw();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_circle.h b/synfig-studio/trunk/src/gtkmm/state_circle.h
new file mode 100644 (file)
index 0000000..a794300
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_circle.h
+**     \brief Circle creation state
+**
+**     $Id: state_circle.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_CIRCLE_H
+#define __SINFG_STUDIO_STATE_CIRCLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateCircle_Context;
+
+class StateCircle : public Smach::state<StateCircle_Context>
+{
+public:
+       StateCircle();
+       ~StateCircle();
+}; // END of class StateCircle
+
+extern StateCircle state_circle;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_draw.cpp b/synfig-studio/trunk/src/gtkmm/state_draw.cpp
new file mode 100644 (file)
index 0000000..6e5d7d6
--- /dev/null
@@ -0,0 +1,1327 @@
+/* === S I N F G =========================================================== */
+/*!    \file rotoscope_bline.cpp
+**     \brief Template File
+**
+**     $Id: state_draw.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include "state_draw.h"
+#include "state_stroke.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+#include <sinfg/valuenode_bline.h>
+#include <sinfg/valuenode_composite.h>
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include <utility>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+
+#include <sinfgapp/blineconvert.h>
+#include <sinfgapp/main.h>
+
+#include <ETL/gaussian>
+#include "dialog_tooloptions.h"
+
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <gtkmm/button.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/scale.h>
+#include <sigc++/connection.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateDraw studio::state_draw;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateDraw_Context : public sigc::trackable
+{
+       typedef etl::smart_ptr<std::list<sinfg::Point> > StrokeData;
+       typedef etl::smart_ptr<std::list<sinfg::Real> > WidthData;
+       
+       typedef list< pair<StrokeData,WidthData> > StrokeQueue;
+       
+       StrokeQueue stroke_queue;
+       
+       
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       bool prev_table_status;
+       bool loop_;
+       bool prev_workarea_layer_status_;
+
+       int nested;
+       SigC::Connection process_queue_connection;
+       
+       ValueNode_BLine::Handle last_stroke;
+       
+       Gtk::Menu menu;
+
+       //Duckmatic::Push duckmatic_push;
+       
+       std::list< etl::smart_ptr<std::list<sinfg::Point> > > stroke_list;
+
+       void refresh_ducks();
+       
+       Duckmatic::Type old_duckmask;
+
+       void fill_last_stroke();
+       
+       Smach::event_result new_bline(std::list<sinfg::BLinePoint> bline,bool loop_bline_flag,float radius);
+
+       Smach::event_result new_region(std::list<sinfg::BLinePoint> bline,sinfg::Real radius);
+
+       Smach::event_result extend_bline_from_begin(ValueNode_BLine::Handle value_node,std::list<sinfg::BLinePoint> bline);
+       Smach::event_result extend_bline_from_end(ValueNode_BLine::Handle value_node,std::list<sinfg::BLinePoint> bline);
+       void reverse_bline(std::list<sinfg::BLinePoint> &bline);
+
+       sinfgapp::Settings& settings;
+
+       Gtk::Table options_table;
+       Gtk::CheckButton checkbutton_pressure_width;
+       Gtk::CheckButton checkbutton_round_ends;
+       Gtk::CheckButton checkbutton_auto_loop;
+       Gtk::CheckButton checkbutton_auto_connect;
+       Gtk::CheckButton checkbutton_region_only;
+       Gtk::Button button_fill_last_stroke;
+       
+       //pressure spinner and such
+       Gtk::Adjustment  adj_min_pressure;
+       Gtk::SpinButton  spin_min_pressure;
+       Gtk::CheckButton check_min_pressure;
+
+       Gtk::Adjustment  adj_feather;
+       Gtk::SpinButton  spin_feather;
+       
+       Gtk::Adjustment  adj_globalthres;
+       Gtk::SpinButton  spin_globalthres;
+       
+       Gtk::Adjustment  adj_localthres;
+       Gtk::CheckButton check_localerror;
+       void UpdateErrorBox();  //switches the stuff if need be :)
+
+       //Added by Adrian - data drive HOOOOO
+       sinfgapp::BLineConverter blineconv;
+
+public:
+       bool get_pressure_width_flag()const { return checkbutton_pressure_width.get_active(); }
+       void set_pressure_width_flag(bool x) { return checkbutton_pressure_width.set_active(x); }
+
+       bool get_auto_loop_flag()const { return checkbutton_auto_loop.get_active(); }
+       void set_auto_loop_flag(bool x) { return checkbutton_auto_loop.set_active(x); }
+
+       bool get_auto_connect_flag()const { return checkbutton_auto_connect.get_active(); }
+       void set_auto_connect_flag(bool x) { return checkbutton_auto_connect.set_active(x); }
+
+       bool get_region_only_flag()const { return checkbutton_region_only.get_active(); }
+       void set_region_only_flag(bool x) { return checkbutton_region_only.set_active(x); }
+       
+       Real get_min_pressure() const { return adj_min_pressure.get_value(); }
+       void set_min_pressure(Real x) { return adj_min_pressure.set_value(x); }
+
+       Real get_feather() const { return adj_feather.get_value(); }
+       void set_feather(Real x) { return adj_feather.set_value(x); }
+       
+       Real get_gthres() const { return adj_globalthres.get_value(); }
+       void set_gthres(Real x) { return adj_globalthres.set_value(x); }
+       
+       Real get_lthres() const { return adj_localthres.get_value(); }
+       void set_lthres(Real x) { return adj_localthres.set_value(x); }
+       
+       bool get_local_error_flag() const { return check_localerror.get_active(); }
+       void set_local_error_flag(bool x) { check_localerror.set_active(x); }
+       
+       bool get_min_pressure_flag()const { return check_min_pressure.get_active(); }
+       void set_min_pressure_flag(bool x) { check_min_pressure.set_active(x); }
+
+       void load_settings();
+       void save_settings();
+       
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_down_handler(const Smach::event& x);
+
+       Smach::event_result event_stroke(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+       void refresh_tool_options();
+
+       Smach::event_result process_stroke(StrokeData stroke_data, WidthData width_data, bool region_flag=false);
+
+       bool process_queue();
+       
+
+       StateDraw_Context(CanvasView* canvas_view);
+
+       ~StateDraw_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Time get_time()const { return get_canvas_interface()->get_time(); }
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //void on_user_click(sinfg::Point point);
+
+//     bool run();
+};     // END of class StateDraw_Context
+
+
+/* === M E T H O D S ======================================================= */
+
+StateDraw::StateDraw():
+       Smach::state<StateDraw_Context>("draw")
+{      
+       insert(event_def(EVENT_STOP,&StateDraw_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateDraw_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateDraw_Context::event_mouse_down_handler));
+       insert(event_def(EVENT_WORKAREA_STROKE,&StateDraw_Context::event_stroke));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateDraw_Context::event_refresh_tool_options));
+}
+
+StateDraw::~StateDraw()
+{
+}
+
+
+void
+StateDraw_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("draw.pressure_width",value) && value=="0")
+               set_pressure_width_flag(false);
+       else
+               set_pressure_width_flag(true);
+
+       if(settings.get_value("draw.auto_loop",value) && value=="0")
+               set_auto_loop_flag(false);
+       else
+               set_auto_loop_flag(true);
+
+       if(settings.get_value("draw.auto_connect",value) && value=="0")
+               set_auto_connect_flag(false);
+       else
+               set_auto_connect_flag(true);
+
+       if(settings.get_value("draw.region_only",value) && value=="1")
+               set_region_only_flag(true);
+       else
+               set_region_only_flag(false);
+       
+       if(settings.get_value("draw.min_pressure_on",value) && value=="0")
+               set_min_pressure_flag(false);
+       else
+               set_min_pressure_flag(true);
+       
+       if(settings.get_value("draw.min_pressure",value))
+       {
+               Real n = atof(value.c_str());
+               set_min_pressure(n);
+       }else
+               set_min_pressure(0);
+
+       if(settings.get_value("draw.feather",value))
+       {
+               Real n = atof(value.c_str());
+               set_feather(n);
+       }else
+               set_feather(0); 
+       
+       if(settings.get_value("draw.gthreshold",value))
+       {
+               Real n = atof(value.c_str());
+               set_gthres(n);
+       }
+       
+       if(settings.get_value("draw.lthreshold",value))
+       {
+               Real n = atof(value.c_str());
+               set_lthres(n);
+       }
+       
+       if(settings.get_value("draw.localize",value) && value == "1")
+               set_local_error_flag(true);
+       else
+               set_local_error_flag(false);
+}
+
+void
+StateDraw_Context::save_settings()
+{      
+       settings.set_value("draw.pressure_width",get_pressure_width_flag()?"1":"0");
+       settings.set_value("draw.auto_loop",get_auto_loop_flag()?"1":"0");
+       settings.set_value("draw.auto_connect",get_auto_connect_flag()?"1":"0");
+       settings.set_value("draw.region_only",get_region_only_flag()?"1":"0");
+       settings.set_value("draw.min_pressure",strprintf("%f",get_min_pressure()));
+       settings.set_value("draw.feather",strprintf("%f",get_feather()));
+       settings.set_value("draw.min_pressure_on",get_min_pressure_flag()?"1":"0");
+       settings.set_value("draw.gthreshold",strprintf("%f",get_gthres()));
+       settings.set_value("draw.lthreshold",strprintf("%f",get_lthres()));     
+       settings.set_value("draw.localize",get_local_error_flag()?"1":"0");
+}
+
+StateDraw_Context::StateDraw_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       loop_(false),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       checkbutton_pressure_width(_("Pressure Width")),
+       checkbutton_auto_loop(_("Auto Loop")),
+       checkbutton_auto_connect(_("Auto Connect")),
+       checkbutton_region_only(_("Create Region Only")),
+       button_fill_last_stroke(_("Fill Last Stroke")),
+       adj_min_pressure(0,0,1,0.01,0.1),
+       spin_min_pressure(adj_min_pressure,0.1,3),
+       check_min_pressure(_("Min Pressure")),
+       adj_feather(0,0,10000,0.01,0.1),
+       spin_feather(adj_feather,0.01,4),
+       adj_globalthres(.70f,0.01,10000,0.01,0.1),
+       spin_globalthres(adj_globalthres,0.01,3),
+       adj_localthres(20,1,100000,0.1,1),      
+       check_localerror(_("LocalError"))
+       
+{
+       sinfg::info("STATE SKETCH: entering state");
+
+       nested=0;
+       load_settings();
+       
+       UpdateErrorBox();
+       
+       //options_table.attach(*manage(new Gtk::Label(_("Draw Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+       options_table.attach(checkbutton_pressure_width, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(checkbutton_auto_loop, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       options_table.attach(checkbutton_auto_connect, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); 
+       options_table.attach(checkbutton_region_only, 0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  
+       
+       options_table.attach(check_min_pressure, 0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(spin_min_pressure, 0, 2, 6, 7, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       options_table.attach(*manage(new Gtk::Label(_("Feather"))), 0, 1, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       options_table.attach(spin_feather, 1, 2, 7, 8, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       options_table.attach(check_localerror, 0, 2, 8, 9, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0); 
+       options_table.attach(*manage(new Gtk::Label(_("Smooth"))), 0, 1, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       options_table.attach(spin_globalthres, 1, 2, 9, 10, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       //options_table.attach(button_fill_last_stroke, 0, 2, 10, 11, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);      
+       
+       button_fill_last_stroke.signal_pressed().connect(sigc::mem_fun(*this,&StateDraw_Context::fill_last_stroke));
+       check_localerror.signal_toggled().connect(sigc::mem_fun(*this,&StateDraw_Context::UpdateErrorBox));
+       
+       options_table.show_all();
+       refresh_tool_options();
+       //App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->present();
+       
+       
+       old_duckmask=get_work_area()->get_type_mask();
+       get_work_area()->set_type_mask(Duck::TYPE_ALL-Duck::TYPE_TANGENT-Duck::TYPE_WIDTH);
+       
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+
+       // Turn off duck clicking
+       get_work_area()->allow_duck_clicks=false;
+       
+       // clear out the ducks
+       //get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       //get_work_area()->queue_draw();
+       
+       // Hide the tables if they are showing
+       prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateDraw_Context::on_user_click));
+
+       get_canvas_view()->work_area->set_cursor(Gdk::PENCIL);
+
+       App::toolbox->refresh();
+       
+       refresh_ducks();
+}
+
+
+void StateDraw_Context::UpdateErrorBox()
+{
+       if(get_local_error_flag())
+       {
+               spin_globalthres.set_adjustment(adj_localthres);
+               spin_globalthres.set_value(adj_localthres.get_value());
+               spin_globalthres.set_increments(0.1,1);
+       }else
+       {
+               spin_globalthres.set_adjustment(adj_globalthres);
+               spin_globalthres.set_value(adj_globalthres.get_value());
+               spin_globalthres.set_increments(0.01,.1);
+       }
+       
+       spin_globalthres.update();
+}
+
+void
+StateDraw_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Draw Tool"));
+       App::dialog_tool_options->set_name("draw");
+       
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("sinfg-fill"),
+               _("Fill Last Stroke")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &StateDraw_Context::fill_last_stroke
+               )
+       );
+
+}
+
+Smach::event_result
+StateDraw_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateDraw_Context::~StateDraw_Context()
+{
+       save_settings();
+
+       App::dialog_tool_options->clear();
+
+       get_work_area()->set_type_mask(old_duckmask);
+       
+       get_canvas_view()->work_area->reset_cursor();
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+
+       // Restore duck clicking
+       get_work_area()->allow_duck_clicks=true;
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateDraw_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateDraw_Context::event_refresh_handler(const Smach::event& x)
+{
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateDraw_Context::event_mouse_down_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               {
+                       // Enter the stroke state to get the stroke
+                       get_canvas_view()->get_smach().push_state(&state_stroke);
+                       return Smach::RESULT_ACCEPT;
+               }
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
+
+#define SIMILAR_TANGENT_THRESHOLD      (0.2)
+
+struct debugclass
+{
+       sinfg::String x;
+       debugclass(const sinfg::String &x):x(x)
+       {
+//             sinfg::warning(">>>>>>>>>>>>>>>>>>> "+x);
+       }
+       ~debugclass()
+       {
+//             sinfg::warning("<<<<<<<<<<<<<<<<<<< "+x);
+       }
+};
+
+struct DepthCounter
+{
+       int &i;
+       DepthCounter(int &i):i(i) { i++; }
+       ~DepthCounter() { i--; }        
+};
+
+Smach::event_result
+StateDraw_Context::event_stroke(const Smach::event& x)
+{
+//     debugclass debugger("StateDraw_Context::event_stroke(const Smach::event& x)");
+               
+       const EventStroke& event(*reinterpret_cast<const EventStroke*>(&x));
+
+       assert(event.stroke_data);
+
+       get_work_area()->add_stroke(event.stroke_data,sinfgapp::Main::get_foreground_color());
+       
+       if(nested==0)
+       {
+               DirtyTrap dirty_trap(get_work_area());
+               Smach::event_result result;
+               result=process_stroke(event.stroke_data,event.width_data,event.modifier&Gdk::CONTROL_MASK || event.modifier&Gdk::BUTTON2_MASK);
+               process_queue();
+               return result;
+       }
+       
+       stroke_queue.push_back(pair<StrokeData,WidthData>(event.stroke_data,event.width_data));
+
+       return Smach::RESULT_ACCEPT;    
+}
+
+bool
+StateDraw_Context::process_queue()
+{
+//     debugclass debugger("StateDraw_Context::process_queue()");
+       if(nested)
+               return true;
+       DepthCounter depth_counter(nested);
+       while(!stroke_queue.empty())
+       {
+               pair<StrokeData,WidthData> front(stroke_queue.front());
+               process_stroke(front.first,front.second);
+               stroke_queue.pop_front();
+       }
+       return false;
+}
+
+Smach::event_result
+StateDraw_Context::process_stroke(StrokeData stroke_data, WidthData width_data, bool region_flag)
+{
+//     debugclass debugger("StateDraw_Context::process_stroke");
+       DepthCounter depth_counter(nested);
+       
+       const float radius(sinfgapp::Main::get_bline_width().units(get_canvas()->rend_desc())+(abs(get_work_area()->get_pw())+abs(get_work_area()->get_ph()))*5);
+
+
+       // If we aren't using pressure width,
+       // then set all the width to 1
+       if(!get_pressure_width_flag())
+       {
+               std::list<sinfg::Real>::iterator iter;
+               for(iter=width_data->begin();iter!=width_data->end();++iter)
+               {
+                       *iter=1.0;
+               }
+       }
+       
+       //get_work_area()->add_stroke(event.stroke_data,sinfgapp::Main::get_foreground_color());
+       //stroke_list.push_back(event.stroke_data);
+       //refresh_ducks();
+               
+       std::list<sinfg::BLinePoint> bline;
+       bool loop_bline_flag(false);
+       
+       //Changed by Adrian - use resident class :)
+       //sinfgapp::convert_stroke_to_bline(bline, *event.stroke_data,*event.width_data, sinfgapp::Main::get_bline_width());
+       blineconv.width = sinfgapp::Main::get_bline_width().units(get_canvas()->rend_desc());
+       
+       if(get_local_error_flag())
+       {
+               float pw = get_work_area()->get_pw();
+               float ph = get_work_area()->get_ph();
+               
+               blineconv.pixelwidth = sqrt(pw*pw+ph*ph);
+               blineconv.smoothness = get_lthres();
+       }else
+       {
+               blineconv.pixelwidth = 1;
+               blineconv.smoothness = get_gthres();            
+       }
+       
+       blineconv(bline,*stroke_data,*width_data);
+       
+       //Postprocess to require minimum pressure
+       if(get_min_pressure_flag())
+       {
+               sinfgapp::BLineConverter::EnforceMinWidth(bline,get_min_pressure());
+       }
+       
+       // If the start and end points are similar, then make then the same point
+       if(get_auto_loop_flag())
+       if(bline.size()>2&&(bline.front().get_vertex()-bline.back().get_vertex()).mag()<=radius)
+       {
+               loop_bline_flag=true;
+               Vector tangent;
+               Real width(0);
+
+               while(bline.size()>2&&(bline.front().get_vertex()-bline.back().get_vertex()).mag()<=radius)
+               {
+                       tangent=bline.back().get_tangent1();
+                       width=bline.back().get_width();
+                       bline.pop_back();
+               }
+               
+               if(abs(bline.front().get_tangent1().norm()*tangent.norm().perp())>SIMILAR_TANGENT_THRESHOLD)
+               {
+                       // If the tangents are not similar, then
+                       // split the tangents
+                       bline.front().set_split_tangent_flag(true);
+                       bline.front().set_tangent1(tangent);
+               }
+               else
+               {
+                       // If the tangents are similar, then set the tangent
+                       // to the average of the two
+                       bline.front().set_tangent((tangent+bline.front().get_tangent1())*0.5f);
+               }
+               
+               // Add the widths of the two points
+               {       
+                       Real width(bline.front().get_width()+width);
+                       width=width<=1?width:1;
+                       bline.front().set_width(width);
+               }
+       }
+
+       // If the bline only has once blinepoint, then there is nothing to do.
+       if(bline.size()<=1)
+               return Smach::RESULT_OK;
+
+       if(region_flag)
+               return new_region(bline,radius);
+
+       return new_bline(bline,loop_bline_flag,radius);
+}
+
+Smach::event_result
+StateDraw_Context::new_bline(std::list<sinfg::BLinePoint> bline,bool loop_bline_flag,float radius)
+{
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Sketch BLine"));
+
+       //ValueNode_BLine::Handle value_node(ValueNode_BLine::create(sinfg::ValueBase(bline,loop_bline_flag)));
+       ValueNode_BLine::Handle value_node;
+
+       {
+               std::list<sinfg::BLinePoint> trans_bline;
+               std::list<sinfg::BLinePoint>::iterator iter;
+               const sinfg::TransformStack& transform(get_canvas_view()->get_curr_transform_stack());
+               
+               for(iter=bline.begin();iter!=bline.end();++iter)
+               {
+                       BLinePoint bline_point(*iter);
+                       Point new_vertex(transform.unperform(bline_point.get_vertex()));
+                       
+                       bline_point.set_tangent1(
+                               transform.unperform(
+                                       bline_point.get_tangent1()+bline_point.get_vertex()
+                               ) -new_vertex
+                       );
+
+                       bline_point.set_tangent2(
+                               transform.unperform(
+                                       bline_point.get_tangent2()+bline_point.get_vertex()
+                               ) -new_vertex
+                       );
+                       
+                       bline_point.set_vertex(new_vertex);
+                       
+                       trans_bline.push_back(bline_point);
+               }
+               value_node=ValueNode_BLine::create(sinfg::ValueBase(trans_bline,loop_bline_flag));
+       }
+
+       // Find any ducks at the start or end that we might attach to
+       // (If we aren't a loop)
+       if(!loop_bline_flag && get_auto_connect_flag())
+       {
+               
+               etl::handle<Duck> start_duck(get_work_area()->find_duck(bline.front().get_vertex(),radius,Duck::TYPE_VERTEX));
+               etl::handle<Duck> finish_duck(get_work_area()->find_duck(bline.back().get_vertex(),radius,Duck::TYPE_VERTEX));
+               
+               if(start_duck)do
+               {
+                       sinfgapp::ValueDesc value_desc(start_duck->get_value_desc());
+                       if(!value_desc)
+                       {
+                               break;
+                       }
+
+                       ValueNode_BLine::Handle value_node_bline;
+
+                       if(value_desc.parent_is_value_node())
+                       {
+                               value_node_bline=ValueNode_BLine::Handle::cast_dynamic(value_desc.get_parent_value_node());
+                       }
+                       if(value_node_bline)
+                       {
+                               if(value_desc.get_index()==0)
+                               {
+                                       // SPECIAL CASE -- EXTENSION
+                                       // We need to reverse the BLine first.
+                                       bline.pop_front();
+                                       reverse_bline(bline);
+                                       return extend_bline_from_begin(value_node_bline,bline);                                 
+                               }
+                               if(value_desc.get_index()==value_node_bline->link_count()-1)
+                               {
+                                       // SPECIAL CASE -- EXTENSION
+                                       bline.pop_front();
+                                       return extend_bline_from_end(value_node_bline,bline);
+                               }
+                       }
+
+                       switch(value_desc.get_value_type())
+                       {
+                       case sinfg::ValueBase::TYPE_BLINEPOINT:
+                               //get_canvas_interface()->auto_export(value_desc);
+                               //value_node->list.front().value_node=value_desc.get_value_node();
+                               
+                               value_desc=sinfgapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node()),0);
+                               //break;
+                       case sinfg::ValueBase::TYPE_VECTOR:
+                               get_canvas_interface()->auto_export(value_desc);
+                               LinkableValueNode::Handle::cast_dynamic(value_node->list.front().value_node)->set_link(0,value_desc.get_value_node());
+                               break;
+                       default:
+                               break;
+                       }
+               }while(0);
+               
+               if(finish_duck)do
+               {
+                       sinfgapp::ValueDesc value_desc(finish_duck->get_value_desc());
+                       if(!value_desc)
+                       {
+                               break;
+                       }
+
+                       ValueNode_BLine::Handle value_node_bline;
+
+                       if(value_desc.parent_is_value_node())
+                               value_node_bline=ValueNode_BLine::Handle::cast_dynamic(value_desc.get_parent_value_node());
+                       if(value_node_bline)
+                       {
+                               if(value_desc.get_index()==0)
+                               {
+                                       // SPECIAL CASE -- EXTENSION
+                                       bline.pop_back();
+                                       return extend_bline_from_begin(value_node_bline,bline);                                 
+                               }
+                               if(value_desc.get_index()==value_node_bline->link_count()-1)
+                               {
+                                       // SPECIAL CASE -- EXTENSION
+                                       // We need to reverse the BLine first.
+                                       bline.pop_back();
+                                       reverse_bline(bline);
+                                       return extend_bline_from_end(value_node_bline,bline);
+                               }
+                       }
+
+                       switch(value_desc.get_value_type())
+                       {
+                       case sinfg::ValueBase::TYPE_BLINEPOINT:
+                               //get_canvas_interface()->auto_export(value_desc);
+                               //value_node->list.back().value_node=value_desc.get_value_node();
+
+                               value_desc=sinfgapp::ValueDesc(LinkableValueNode::Handle::cast_dynamic(value_desc.get_value_node()),0);
+                               //break;
+                       case sinfg::ValueBase::TYPE_VECTOR:
+                               get_canvas_interface()->auto_export(value_desc);
+                               LinkableValueNode::Handle::cast_dynamic(value_node->list.back().value_node)->set_link(0,value_desc.get_value_node());
+                               break;
+                       default:
+                               break;
+                       }
+                       
+               }while(0);
+       }
+       
+       // Create the layer
+       {
+               Layer::Handle layer;
+               Canvas::Handle canvas(get_canvas_view()->get_canvas());
+               int depth(0);
+               
+               // we are temporarily using the layer to hold something
+               layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+               if(layer)
+               {
+                       depth=layer->get_depth();
+                       canvas=layer->get_canvas();
+               }
+               
+               //int number(sinfg::UniqueID().get_uid());
+               
+               sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+               
+               if(get_region_only_flag())
+                       layer=get_canvas_interface()->add_layer_to("region",canvas,depth);
+               else
+                       layer=get_canvas_interface()->add_layer_to("outline",canvas,depth);
+                       
+               if(get_feather())
+               {
+                       layer->set_param("feather",get_feather());
+                       get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
+               }
+               assert(layer);
+               //layer->set_description(strprintf("Stroke %d",number));
+               //get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+               
+               
+               
+               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+               
+               assert(action);
+               
+               action->set_param("canvas",get_canvas());                       
+               action->set_param("canvas_interface",get_canvas_interface());                   
+               action->set_param("layer",layer);                       
+               if(!action->set_param("param",String("bline")))
+                       sinfg::error("LayerParamConnect didn't like \"param\"");
+               if(!action->set_param("value_node",ValueNode::Handle(value_node)))
+                       sinfg::error("LayerParamConnect didn't like \"value_node\"");
+               
+               if(!get_canvas_interface()->get_instance()->perform_action(action))
+               {
+                       get_canvas_view()->get_ui_interface()->error(_("Unable to create layer"));
+                       group.cancel();
+                       //refresh_ducks();
+                       return Smach::RESULT_ERROR;
+               }
+               get_canvas_view()->get_selection_manager()->set_selected_layer(layer);
+               //refresh_ducks();
+       }
+       
+       last_stroke=value_node;
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateDraw_Context::new_region(std::list<sinfg::BLinePoint> bline, sinfg::Real radius)
+{
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Define Region"));
+       
+       std::list<sinfgapp::ValueDesc> vertex_list;
+       
+       // First we need to come up with a rough list of
+       // BLinePoints that we are going to be using to
+       // define our region. 
+       {
+               std::list<sinfg::BLinePoint>::iterator iter;
+               for(iter=bline.begin();iter!=bline.end();++iter)
+               {
+                       etl::handle<Duck> duck(get_work_area()->find_duck(iter->get_vertex(),0,Duck::TYPE_VERTEX));
+                       
+                       if(!duck)
+                       {
+                               sinfg::info(__FILE__":%d: Nothing to enclose!",__LINE__);                               
+                               return Smach::RESULT_OK;                
+                       }
+                       
+                       
+                       assert(duck->get_type()==Duck::TYPE_VERTEX);
+                       
+                       sinfgapp::ValueDesc value_desc(duck->get_value_desc());
+                       
+                       if(!value_desc)
+                       {
+                               sinfg::info(__FILE__":%d: Got a hit, but no ValueDesc on this duck",__LINE__);                          
+                               continue;
+                       }
+                       
+                       switch(value_desc.get_value_type())
+                       {
+                       case sinfg::ValueBase::TYPE_BLINEPOINT:
+                               //if(vertex_list.empty() || value_desc!=vertex_list.back())
+                               vertex_list.push_back(value_desc);
+                               assert(vertex_list.back().is_valid());
+                       
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+       
+       if(vertex_list.size()<=2)
+       {
+               sinfg::info(__FILE__":%d: Vertex list too small to make region.",__LINE__);
+               return Smach::RESULT_OK;                
+       }
+
+       assert(vertex_list.back().is_valid());
+       
+       // Remove any duplicates
+       {
+       }
+       
+       // Now we need to clean the list of vertices up
+       // a bit. This includes inserting missing vertices
+       // and removing extraneous ones.
+       // We can do this in multiple passes.
+       int i=0;
+       for(bool done=false;!done && i<30;i++)
+       {
+               // Set done to "true" for now. If
+               // any updates are performed, we will
+               // change it back to false.
+               done=true;
+               
+               std::list<sinfgapp::ValueDesc>::iterator prev,iter,next;
+               prev=vertex_list.end();prev--;  // Set prev to the last ValueDesc
+               next=vertex_list.begin();
+               iter=next++; // Set iter to the first value desc, and next to the second
+               
+               for(;iter!=vertex_list.end();prev=iter,iter=next++)
+               {
+                       sinfgapp::ValueDesc value_prev(*prev);
+                       sinfgapp::ValueDesc value_desc(*iter);
+                       sinfgapp::ValueDesc value_next((next==vertex_list.end())?vertex_list.front():*next);
+                       
+                       assert(value_desc.is_valid());
+                       assert(value_next.is_valid());
+                       assert(value_prev.is_valid());
+                       
+                       //sinfg::info("-------");
+                       //sinfg::info(__FILE__":%d: value_prev 0x%08X:%d",__LINE__,value_prev.get_parent_value_node().get(),value_prev.get_index());
+                       //sinfg::info(__FILE__":%d: value_desc 0x%08X:%d",__LINE__,value_desc.get_parent_value_node().get(),value_desc.get_index());
+                       //sinfg::info(__FILE__":%d: value_next 0x%08X:%d",__LINE__,value_next.get_parent_value_node().get(),value_next.get_index());
+
+                       /*
+                       if(value_prev.parent_is_value_node() && value_desc.parent_is_value_node() && value_next.parent_is_value_node())
+                       {
+                               // Remove random extraneous vertices
+                               if(value_prev.get_parent_value_node()==value_next.get_parent_value_node() &&
+                                       value_prev.get_parent_value_node()!=value_desc.get_parent_value_node())
+                               {
+                                       DEBUGPOINT();
+                                       vertex_list.erase(iter);
+                                       done=false;
+                                       break;
+                               }
+                       }       
+                       */
+                       
+                       // Remove duplicate vertices
+                       if(value_prev.get_value_node()==value_desc.get_value_node()
+                               || value_desc.get_value_node()==value_next.get_value_node())
+                       {
+                               DEBUGPOINT();
+                               vertex_list.erase(iter);
+                               done=false;
+                               break;
+                       }
+                       if(value_prev.get_value_node()==value_next.get_value_node())
+                       {
+                               DEBUGPOINT();
+                               vertex_list.erase(prev);
+                               done=false;
+                               break;
+                       }
+                       
+                       if(value_desc.parent_is_value_node() && value_next.parent_is_value_node())
+                       if(value_desc.get_parent_value_node()==value_next.get_parent_value_node() && (next!=vertex_list.end()))
+                       {
+                               // Fill in missing vertices
+                               if(value_desc.get_index()<value_next.get_index()-1)
+                               {
+                                       DEBUGPOINT();
+                                       vertex_list.insert(next,sinfgapp::ValueDesc(value_desc.get_parent_value_node(),value_desc.get_index()+1));
+                                       done=false;
+                                       break;
+                               }
+                               if(value_next.get_index()<value_desc.get_index()-1)
+                               {
+                                       DEBUGPOINT();
+                                       vertex_list.insert(next,sinfgapp::ValueDesc(value_desc.get_parent_value_node(),value_next.get_index()+1));
+                                       done=false;
+                                       break;
+                               }
+                       }
+                       
+                       // Ensure that connections
+                       // between blines are properly
+                       // connected
+                       if(value_desc.parent_is_value_node() && value_next.parent_is_value_node())
+                       if(value_desc.get_parent_value_node()!=value_next.get_parent_value_node() &&
+                               value_desc.get_value_node()!=value_next.get_value_node())
+                       {
+                               BLinePoint vertex(value_desc.get_value(get_time()).get(BLinePoint()));
+                               BLinePoint vertex_next(value_next.get_value(get_time()).get(BLinePoint()));
+
+                               //sinfg::info("--------");
+                               //sinfg::info(__FILE__":%d: vertex: [%f, %f]",__LINE__,vertex.get_vertex()[0],vertex.get_vertex()[1]);
+                               //sinfg::info(__FILE__":%d: vertex_next: [%f, %f]",__LINE__,vertex_next.get_vertex()[0],vertex_next.get_vertex()[1]);
+                               
+                               if((vertex.get_vertex()-vertex_next.get_vertex()).mag_squared()<radius*radius)
+                               {
+                                       DEBUGPOINT();
+                                       ValueNode_Composite::Handle value_node;
+                                       ValueNode_Composite::Handle value_node_next;
+                                       value_node=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node().clone());
+                                       value_node_next=ValueNode_Composite::Handle::cast_dynamic(value_next.get_value_node().clone());
+                                       if(!value_node || !value_node_next)
+                                       {
+                                               sinfg::info(__FILE__":%d: Unable to properly connect blines.",__LINE__);
+                                               continue;
+                                       }
+                                       DEBUGPOINT();
+                                       value_node->set_link(5,value_node_next->get_link(5));
+                                       value_node->set_link(3,ValueNode_Const::create(true));
+
+                                       get_canvas_interface()->auto_export(value_node);
+                                       assert(value_node->is_exported());
+                                       *iter=sinfgapp::ValueDesc(get_canvas(),value_node->get_id());
+                                       vertex_list.erase(next);
+                                       done=false;
+                                       break;                                  
+                               }
+                               else
+                               {
+                                       DEBUGPOINT();
+                                       bool positive_trend(value_desc.get_index()>value_prev.get_index());
+                                       
+                                       if(!positive_trend && value_desc.get_index()>0)
+                                       {
+                                               DEBUGPOINT();
+                                               vertex_list.insert(next,sinfgapp::ValueDesc(value_desc.get_parent_value_node(),value_desc.get_index()-1));
+                                               done=false;
+                                               break;                                  
+                                       }
+                                       if(positive_trend && value_desc.get_index()<LinkableValueNode::Handle::cast_static(value_desc.get_value_node())->link_count()-1)
+                                       {
+                                               DEBUGPOINT();
+                                               vertex_list.insert(next,sinfgapp::ValueDesc(value_desc.get_parent_value_node(),value_desc.get_index()+1));
+                                               done=false;
+                                               break;                                  
+                                       }
+                               }
+                               
+                       }
+               }
+       }
+
+       if(vertex_list.size()<=2)
+       {
+               sinfg::info(__FILE__":%d: Vertex list too small to make region.",__LINE__);
+               return Smach::RESULT_OK;                
+       }
+       
+       ValueNode_BLine::Handle value_node_bline;
+
+       // Now we need to test for the trivial case,
+       // which is where all of the vertices
+       // come from one BLine. 
+       if(vertex_list.front().parent_is_linkable_value_node())
+       {
+               bool trivial_case(true);
+               ValueNode::Handle trivial_case_value_node;
+               
+               trivial_case_value_node=vertex_list.front().get_parent_value_node();
+               
+               std::list<sinfgapp::ValueDesc>::iterator iter;
+               for(iter=vertex_list.begin();iter!=vertex_list.end();++iter)
+               {
+                       if(trivial_case_value_node!=iter->get_parent_value_node())
+                       {
+                               trivial_case=false;
+                               break;
+                       }
+               }
+               if(trivial_case)
+                       value_node_bline=ValueNode_BLine::Handle::cast_dynamic(trivial_case_value_node);
+       }
+       
+       // If we aren't the trivial case,
+       // then go ahead and create the new
+       // BLine value node
+       if(!value_node_bline)
+       {
+               value_node_bline=ValueNode_BLine::create();
+
+               std::list<sinfgapp::ValueDesc>::iterator iter;          
+               for(iter=vertex_list.begin();iter!=vertex_list.end();++iter)
+               {
+                       // Ensure that the vertex is exported.
+                       get_canvas_interface()->auto_export(*iter);     
+                       
+                       value_node_bline->add(iter->get_value_node());  
+                       //value_node_bline->add(ValueNode_BLine::ListEntry(iter->get_value_node()));    
+               }
+               
+               value_node_bline->set_loop(true);
+       }
+
+       get_canvas_interface()->auto_export(value_node_bline);                  
+
+       // Now we create the region layer
+       // Create the layer
+       {
+               Layer::Handle layer;
+               Canvas::Handle canvas(get_canvas_view()->get_canvas());
+               int depth(0);
+               
+               // we are temporarily using the layer to hold something
+               layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+               if(layer)
+               {
+                       depth=layer->get_depth();
+                       canvas=layer->get_canvas();
+               }
+               
+               sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+               
+               layer=get_canvas_interface()->add_layer_to("region",canvas,depth);
+               assert(layer);
+               layer->set_param("color",sinfgapp::Main::get_background_color());
+               if(get_feather())
+               {
+                       layer->set_param("feather",get_feather());
+                       get_canvas_interface()->signal_layer_param_changed()(layer,"feather");
+               }
+               get_canvas_interface()->signal_layer_param_changed()(layer,"color");
+
+               sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+               
+               assert(action);
+               
+               action->set_param("canvas",get_canvas());                       
+               action->set_param("canvas_interface",get_canvas_interface());                   
+               action->set_param("layer",layer);                       
+               if(!action->set_param("param",String("bline")))
+                       sinfg::error("LayerParamConnect didn't like \"param\"");
+               if(!action->set_param("value_node",ValueNode::Handle(value_node_bline)))
+                       sinfg::error("LayerParamConnect didn't like \"value_node\"");
+               
+               if(!get_canvas_interface()->get_instance()->perform_action(action))
+               {
+                       get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
+                       group.cancel();
+                       return Smach::RESULT_ERROR;
+               }
+               get_canvas_view()->get_selection_manager()->set_selected_layer(layer);
+       }
+       
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StateDraw_Context::refresh_ducks()
+{
+       get_canvas_view()->queue_rebuild_ducks();
+/*
+       get_work_area()->clear_ducks();
+       
+       
+       std::list< etl::smart_ptr<std::list<sinfg::Point> > >::iterator iter;
+       
+       for(iter=stroke_list.begin();iter!=stroke_list.end();++iter)
+       {
+               get_work_area()->add_stroke(*iter);
+       }
+       
+       get_work_area()->queue_draw();                  
+*/
+}
+
+
+Smach::event_result
+StateDraw_Context::extend_bline_from_begin(ValueNode_BLine::Handle value_node,std::list<sinfg::BLinePoint> bline)
+{
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Extend BLine"));
+       
+       std::list<sinfg::BLinePoint>::reverse_iterator iter;
+       iter=bline.rbegin();
+       for(;!(iter==bline.rend());++iter)
+       {
+               //iter->reverse();
+               ValueNode_Composite::Handle composite(ValueNode_Composite::create(*iter));
+
+               sinfgapp::Action::Handle action(sinfgapp::Action::create("value_node_dynamic_list_insert"));
+               
+               assert(action);
+               sinfgapp::ValueDesc value_desc(value_node,0);
+               
+               action->set_param("canvas",get_canvas());                       
+               action->set_param("canvas_interface",get_canvas_interface());                   
+               action->set_param("value_desc",value_desc);
+               if(!action->set_param("item",ValueNode::Handle(composite)))
+                       sinfg::error("ACTION didn't like \"item\"");
+               
+               if(!get_canvas_interface()->get_instance()->perform_action(action))
+               {
+                       get_canvas_view()->get_ui_interface()->error(_("Unable to insert item"));
+                       group.cancel();
+                       //refresh_ducks();
+                       return Smach::RESULT_ERROR;
+               }               
+       }
+       last_stroke=value_node;
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateDraw_Context::extend_bline_from_end(ValueNode_BLine::Handle value_node,std::list<sinfg::BLinePoint> bline)
+{
+       // Create the action group
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Extend BLine"));
+
+       std::list<sinfg::BLinePoint>::iterator iter;
+       iter=bline.begin();
+       for(;iter!=bline.end();++iter)
+       {
+               ValueNode_Composite::Handle composite(ValueNode_Composite::create(*iter));
+
+               sinfgapp::Action::Handle action(sinfgapp::Action::create("value_node_dynamic_list_insert"));
+               
+               assert(action);
+               sinfgapp::ValueDesc value_desc(value_node,value_node->link_count());
+               
+               action->set_param("canvas",get_canvas());                       
+               action->set_param("canvas_interface",get_canvas_interface());                   
+               action->set_param("value_desc",value_desc);
+               if(!action->set_param("item",ValueNode::Handle(composite)))
+                       sinfg::error("ACTION didn't like \"item\"");
+               
+               if(!get_canvas_interface()->get_instance()->perform_action(action))
+               {
+                       get_canvas_view()->get_ui_interface()->error(_("Unable to insert item"));
+                       group.cancel();
+                       //refresh_ducks();
+                       return Smach::RESULT_ERROR;
+               }               
+       }
+       last_stroke=value_node;
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StateDraw_Context::reverse_bline(std::list<sinfg::BLinePoint> &bline)
+{
+       int i;
+       
+       std::list<sinfg::BLinePoint>::iterator iter,eiter;
+       iter=bline.begin();
+       eiter=bline.end();
+       eiter--;
+       for(i=0;i<(int)bline.size()/2;++iter,--eiter,i++)
+       {
+               iter_swap(iter,eiter);
+               iter->reverse();
+               eiter->reverse();
+       }
+}
+
+void
+StateDraw_Context::fill_last_stroke()
+{
+       if(!last_stroke)
+               return;
+       
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Fill Stroke"));
+
+       Layer::Handle layer;
+       
+       get_canvas_interface()->auto_export(last_stroke);                       
+
+       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+       
+       layer=get_canvas_interface()->add_layer("region");
+       assert(layer);
+       layer->set_param("color",sinfgapp::Main::get_background_color());
+
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("layer_param_connect"));
+       
+       assert(action);
+       
+       action->set_param("canvas",get_canvas());                       
+       action->set_param("canvas_interface",get_canvas_interface());                   
+       action->set_param("layer",layer);                       
+       if(!action->set_param("param",String("segment_list")))
+               sinfg::error("LayerParamConnect didn't like \"param\"");
+       if(!action->set_param("value_node",ValueNode::Handle(last_stroke)))
+               sinfg::error("LayerParamConnect didn't like \"value_node\"");
+       
+       if(!get_canvas_interface()->get_instance()->perform_action(action))
+       {
+               get_canvas_view()->get_ui_interface()->error(_("Unable to create Region layer"));
+               group.cancel();
+               return;
+       }
+       get_canvas_view()->get_selection_manager()->set_selected_layer(layer);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_draw.h b/synfig-studio/trunk/src/gtkmm/state_draw.h
new file mode 100644 (file)
index 0000000..b84319b
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_roto.h
+**     \brief Template Header
+**
+**     $Id: state_draw.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_ROTOSCOPE_H
+#define __SINFG_STUDIO_STATE_ROTOSCOPE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateDraw_Context;
+
+class StateDraw : public Smach::state<StateDraw_Context>
+{
+public:
+       StateDraw();
+       ~StateDraw();
+}; // END of class StateDraw
+
+extern StateDraw state_draw;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_eyedrop.cpp b/synfig-studio/trunk/src/gtkmm/state_eyedrop.cpp
new file mode 100644 (file)
index 0000000..f6f106a
--- /dev/null
@@ -0,0 +1,140 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_eyedrop.cpp
+**     \brief Template File
+**
+**     $Id: state_eyedrop.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "state_eyedrop.h"
+#include "workarea.h"
+#include <sinfg/context.h>
+#include "app.h"
+#include "dialog_color.h"
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "canvasview.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateEyedrop_Context
+{
+       CanvasView *canvas_view;
+       CanvasView::IsWorking is_working;
+
+public:
+       StateEyedrop_Context(CanvasView *canvas_view);
+       ~StateEyedrop_Context();
+       
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_workarea_mouse_button_down_handler(const Smach::event& x);
+
+}; // END of class StateEyedrop_Context
+
+/* === G L O B A L S ======================================================= */
+
+StateEyedrop studio::state_eyedrop;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+StateEyedrop::StateEyedrop():
+       Smach::state<StateEyedrop_Context>("eyedrop")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateEyedrop_Context::event_stop_handler));
+       insert(event_def(EVENT_STOP,&StateEyedrop_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateEyedrop_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateEyedrop_Context::event_workarea_mouse_button_down_handler));
+}      
+
+StateEyedrop::~StateEyedrop()
+{
+}
+
+StateEyedrop_Context::StateEyedrop_Context(CanvasView *canvas_view):
+       canvas_view(canvas_view),
+       is_working(*canvas_view)
+{
+       sinfg::info("Enterted Eyedrop State");
+       canvas_view->work_area->set_cursor(Gdk::Cursor(Gdk::CROSSHAIR));
+       
+       App::toolbox->refresh();
+}
+
+StateEyedrop_Context::~StateEyedrop_Context()
+{
+       sinfg::info("Left Eyedrop State");
+       canvas_view->work_area->reset_cursor();
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateEyedrop_Context::event_stop_handler(const Smach::event& x)
+{
+       sinfg::info("STATE EYEDROP: Received Stop Event");
+       throw Smach::egress_exception();
+//     canvas_view->get_smach().pop_state();
+//     return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateEyedrop_Context::event_refresh_handler(const Smach::event& x)
+{
+       sinfg::info("STATE EYEDROP: Received Refresh Event");
+       canvas_view->work_area->queue_render_preview();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateEyedrop_Context::event_workarea_mouse_button_down_handler(const Smach::event& x)
+{
+       sinfg::info("STATE EYEDROP: Received mouse button down Event");
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       if(event.button==BUTTON_LEFT)
+       {
+               Color color(canvas_view->get_canvas()->get_context().get_color(event.pos));
+               sinfgapp::Main::set_foreground_color(color);
+               studio::App::dialog_color->set_color(color);
+               return Smach::RESULT_ACCEPT;
+       }
+       return Smach::RESULT_OK;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_eyedrop.h b/synfig-studio/trunk/src/gtkmm/state_eyedrop.h
new file mode 100644 (file)
index 0000000..0ceea46
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_eyedrop.h
+**     \brief Template Header
+**
+**     $Id: state_eyedrop.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STATE_EYEDROP_H
+#define __SINFG_STATE_EYEDROP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio { 
+       
+class StateEyedrop_Context;
+
+class StateEyedrop : public Smach::state<StateEyedrop_Context>
+{
+public:
+       StateEyedrop();
+       ~StateEyedrop();
+}; // END of class StateEyedrop
+
+extern StateEyedrop state_eyedrop;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_fill.cpp b/synfig-studio/trunk/src/gtkmm/state_fill.cpp
new file mode 100644 (file)
index 0000000..07d2aad
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_fill.cpp
+**     \brief Template File
+**
+**     $Id: state_fill.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "state_fill.h"
+#include "workarea.h"
+#include <sinfg/context.h>
+#include "app.h"
+#include "dialog_color.h"
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "canvasview.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateFill_Context
+{
+       CanvasView *canvas_view;
+       CanvasView::IsWorking is_working;
+
+public:
+       StateFill_Context(CanvasView *canvas_view);
+       ~StateFill_Context();
+       
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_workarea_layer_clicked_handler(const Smach::event& x);
+
+
+       etl::handle<CanvasView> get_canvas_view()const{return canvas_view;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view->get_work_area();}
+
+
+}; // END of class StateFill_Context
+
+/* === G L O B A L S ======================================================= */
+
+StateFill studio::state_fill;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+StateFill::StateFill():
+       Smach::state<StateFill_Context>("fill")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateFill_Context::event_stop_handler));
+       insert(event_def(EVENT_STOP,&StateFill_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateFill_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_LAYER_CLICKED,&StateFill_Context::event_workarea_layer_clicked_handler));
+}      
+
+StateFill::~StateFill()
+{
+}
+
+StateFill_Context::StateFill_Context(CanvasView *canvas_view):
+       canvas_view(canvas_view),
+       is_working(*canvas_view)
+{
+       sinfg::info("Enterted Fill State");
+       canvas_view->work_area->set_cursor(Gdk::CROSSHAIR);
+       
+       App::toolbox->refresh();
+}
+
+StateFill_Context::~StateFill_Context()
+{
+       sinfg::info("Left Fill State");
+       canvas_view->work_area->reset_cursor();
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateFill_Context::event_stop_handler(const Smach::event& x)
+{
+       sinfg::info("STATE FILL: Received Stop Event");
+       throw Smach::egress_exception();
+//     canvas_view->get_smach().pop_state();
+//     return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateFill_Context::event_refresh_handler(const Smach::event& x)
+{
+       sinfg::info("STATE FILL: Received Refresh Event");
+       canvas_view->work_area->queue_render_preview();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateFill_Context::event_workarea_layer_clicked_handler(const Smach::event& x)
+{
+       sinfg::info("STATE FILL: Received layer clicked Event");
+       const EventLayerClick& event(*reinterpret_cast<const EventLayerClick*>(&x));
+
+       if(!event.layer)
+       {
+               get_canvas_view()->get_ui_interface()->warning(_("No layer here"));
+               return Smach::RESULT_ACCEPT;
+       }
+
+       
+       //sinfgapp::Action::Handle action(sinfgapp::Action::create("value_desc_set"));
+       sinfgapp::ValueDesc value_desc(event.layer,"color");
+
+       if(!get_canvas_interface()->change_value(value_desc,ValueBase(sinfgapp::Main::get_foreground_color())))
+       {
+               get_canvas_view()->get_ui_interface()->warning(_("Unable to set layer color"));
+               return Smach::RESULT_ERROR;
+       }
+       /*
+       assert(action);
+       
+       action->set_param("canvas",get_canvas());                       
+       action->set_param("canvas_interface",get_canvas_interface());                   
+       action->set_param("value_desc",value_desc);
+       action->set_param("time",get_canvas_interface()->get_time());
+       //action->set_param("layer",event.layer);                       
+       //if(!action->set_param("param",String("color")))
+       //      sinfg::error("LayerParamConnect didn't like \"param\"");
+       if(!action->set_param("new_value",ValueBase(sinfgapp::Main::get_foreground_color())))
+               sinfg::error("LayerParamConnect didn't like \"foreground_color\"");
+       
+       if(!get_canvas_interface()->get_instance()->perform_action(action))
+       {
+               get_canvas_view()->get_ui_interface()->warning(_("Unable to set layer color"));
+               return Smach::RESULT_ERROR;
+       }
+       get_canvas_view()->get_ui_interface()->task(_("Idle"));
+       */
+       return Smach::RESULT_ACCEPT;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_fill.h b/synfig-studio/trunk/src/gtkmm/state_fill.h
new file mode 100644 (file)
index 0000000..8de778d
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_fill.h
+**     \brief Template Header
+**
+**     $Id: state_fill.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STATE_FILL_H
+#define __SINFG_STATE_FILL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio { 
+       
+class StateFill_Context;
+
+class StateFill : public Smach::state<StateFill_Context>
+{
+public:
+       StateFill();
+       ~StateFill();
+}; // END of class StateFill
+
+extern StateFill state_fill;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_gradient.cpp b/synfig-studio/trunk/src/gtkmm/state_gradient.cpp
new file mode 100644 (file)
index 0000000..b34f222
--- /dev/null
@@ -0,0 +1,492 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_gradient.cpp
+**     \brief Template File
+**
+**     $Id: state_gradient.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_gradient.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+
+#include "widget_enum.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+enum
+{
+       GRADIENT_INTERPOLATION_LINEAR=0,
+       GRADIENT_RADIAL=1,
+       GRADIENT_CONICAL=2,
+       GRADIENT_SPIRAL=3
+};
+
+/* === G L O B A L S ======================================================= */
+
+StateGradient studio::state_gradient;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateGradient_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       Duckmatic::Push duckmatic_push;
+       
+       sinfgapp::Settings& settings;
+
+       Point point_holder;
+       
+       etl::handle<Duck> point2_duck;
+
+       void refresh_ducks();
+
+       bool prev_workarea_layer_status_;
+       
+       Gtk::Table options_table;
+       Gtk::Entry entry_id;
+       Widget_Enum enum_type;
+       Widget_Enum     enum_blend;
+       
+public:
+       sinfg::String get_id()const { return entry_id.get_text(); }
+       void set_id(const sinfg::String& x) { return entry_id.set_text(x); }
+
+       int get_type()const { return enum_type.get_value(); }
+       void set_type(int x) { return enum_type.set_value(x); }
+       
+       int get_blend()const { return enum_blend.get_value(); }
+       void set_blend(int x) { return enum_blend.set_value(x); }
+
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+
+       StateGradient_Context(CanvasView* canvas_view);
+
+       ~StateGradient_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //void on_user_click(sinfg::Point point);
+       void load_settings();
+       void save_settings();
+       void reset();
+       void increment_id();
+       
+       void make_gradient(const Point& p1, const Point& p2);
+       bool no_egress_on_selection_change;
+       Smach::event_result event_layer_selection_changed_handler(const Smach::event& x)
+       {
+               if(!no_egress_on_selection_change)
+                       throw Smach::egress_exception();
+               return Smach::RESULT_OK;
+       }
+
+};     // END of class StateGradient_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateGradient::StateGradient():
+       Smach::state<StateGradient_Context>("gradient")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateGradient_Context::event_layer_selection_changed_handler));
+       insert(event_def(EVENT_STOP,&StateGradient_Context::event_stop_handler));
+       insert(event_def(EVENT_TABLES_SHOW,&StateGradient_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateGradient_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateGradient_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateGradient_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateGradient_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateGradient_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateGradient_Context::event_refresh_tool_options));
+}      
+
+StateGradient::~StateGradient()
+{
+}
+
+void
+StateGradient_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("gradient.id",value))
+               set_id(value);
+       else
+               set_id("Gradient");
+       
+       if(settings.get_value("gradient.type",value))
+               set_type(atoi(value.c_str()));
+       else
+               set_type(GRADIENT_INTERPOLATION_LINEAR);
+       
+       if(settings.get_value("gradient.blend",value))
+               set_blend(atoi(value.c_str()));
+       else
+               set_blend(Color::BLEND_COMPOSITE);
+}
+
+void
+StateGradient_Context::save_settings()
+{      
+       settings.set_value("gradient.id",get_id().c_str());
+       settings.set_value("gradient.type",strprintf("%d",get_type()));
+       settings.set_value("gradient.blend",strprintf("%d",get_blend()));
+}
+
+void
+StateGradient_Context::reset()
+{
+       refresh_ducks();
+}
+
+void
+StateGradient_Context::increment_id()
+{
+       String id(get_id());
+       int number=1;
+       int digits=0;
+       
+       if(id.empty())
+               id="Gradient";
+       
+       // If there is a number
+       // already at the end of the
+       // id, then remove it.
+       if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
+       {
+               // figure out how many digits it is
+               for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false);
+               
+               String str_number;
+               str_number=String(id,id.size()-digits,id.size());
+               id=String(id,0,id.size()-digits);
+               
+               number=atoi(str_number.c_str());
+       }
+       else
+       {
+               number=1;
+               digits=3;
+       }
+       
+       number++;
+       
+       // Add the number back onto the id
+       {
+               const String format(strprintf("%%0%dd",digits));
+               id+=strprintf(format.c_str(),number);
+       }
+       
+       // Set the ID
+       set_id(id);
+}
+
+StateGradient_Context::StateGradient_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       duckmatic_push(get_work_area()),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       entry_id()
+{
+       no_egress_on_selection_change=false;
+       // Set up the tool options dialog
+       ///options_table.attach(*manage(new Gtk::Label(_("Gradient Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);   
+       options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       enum_type.set_param_desc(ParamDesc("type")
+               .set_local_name(_("Gradient Type"))
+               .set_description(_("Determines the type of Gradient used"))
+               .set_hint("enum")
+               .add_enum_value(GRADIENT_INTERPOLATION_LINEAR,"linear",_("Linear"))
+               .add_enum_value(GRADIENT_RADIAL,"radial",_("Radial"))
+               .add_enum_value(GRADIENT_CONICAL,"conical",_("Conical"))
+               .add_enum_value(GRADIENT_SPIRAL,"spiral",_("Spiral")));
+       
+       enum_blend.set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method")
+               .set_local_name(_("Blend Method"))
+               .set_description(_("The blend method the gradient will use")));
+       
+       load_settings();
+
+       options_table.attach(enum_type, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(enum_blend, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+       
+       get_work_area()->refresh_cursor();
+       
+       // Hide the tables if they are showing
+       get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateGradient_Context::on_user_click));
+
+       App::toolbox->refresh();
+}
+
+void
+StateGradient_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Gradient Tool"));
+       App::dialog_tool_options->set_name("gradient");
+}
+
+Smach::event_result
+StateGradient_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateGradient_Context::~StateGradient_Context()
+{
+       save_settings();
+
+       // Restore layer clicking
+//     get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+       get_work_area()->allow_layer_clicks=true;
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       //if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       //get_canvas_view()->show_tables();
+
+       get_work_area()->refresh_cursor();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateGradient_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateGradient_Context::event_refresh_handler(const Smach::event& x)
+{
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StateGradient_Context::make_gradient(const Point& _p1, const Point& _p2)
+{
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Gradient"));
+       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+       Layer::Handle layer;
+       
+       Canvas::Handle canvas(get_canvas_view()->get_canvas());
+       int depth(0);
+       
+       // we are temporarily using the layer to hold something
+       layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+       if(layer)
+       {
+               depth=layer->get_depth();
+               canvas=layer->get_canvas();
+       }
+       const sinfg::TransformStack& transform(get_canvas_view()->get_curr_transform_stack());
+       const Point p1(transform.unperform(_p1));
+       const Point p2(transform.unperform(_p2));
+
+       switch(get_type())
+       {
+       case GRADIENT_INTERPOLATION_LINEAR:
+               
+               layer=get_canvas_interface()->add_layer_to("linear_gradient",canvas,depth);
+               layer->set_param("p1",p1);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"p1");
+               layer->set_param("p2",p2);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"p2");
+               break;
+       case GRADIENT_RADIAL:
+               layer=get_canvas_interface()->add_layer_to("radial_gradient",canvas,depth);
+               layer->set_param("center",p1);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"center");
+               layer->set_param("radius",(p2-p1).mag());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
+               break;
+       case GRADIENT_CONICAL:
+               layer=get_canvas_interface()->add_layer_to("conical_gradient",canvas,depth);
+               layer->set_param("center",p1);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"center");
+               {
+                       Vector diff(p2-p1);
+                       layer->set_param("angle",Angle::tan(diff[1],diff[0]));
+                       get_canvas_interface()->signal_layer_param_changed()(layer,"angle");
+               }
+               break;
+       case GRADIENT_SPIRAL:
+               layer=get_canvas_interface()->add_layer_to("spiral_gradient",canvas,depth);
+               layer->set_param("center",p1);
+               get_canvas_interface()->signal_layer_param_changed()(layer,"center");
+               layer->set_param("radius",(p2-p1).mag());
+               get_canvas_interface()->signal_layer_param_changed()(layer,"radius");
+               {
+                       Vector diff(p2-p1);
+                       layer->set_param("angle",Angle::tan(diff[1],diff[0]));
+                       get_canvas_interface()->signal_layer_param_changed()(layer,"angle");
+               }
+               break;
+
+       default:
+               return;
+       }
+       
+       layer->set_param("blend_method",get_blend());
+       get_canvas_interface()->signal_layer_param_changed()(layer,"blend_method");
+       
+       layer->set_description(get_id());
+       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+       
+       no_egress_on_selection_change=true;
+       get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+       get_canvas_interface()->get_selection_manager()->set_selected_layer(layer);
+       no_egress_on_selection_change=false;
+
+       reset();
+       increment_id();
+}
+
+Smach::event_result
+StateGradient_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DOWN && event.button==BUTTON_LEFT)
+       {
+               point_holder=get_work_area()->snap_point_to_grid(event.pos);
+               etl::handle<Duck> duck=new Duck();
+               duck->set_point(point_holder);
+               duck->set_name("p1");
+               duck->set_type(Duck::TYPE_POSITION);
+               get_work_area()->add_duck(duck);
+
+               point2_duck=new Duck();
+               point2_duck->set_point(point_holder);
+               point2_duck->set_name("p2");
+               point2_duck->set_type(Duck::TYPE_POSITION);
+               get_work_area()->add_duck(point2_duck);         
+
+               handle<Duckmatic::Bezier> bezier(new Duckmatic::Bezier());
+               bezier->p1=bezier->c1=duck;
+               bezier->p2=bezier->c2=point2_duck;
+               get_work_area()->add_bezier(bezier);
+
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DRAG && event.button==BUTTON_LEFT)
+       {
+               point2_duck->set_point(get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->queue_draw();                  
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button==BUTTON_LEFT)
+       {
+               make_gradient(point_holder, get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->clear_ducks();
+               return Smach::RESULT_ACCEPT;
+       }
+
+       return Smach::RESULT_OK;
+}
+
+
+void
+StateGradient_Context::refresh_ducks()
+{
+       get_work_area()->clear_ducks();
+       get_work_area()->queue_draw();                  
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_gradient.h b/synfig-studio/trunk/src/gtkmm/state_gradient.h
new file mode 100644 (file)
index 0000000..97abee6
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_gradient.h
+**     \brief Template Header
+**
+**     $Id: state_gradient.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_GRADIENT_H
+#define __SINFG_STUDIO_STATE_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateGradient_Context;
+
+class StateGradient : public Smach::state<StateGradient_Context>
+{
+public:
+       StateGradient();
+       ~StateGradient();
+}; // END of class StateGradient
+
+extern StateGradient state_gradient;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_normal.cpp b/synfig-studio/trunk/src/gtkmm/state_normal.cpp
new file mode 100644 (file)
index 0000000..00d0cdb
--- /dev/null
@@ -0,0 +1,419 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: state_normal.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "state_normal.h"
+#include "workarea.h"
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/dialog.h>
+#include "widget_waypointmodel.h"
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_composite.h>
+#include <sinfg/valuenode_const.h>
+#include "canvasview.h"
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateNormal_Context : public sigc::trackable
+{
+       CanvasView *canvas_view;
+       
+       CanvasView* get_canvas_view() { return canvas_view; }
+       Canvas::Handle get_canvas() { return canvas_view->get_canvas(); }
+       WorkArea* get_work_area() { return canvas_view->get_work_area(); }
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface() { return canvas_view->canvas_interface(); }
+       
+public:
+       StateNormal_Context(CanvasView *canvas_view);
+       ~StateNormal_Context();
+       
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_ducks_handler(const Smach::event& x);
+
+       Smach::event_result event_undo_handler(const Smach::event& x);
+
+       Smach::event_result event_redo_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_button_down_handler(const Smach::event& x);
+
+       Smach::event_result event_multiple_ducks_clicked_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       Smach::event_result event_layer_click(const Smach::event& x);
+
+       void edit_several_waypoints(std::list<sinfgapp::ValueDesc> value_desc_list);
+
+       void refresh_tool_options();
+}; // END of class StateNormal_Context
+
+/* === G L O B A L S ======================================================= */
+
+StateNormal studio::state_normal;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+StateNormal::StateNormal():
+       Smach::state<StateNormal_Context>("normal")
+{
+       insert(event_def(EVENT_STOP,&StateNormal_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateNormal_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateNormal_Context::event_refresh_ducks_handler));
+       insert(event_def(EVENT_UNDO,&StateNormal_Context::event_undo_handler));
+       insert(event_def(EVENT_REDO,&StateNormal_Context::event_redo_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateNormal_Context::event_mouse_button_down_handler));
+       insert(event_def(EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,&StateNormal_Context::event_multiple_ducks_clicked_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateNormal_Context::event_refresh_tool_options)); 
+       insert(event_def(EVENT_WORKAREA_LAYER_CLICKED,&StateNormal_Context::event_layer_click));        
+}      
+
+StateNormal::~StateNormal()
+{
+}
+
+StateNormal_Context::StateNormal_Context(CanvasView *canvas_view):
+       canvas_view(canvas_view)
+{
+       sinfg::info("Enterted Normal State");
+}
+
+StateNormal_Context::~StateNormal_Context()
+{
+       sinfg::info("Left Normal State");
+}
+
+void
+StateNormal_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_name("normal");
+}
+
+Smach::event_result
+StateNormal_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_stop_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received Stop Event");
+       canvas_view->stop();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_refresh_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received Refresh Event");
+       canvas_view->rebuild_tables();
+       canvas_view->work_area->queue_render_preview();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_refresh_ducks_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received Refresh Ducks");
+       canvas_view->queue_rebuild_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_undo_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received Undo Event");
+       canvas_view->get_instance()->undo();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_redo_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received Redo Event");
+       canvas_view->get_instance()->redo();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateNormal_Context::event_mouse_button_down_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received mouse button down Event");
+
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+
+       switch(event.button)
+       {
+       case BUTTON_RIGHT:
+               canvas_view->popup_main_menu();
+               return Smach::RESULT_ACCEPT;
+       default:
+               return Smach::RESULT_OK;
+       }
+}
+
+Smach::event_result
+StateNormal_Context::event_layer_click(const Smach::event& x)
+{
+       const EventLayerClick& event(*reinterpret_cast<const EventLayerClick*>(&x));
+       
+       if(event.layer)
+       {
+               sinfg::info("STATE NORMAL: Received layer click Event, \"%s\"",event.layer->get_name().c_str());
+       }
+       else
+       {
+               sinfg::info("STATE NORMAL: Received layer click Event with an empty layer.");
+       }
+       
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               if(!(event.modifier&Gdk::CONTROL_MASK))
+                       canvas_view->get_selection_manager()->clear_selected_layers();
+               if(event.layer)
+               {
+                       std::list<Layer::Handle> layer_list(canvas_view->get_selection_manager()->get_selected_layers());
+                       std::set<Layer::Handle> layers(layer_list.begin(),layer_list.end());
+                       if(layers.count(event.layer))
+                       {
+                               layers.erase(event.layer);
+                               layer_list=std::list<Layer::Handle>(layers.begin(),layers.end());
+                               canvas_view->get_selection_manager()->clear_selected_layers();
+                               canvas_view->get_selection_manager()->set_selected_layers(layer_list);
+                       }
+                       else
+                       {
+                               canvas_view->get_selection_manager()->set_selected_layer(event.layer);
+                       }
+               }
+               return Smach::RESULT_ACCEPT;
+       case BUTTON_RIGHT:
+               canvas_view->popup_layer_menu(event.layer);
+               return Smach::RESULT_ACCEPT;
+       default:
+               return Smach::RESULT_OK;
+       }
+}
+
+/*
+void
+StateNormal_Context::edit_several_waypoints(std::list<sinfgapp::ValueDesc> value_desc_list)
+{
+       Gtk::Dialog dialog(
+               "Edit Multiple Waypoints",              // Title
+               true,           // Modal
+               true            // use_separator
+       );
+
+       Widget_WaypointModel widget_waypoint_model;
+       widget_waypoint_model.show();
+
+       dialog.get_vbox()->pack_start(widget_waypoint_model);
+       
+       
+       dialog.add_button(Gtk::StockID("gtk-apply"),1);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),0);
+       dialog.show();
+       
+       DEBUGPOINT();
+       if(dialog.run()==0)
+               return;
+       DEBUGPOINT();
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Set Waypoints"));
+
+       std::list<sinfgapp::ValueDesc>::iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               sinfgapp::ValueDesc value_desc(*iter);
+               
+               if(!value_desc.is_valid())
+                       continue;
+
+               ValueNode_Animated::Handle value_node;
+               
+               // If this value isn't a ValueNode_Animated, but
+               // it is somewhat constant, then go ahead and convert
+               // it to a ValueNode_Animated.
+               if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+               {
+                       ValueBase value;
+                       if(value_desc.is_value_node())
+                               value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
+                       else
+                               value=value_desc.get_value();
+                       
+                       value_node=ValueNode_Animated::create(value,get_canvas()->get_time());
+                       
+                       sinfgapp::Action::Handle action;
+                       
+                       if(!value_desc.is_value_node())
+                       {
+                               action=sinfgapp::Action::create("value_desc_connect");
+                               action->set_param("dest",value_desc);
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       else
+                       {
+                               action=sinfgapp::Action::create("value_node_replace");
+                               action->set_param("dest",value_desc.get_value_node());
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       
+       
+                       if(!get_canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               get_canvas_view()->get_ui_interface()->error(_("Unable to convert to animated waypoint"));
+                               group.cancel();
+                               return;
+                       }
+               }
+               else
+               {
+                       if(value_desc.is_value_node())
+                               value_node=ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node());
+               }
+               
+               
+               if(value_node)
+               {
+                       
+                       sinfgapp::Action::Handle action(sinfgapp::Action::create("waypoint_set_smart"));
+
+                       if(!action)
+                       {
+                               get_canvas_view()->get_ui_interface()->error(_("Unable to find waypoint_set_smart action"));
+                               group.cancel();
+                               return;
+                       }
+                               
+
+                       action->set_param("canvas",get_canvas());                       
+                       action->set_param("canvas_interface",get_canvas_interface());                   
+                       action->set_param("value_node",ValueNode::Handle(value_node));                  
+                       action->set_param("time",get_canvas()->get_time());                                             
+                       action->set_param("model",widget_waypoint_model.get_waypoint_model());
+               
+                       if(!get_canvas_interface()->get_instance()->perform_action(action))
+                       {
+                               get_canvas_view()->get_ui_interface()->error(_("Unable to set a specific waypoint"));
+                               group.cancel();
+                               return;
+                       }
+               }
+               else
+               {
+                       //get_canvas_view()->get_ui_interface()->error(_("Unable to animate a specific valuedesc"));
+                       //group.cancel();
+                       //return;
+               }
+                       
+       }
+}
+*/
+
+Smach::event_result
+StateNormal_Context::event_multiple_ducks_clicked_handler(const Smach::event& x)
+{
+       sinfg::info("STATE NORMAL: Received multiple duck click event");
+
+       //const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+
+       std::list<sinfgapp::ValueDesc> value_desc_list;
+       
+       // Create a list of value_descs associated with selection
+       const DuckList selected_ducks(get_work_area()->get_selected_ducks());
+       DuckList::const_iterator iter;
+       for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
+       {
+               sinfgapp::ValueDesc value_desc((*iter)->get_value_desc());
+               
+               if(!value_desc.is_valid())
+                       continue;
+               
+               if(value_desc.get_value_type()==ValueBase::TYPE_BLINEPOINT && value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
+               {
+                       value_desc_list.push_back(
+                               sinfgapp::ValueDesc(
+                                       ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
+                                       ,0
+                               )
+                       );
+               }
+               else
+                       value_desc_list.push_back(value_desc);
+       }
+
+       Gtk::Menu *menu=manage(new Gtk::Menu());
+       
+       canvas_view->get_instance()->make_param_menu(menu,canvas_view->get_canvas(),value_desc_list);
+       
+       /*
+       sinfgapp::Action::ParamList param_list;
+       param_list=get_canvas_interface()->generate_param_list(value_desc_list);
+
+       canvas_view->add_actions_to_menu(menu, param_list,sinfgapp::Action::CATEGORY_VALUEDESC|sinfgapp::Action::CATEGORY_VALUENODE);
+
+       menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Edit Waypoints"),
+               sigc::bind(
+                       sigc::mem_fun(
+                               *this,
+                               &studio::StateNormal_Context::edit_several_waypoints
+                       ),
+                       value_desc_list
+               )
+       ));
+       */
+       menu->popup(3,gtk_get_current_event_time());
+
+       return Smach::RESULT_ACCEPT;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_normal.h b/synfig-studio/trunk/src/gtkmm/state_normal.h
new file mode 100644 (file)
index 0000000..68938e7
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_normal.h
+**     \brief Template Header
+**
+**     $Id: state_normal.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STATE_NORMAL_H
+#define __SINFG_STATE_NORMAL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio { 
+       
+class StateNormal_Context;
+
+class StateNormal : public Smach::state<StateNormal_Context>
+{
+public:
+       StateNormal();
+       ~StateNormal();
+}; // END of class StateNormal
+
+extern StateNormal state_normal;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_polygon.cpp b/synfig-studio/trunk/src/gtkmm/state_polygon.cpp
new file mode 100644 (file)
index 0000000..cd185fc
--- /dev/null
@@ -0,0 +1,479 @@
+/* === S I N F G =========================================================== */
+/*!    \file rotoscope_polygon.cpp
+**     \brief Template File
+**
+**     $Id: state_polygon.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_polygon.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StatePolygon studio::state_polygon;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StatePolygon_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       bool prev_table_status;
+       bool prev_workarea_layer_status_;
+
+       Gtk::Menu menu;
+
+       Duckmatic::Push duckmatic_push;
+       
+       std::list<sinfg::Point> polygon_point_list;
+       sinfgapp::Settings& settings;
+
+       
+       bool on_polygon_duck_change(const sinfg::Point &point, std::list<sinfg::Point>::iterator iter);
+
+
+       void popup_handle_menu(sinfgapp::ValueDesc value_desc);
+
+
+       void refresh_ducks();
+       
+       Gtk::Table options_table;
+       Gtk::Entry entry_id;
+       Gtk::Button button_make;
+
+public:
+       sinfg::String get_id()const { return entry_id.get_text(); }
+       void set_id(const sinfg::String& x) { return entry_id.set_text(x); }
+
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+       void refresh_tool_options();
+
+       StatePolygon_Context(CanvasView* canvas_view);
+
+       ~StatePolygon_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //void on_user_click(sinfg::Point point);
+       void load_settings();
+       void save_settings();
+       void reset();
+       void increment_id();
+       bool no_egress_on_selection_change;
+       Smach::event_result event_layer_selection_changed_handler(const Smach::event& x)
+       {
+               if(!no_egress_on_selection_change)
+                       throw Smach::egress_exception();
+               return Smach::RESULT_OK;
+       }
+
+       void run();
+};     // END of class StatePolygon_Context
+
+/* === M E T H O D S ======================================================= */
+
+StatePolygon::StatePolygon():
+       Smach::state<StatePolygon_Context>("polygon")
+{
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StatePolygon_Context::event_layer_selection_changed_handler));
+       insert(event_def(EVENT_STOP,&StatePolygon_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StatePolygon_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StatePolygon_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StatePolygon_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StatePolygon_Context::event_refresh_tool_options));
+}      
+
+StatePolygon::~StatePolygon()
+{
+}
+
+void
+StatePolygon_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("polygon.id",value))
+               set_id(value);
+       else
+               set_id("Polygon");
+}
+
+void
+StatePolygon_Context::save_settings()
+{      
+       settings.set_value("polygon.id",get_id().c_str());
+}
+
+void
+StatePolygon_Context::reset()
+{
+       polygon_point_list.clear();
+       refresh_ducks();
+}
+
+void
+StatePolygon_Context::increment_id()
+{
+       String id(get_id());
+       int number=1;
+       int digits=0;
+       
+       if(id.empty())
+               id="Polygon";
+       
+       // If there is a number
+       // already at the end of the
+       // id, then remove it.
+       if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
+       {
+               // figure out how many digits it is
+               for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false);
+               
+               String str_number;
+               str_number=String(id,id.size()-digits,id.size());
+               id=String(id,0,id.size()-digits);
+               
+               number=atoi(str_number.c_str());
+       }
+       else
+       {
+               number=1;
+               digits=3;
+       }
+       
+       number++;
+       
+       // Add the number back onto the id
+       {
+               const String format(strprintf("%%0%dd",digits));
+               id+=strprintf(format.c_str(),number);
+       }
+       
+       // Set the ID
+       set_id(id);
+}
+
+StatePolygon_Context::StatePolygon_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       duckmatic_push(get_work_area()),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       entry_id(),
+       button_make(_("Make"))
+{
+       no_egress_on_selection_change=false;
+       load_settings();
+       
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Polygon Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+       options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //options_table.attach(button_make, 0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       button_make.signal_pressed().connect(sigc::mem_fun(*this,&StatePolygon_Context::run));
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       
+       // Hide the tables if they are showing
+       prev_table_status=get_canvas_view()->tables_are_visible();
+       if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StatePolygon_Context::on_user_click));
+
+       App::toolbox->refresh();
+}
+
+void
+StatePolygon_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+
+       App::dialog_tool_options->set_local_name(_("Polygon Tool"));
+       App::dialog_tool_options->set_name("polygon");
+
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-execute"),
+               _("Make Polygon")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &StatePolygon_Context::run
+               )
+       );
+
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-clear"),
+               _("Clear current Polygon")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &StatePolygon_Context::reset
+               )
+       );
+}
+
+Smach::event_result
+StatePolygon_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StatePolygon_Context::~StatePolygon_Context()
+{
+       run();
+
+       save_settings();
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+
+       App::dialog_tool_options->clear();
+
+       get_canvas_view()->work_area->reset_cursor();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StatePolygon_Context::event_stop_handler(const Smach::event& x)
+{
+       sinfg::info("STATE RotoPolygon: Received Stop Event");
+       //throw Smach::egress_exception();
+       reset();
+       return Smach::RESULT_ACCEPT;
+       
+}
+
+Smach::event_result
+StatePolygon_Context::event_refresh_handler(const Smach::event& x)
+{
+       sinfg::info("STATE RotoPolygon: Received Refresh Event");
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StatePolygon_Context::run()
+{
+       if(polygon_point_list.empty())
+               return;
+       
+       if(polygon_point_list.size()<3)
+       {
+               get_canvas_view()->get_ui_interface()->error("You need at least 3 points to create a polygon");
+               return;
+       }
+               Layer::Handle layer;
+               Canvas::Handle canvas(get_canvas_view()->get_canvas());
+               int depth(0);
+               
+               // we are temporarily using the layer to hold something
+               layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+               if(layer)
+               {
+                       depth=layer->get_depth();
+                       canvas=layer->get_canvas();
+               }
+
+               {
+                       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Polygon"));
+                       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+       
+                       Layer::Handle layer(get_canvas_interface()->add_layer_to("polygon",canvas,depth));
+                       layer->set_description(get_id());
+                       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+                       
+                       layer->disconnect_dynamic_param("vector_list");
+                       if(!layer->set_param("vector_list",polygon_point_list))
+                       {
+                               group.cancel();
+                               get_canvas_view()->get_ui_interface()->error("Unable to set layer parameter");
+                               return;
+                       }
+                       
+                       {
+                               sinfgapp::Action::Handle action(sinfgapp::Action::create("value_desc_convert"));
+                               sinfgapp::ValueDesc value_desc(layer,"vector_list");
+                               action->set_param("canvas",get_canvas());                       
+                               action->set_param("canvas_interface",get_canvas_interface());                   
+                               action->set_param("value_desc",value_desc);                     
+                               action->set_param("type","dynamic_list");
+                               if(!get_canvas_interface()->get_instance()->perform_action(action))
+                               {
+                                       group.cancel();
+                                       get_canvas_view()->get_ui_interface()->error("Unable to execute action \"value_desc_convert\"");
+                                       return;
+                               }
+                       }                       
+                       no_egress_on_selection_change=true;
+                       get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+                       get_canvas_interface()->get_selection_manager()->set_selected_layer(layer);
+                       no_egress_on_selection_change=false;
+                       //get_canvas_interface()->signal_dirty_preview()();
+               }
+/*
+               else
+               {
+                       ValueNode::Handle value_node=(ValueNode_Const::create(polygon_point_list));
+                       std::string valuenode_name="Poly";
+                       while(studio::App::dialog_entry("New Polygon", "Please enter the new ID for this value_node",valuenode_name))
+                               if(get_canvas_interface()->add_value_node(value_node,valuenode_name))
+                                       return true;
+               }
+*/
+       reset();
+       increment_id();
+}
+
+Smach::event_result
+StatePolygon_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       sinfg::info("STATE ROTOPOLYGON: Received mouse button down Event");
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               polygon_point_list.push_back(get_work_area()->snap_point_to_grid(event.pos));
+               refresh_ducks();
+               return Smach::RESULT_ACCEPT;
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
+
+
+void
+StatePolygon_Context::refresh_ducks()
+{
+       get_work_area()->clear_ducks();
+       
+       if(polygon_point_list.empty()) return;
+
+       std::list<sinfg::Point>::iterator iter=polygon_point_list.begin();
+       
+       etl::handle<WorkArea::Duck> duck;
+       duck=new WorkArea::Duck(*iter);
+       duck->set_editable(true);
+       duck->signal_edited().connect(
+               sigc::bind(sigc::mem_fun(*this,&studio::StatePolygon_Context::on_polygon_duck_change),iter)
+       );
+       duck->signal_user_click(0).connect(sigc::mem_fun(*this,&StatePolygon_Context::run));
+       
+       get_work_area()->add_duck(duck);
+
+       for(++iter;iter!=polygon_point_list.end();++iter)
+       {
+               etl::handle<WorkArea::Bezier> bezier(new WorkArea::Bezier());
+               bezier->p1=bezier->c1=duck;
+
+               duck=new WorkArea::Duck(*iter);
+               duck->set_editable(true);
+               duck->set_name(strprintf("%x",&*iter));
+               duck->signal_edited().connect(
+                       sigc::bind(sigc::mem_fun(*this,&studio::StatePolygon_Context::on_polygon_duck_change),iter)
+               );              
+
+               get_work_area()->add_duck(duck);                        
+
+               bezier->p2=bezier->c2=duck;
+               get_work_area()->add_bezier(bezier);                    
+       }
+       get_work_area()->queue_draw();                  
+}
+
+
+bool
+StatePolygon_Context::on_polygon_duck_change(const sinfg::Point &point, std::list<sinfg::Point>::iterator iter)
+{
+       *iter=point;
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_polygon.h b/synfig-studio/trunk/src/gtkmm/state_polygon.h
new file mode 100644 (file)
index 0000000..7879ec2
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file rotoscope_polygon.h
+**     \brief Template Header
+**
+**     $Id: state_polygon.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_ROTOSCOPE_POLYGON_H
+#define __SINFG_STUDIO_ROTOSCOPE_POLYGON_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StatePolygon_Context;
+
+class StatePolygon : public Smach::state<StatePolygon_Context>
+{
+public:
+       StatePolygon();
+       ~StatePolygon();
+}; // END of class StatePolygon
+
+extern StatePolygon state_polygon;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_rectangle.cpp b/synfig-studio/trunk/src/gtkmm/state_rectangle.cpp
new file mode 100644 (file)
index 0000000..297b477
--- /dev/null
@@ -0,0 +1,446 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_gradient.cpp
+**     \brief Template File
+**
+**     $Id: state_rectangle.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_rectangle.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateRectangle studio::state_rectangle;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateRectangle_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       Duckmatic::Push duckmatic_push;
+       
+       Point point_holder;
+       
+       etl::handle<Duck> point2_duck;
+
+       void refresh_ducks();
+       
+       bool prev_workarea_layer_status_;
+               
+       //Toolbox settings
+       sinfgapp::Settings& settings;
+       
+       //Toolbox display
+       Gtk::Table options_table;
+       
+       Gtk::Entry              entry_id; //what to name the layer
+               
+       Gtk::Adjustment adj_expand;
+       Gtk::SpinButton spin_expand;
+       
+       Gtk::CheckButton check_invert;
+       
+public:
+
+       sinfg::String get_id()const { return entry_id.get_text(); }
+       void set_id(const sinfg::String& x) { return entry_id.set_text(x); }
+
+       Real get_expand()const { return adj_expand.get_value(); }
+       void set_expand(Real f) { adj_expand.set_value(f); }
+       
+       bool get_invert()const { return check_invert.get_active(); }
+       void set_invert(bool i) { check_invert.set_active(i); }
+       
+       void refresh_tool_options(); //to refresh the toolbox   
+
+       //events
+       Smach::event_result event_stop_handler(const Smach::event& x);
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       //constructor destructor
+       StateRectangle_Context(CanvasView* canvas_view);
+       ~StateRectangle_Context();
+
+       //Canvas interaction
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //Modifying settings etc.
+       void load_settings();
+       void save_settings();
+       void reset();
+       void increment_id();
+       bool no_egress_on_selection_change;
+       Smach::event_result event_layer_selection_changed_handler(const Smach::event& x)
+       {
+               if(!no_egress_on_selection_change)
+                       throw Smach::egress_exception();
+               return Smach::RESULT_OK;
+       }
+
+       void make_rectangle(const Point& p1, const Point& p2);
+       
+};     // END of class StateGradient_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateRectangle::StateRectangle():
+       Smach::state<StateRectangle_Context>("rectangle")
+{
+       insert(event_def(EVENT_STOP,&StateRectangle_Context::event_stop_handler));
+       insert(event_def(EVENT_LAYER_SELECTION_CHANGED,&StateRectangle_Context::event_layer_selection_changed_handler));
+       insert(event_def(EVENT_REFRESH,&StateRectangle_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateRectangle_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateRectangle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateRectangle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateRectangle_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateRectangle_Context::event_refresh_tool_options));
+}
+
+StateRectangle::~StateRectangle()
+{
+}
+
+void
+StateRectangle_Context::load_settings()
+{      
+       String value;
+       
+       //parse the arguments yargh!
+       if(settings.get_value("rectangle.id",value))
+               set_id(value);
+       else
+               set_id("Rectangle");
+
+       if(settings.get_value("rectangle.expand",value))
+               set_expand(atof(value.c_str()));
+       else
+               set_expand(0);
+       
+       if(settings.get_value("rectangle.invert",value) && value != "0")
+               set_invert(true);
+       else
+               set_invert(false);
+}
+
+void
+StateRectangle_Context::save_settings()
+{      
+       settings.set_value("rectangle.id",get_id().c_str());
+       settings.set_value("rectangle.expand",strprintf("%f",get_expand()));
+       settings.set_value("rectangle.invert",get_invert()?"1":"0");
+}
+
+void
+StateRectangle_Context::reset()
+{
+       refresh_ducks();
+}
+
+void
+StateRectangle_Context::increment_id()
+{
+       String id(get_id());
+       int number=1;
+       int digits=0;
+       
+       if(id.empty())
+               id="Circle";
+       
+       // If there is a number
+       // already at the end of the
+       // id, then remove it.
+       if(id[id.size()-1]<='9' && id[id.size()-1]>='0')
+       {
+               // figure out how many digits it is
+               for(digits=0;(int)id.size()-1>=digits && id[id.size()-1-digits]<='9' && id[id.size()-1-digits]>='0';digits++)while(false);
+               
+               String str_number;
+               str_number=String(id,id.size()-digits,id.size());
+               id=String(id,0,id.size()-digits);
+               
+               number=atoi(str_number.c_str());
+       }
+       else
+       {
+               number=1;
+               digits=3;
+       }
+       
+       number++;
+       
+       // Add the number back onto the id
+       {
+               const String format(strprintf("%%0%dd",digits));
+               id+=strprintf(format.c_str(),number);
+       }
+       
+       // Set the ID
+       set_id(id);
+}
+
+StateRectangle_Context::StateRectangle_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       duckmatic_push(get_work_area()),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       entry_id(),
+       adj_expand(0,0,1,0.01,0.1),
+       spin_expand(adj_expand,0.1,3),
+       check_invert(_("Invert"))
+{
+       no_egress_on_selection_change=false;
+       load_settings();
+       
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Circle Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);      
+       options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       //expand stuff
+       options_table.attach(*manage(new Gtk::Label(_("Expansion:"))), 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(spin_expand, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+               
+       //invert flag
+       options_table.attach(check_invert, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       options_table.show_all();
+       
+       //App::dialog_tool_options->set_widget(options_table);
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+
+       // Hide the tables if they are showing
+       //prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateRectangle_Context::on_user_click));
+
+       App::toolbox->refresh();
+}
+
+void
+StateRectangle_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Rectangle Tool"));
+       App::dialog_tool_options->set_name("rectangle");
+}
+
+Smach::event_result
+StateRectangle_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateRectangle_Context::~StateRectangle_Context()
+{
+       save_settings();
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks = prev_workarea_layer_status_;
+
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       //if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateRectangle_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateRectangle_Context::event_refresh_handler(const Smach::event& x)
+{
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+void
+StateRectangle_Context::make_rectangle(const Point& _p1, const Point& _p2)
+{
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("New Rectangle"));
+       sinfgapp::PushMode push_mode(get_canvas_interface(),sinfgapp::MODE_NORMAL);
+
+       Layer::Handle layer;
+       
+       Canvas::Handle canvas(get_canvas_view()->get_canvas());
+       int depth(0);
+       
+       // we are temporarily using the layer to hold something
+       layer=get_canvas_view()->get_selection_manager()->get_selected_layer();
+       if(layer)
+       {
+               depth=layer->get_depth();
+               canvas=layer->get_canvas();
+       }
+
+       //create the layer
+       layer=get_canvas_interface()->add_layer_to("rectangle",canvas,depth);
+
+       const sinfg::TransformStack& transform(get_canvas_view()->get_curr_transform_stack());
+       const Point p1(transform.unperform(_p1));
+       const Point p2(transform.unperform(_p2));
+       
+       //set all the parameters
+       layer->set_param("point1",p1);
+       get_canvas_interface()->signal_layer_param_changed()(layer,"point1");
+       layer->set_param("point2",p2);
+       get_canvas_interface()->signal_layer_param_changed()(layer,"point2");
+       
+       layer->set_param("expand",get_expand());
+       get_canvas_interface()->signal_layer_param_changed()(layer,"expand");
+
+       layer->set_param("invert",get_invert());
+       get_canvas_interface()->signal_layer_param_changed()(layer,"invert");
+       
+       //name
+       layer->set_description(get_id());
+       get_canvas_interface()->signal_layer_new_description()(layer,layer->get_description());
+
+       no_egress_on_selection_change=true;
+       get_canvas_interface()->get_selection_manager()->clear_selected_layers();
+       get_canvas_interface()->get_selection_manager()->set_selected_layer(layer);
+       no_egress_on_selection_change=false;
+
+       //post clean up stuff...
+       reset();
+       increment_id();
+}
+
+Smach::event_result
+StateRectangle_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DOWN && event.button==BUTTON_LEFT)
+       {
+               point_holder=get_work_area()->snap_point_to_grid(event.pos);
+               etl::handle<Duck> duck=new Duck();
+               duck->set_point(point_holder);
+               duck->set_name("p1");
+               duck->set_type(Duck::TYPE_POSITION);
+               get_work_area()->add_duck(duck);
+
+               point2_duck=new Duck();
+               point2_duck->set_point(point_holder);
+               point2_duck->set_name("p2");
+               point2_duck->set_type(Duck::TYPE_POSITION);
+               point2_duck->set_box_duck(duck);
+               get_work_area()->add_duck(point2_duck);
+
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_DRAG && event.button==BUTTON_LEFT)
+       {
+               point2_duck->set_point(get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->queue_draw();                  
+               return Smach::RESULT_ACCEPT;
+       }
+
+       if(event.key==EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button==BUTTON_LEFT)
+       {
+               make_rectangle(point_holder, get_work_area()->snap_point_to_grid(event.pos));
+               get_work_area()->clear_ducks();
+               return Smach::RESULT_ACCEPT;
+       }
+
+       return Smach::RESULT_OK;
+}
+
+
+void
+StateRectangle_Context::refresh_ducks()
+{
+       get_work_area()->clear_ducks();
+       get_work_area()->queue_draw();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_rectangle.h b/synfig-studio/trunk/src/gtkmm/state_rectangle.h
new file mode 100644 (file)
index 0000000..96ec24d
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_rectangle.h
+**     \brief Rectangle creation state
+**
+**     $Id: state_rectangle.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_RECTANGLE_H
+#define __SINFG_STUDIO_STATE_RECTANGLE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateRectangle_Context;
+
+class StateRectangle : public Smach::state<StateRectangle_Context>
+{
+public:
+       StateRectangle();
+       ~StateRectangle();
+}; // END of class StateRectangle
+
+extern StateRectangle state_rectangle;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_rotate.cpp b/synfig-studio/trunk/src/gtkmm/state_rotate.cpp
new file mode 100644 (file)
index 0000000..6761482
--- /dev/null
@@ -0,0 +1,383 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_rotate.cpp
+**     \brief Template File
+**
+**     $Id: state_rotate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_rotate.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+#include <sinfg/angle.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#ifndef EPSILON
+#define EPSILON        0.0000001
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+StateRotate studio::state_rotate;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class DuckDrag_Rotate : public DuckDrag_Base
+{
+
+       sinfg::Vector last_rotate;
+       sinfg::Vector drag_offset;
+       sinfg::Vector center;
+       sinfg::Vector snap;
+
+       Angle original_angle;
+       Real original_mag;
+
+       std::vector<sinfg::Vector> positions;
+       
+       
+       bool bad_drag;
+       bool move_only;
+       
+public:
+       etl::handle<CanvasView> canvas_view_;
+       bool use_magnitude;
+       DuckDrag_Rotate();
+       void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin);
+       bool end_duck_drag(Duckmatic* duckmatic);
+       void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector);
+
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+};
+
+
+class studio::StateRotate_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+               
+       sinfgapp::Settings& settings;
+
+       etl::handle<DuckDrag_Rotate> duck_dragger_;
+
+       Gtk::Table options_table;
+       
+       Gtk::CheckButton checkbutton_scale;
+       
+public:
+
+       bool get_scale_flag()const { return checkbutton_scale.get_active(); }
+       void set_scale_flag(bool x) { return checkbutton_scale.set_active(x); refresh_scale_flag(); }
+       
+
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+
+       void refresh_scale_flag() { if(duck_dragger_)duck_dragger_->use_magnitude=get_scale_flag(); }
+
+       StateRotate_Context(CanvasView* canvas_view);
+
+       ~StateRotate_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       void load_settings();
+       void save_settings();
+};     // END of class StateRotate_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateRotate::StateRotate():
+       Smach::state<StateRotate_Context>("rotate")
+{
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateRotate_Context::event_refresh_tool_options));
+}      
+
+StateRotate::~StateRotate()
+{
+}
+
+void
+StateRotate_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("rotate.scale",value) && value=="0")
+               set_scale_flag(false);
+       else
+               set_scale_flag(true);
+}
+
+void
+StateRotate_Context::save_settings()
+{      
+       settings.set_value("rotate.scale",get_scale_flag()?"1":"0");
+}
+
+StateRotate_Context::StateRotate_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       duck_dragger_(new DuckDrag_Rotate()),
+       checkbutton_scale(_("Allow Scale"))
+{      
+       duck_dragger_->canvas_view_=get_canvas_view();
+       
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Rotate Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);      
+       options_table.attach(checkbutton_scale, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       checkbutton_scale.signal_toggled().connect(sigc::mem_fun(*this,&StateRotate_Context::refresh_scale_flag));
+       
+       options_table.show_all();
+       refresh_tool_options();
+       //App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->present();
+       
+       get_work_area()->allow_layer_clicks=true;
+       get_work_area()->set_duck_dragger(duck_dragger_);
+
+//     get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::toolbox->refresh();
+
+       load_settings();
+       refresh_scale_flag();
+}
+
+void
+StateRotate_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Rotate Tool"));
+       App::dialog_tool_options->set_name("rotate");
+}
+
+Smach::event_result
+StateRotate_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateRotate_Context::~StateRotate_Context()
+{
+       save_settings();
+
+       get_work_area()->clear_duck_dragger();
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       App::toolbox->refresh();
+}
+
+
+
+
+DuckDrag_Rotate::DuckDrag_Rotate()
+{
+       use_magnitude=true;
+}
+
+void
+DuckDrag_Rotate::begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& offset)
+{
+       last_rotate=Vector(1,1);
+
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+       
+/*
+       if(duckmatic->get_selected_ducks().size()<2)
+       {
+               bad_drag=true;
+               return;
+       }
+*/
+       bad_drag=false;
+       
+               drag_offset=duckmatic->find_duck(offset)->get_trans_point();
+
+               //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset);
+               //snap=offset-drag_offset;
+               snap=Vector(0,0);
+
+       // Calculate center
+       Point vmin(100000000,100000000);
+       Point vmax(-100000000,-100000000);
+       //std::set<etl::handle<Duck> >::iterator iter;
+       positions.clear();
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               Point p((*iter)->get_trans_point());
+               vmin[0]=min(vmin[0],p[0]);
+               vmin[1]=min(vmin[1],p[1]);
+               vmax[0]=max(vmax[0],p[0]);
+               vmax[1]=max(vmax[1],p[1]);
+               positions.push_back(p);
+       }
+       center=(vmin+vmax)*0.5;
+       if((vmin-vmax).mag()<=EPSILON)
+               move_only=true;
+       else
+               move_only=false;
+
+       
+       sinfg::Vector vect(offset-center);
+       original_angle=Angle::tan(vect[1],vect[0]);
+       original_mag=vect.mag();
+}
+
+
+void
+DuckDrag_Rotate::duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)
+{
+       if(bad_drag)
+               return;
+       
+       //std::set<etl::handle<Duck> >::iterator iter;
+       sinfg::Vector vect(duckmatic->snap_point_to_grid(vector)-center+snap);
+
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       if(move_only)
+       {
+               int i;
+               for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+               {
+                       if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue;
+                       
+                       Vector p(positions[i]);
+       
+                       p[0]+=vect[0];
+                       p[1]+=vect[1];
+                       (*iter)->set_trans_point(p);
+               }
+               for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+               {
+                       if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+                       
+                       Vector p(positions[i]);
+       
+                       p[0]+=vect[0];
+                       p[1]+=vect[1];
+                       (*iter)->set_trans_point(p);
+               }
+               return;
+       }
+       
+       Angle::tan angle(vect[1],vect[0]);
+       angle=original_angle-angle;
+       Real mag(vect.mag()/original_mag);
+       Real sine(Angle::sin(angle).get());
+       Real cosine(Angle::cos(angle).get());
+       
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue;
+               
+               Vector x(positions[i]-center),p;
+
+               p[0]=cosine*x[0]+sine*x[1];
+               p[1]=-sine*x[0]+cosine*x[1];
+               if(use_magnitude)p*=mag;
+               p+=center;
+               (*iter)->set_trans_point(p);
+       }
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+               
+               Vector x(positions[i]-center),p;
+
+               p[0]=cosine*x[0]+sine*x[1];
+               p[1]=-sine*x[0]+cosine*x[1];
+               if(use_magnitude)p*=mag;
+               p+=center;
+               (*iter)->set_trans_point(p);
+       }
+       
+       last_rotate=vect;
+       //snap=Vector(0,0);
+}
+
+bool
+DuckDrag_Rotate::end_duck_drag(Duckmatic* duckmatic)
+{
+       if(bad_drag)return false;
+       if(move_only)
+       {
+               sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Move Duck"));
+               duckmatic->signal_edited_selected_ducks();
+               return true;
+       }
+       
+       sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Rotate Ducks"));
+               
+       if((last_rotate-Vector(1,1)).mag()>0.0001)
+       {
+               duckmatic->signal_edited_selected_ducks();
+               return true;
+       }
+       else
+       {
+               duckmatic->signal_user_click_selected_ducks(0);
+               return false;
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_rotate.h b/synfig-studio/trunk/src/gtkmm/state_rotate.h
new file mode 100644 (file)
index 0000000..8bce187
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_rotate.h
+**     \brief Template Header
+**
+**     $Id: state_rotate.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_ROTATE_H
+#define __SINFG_STUDIO_STATE_ROTATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateRotate_Context;
+
+class StateRotate : public Smach::state<StateRotate_Context>
+{
+public:
+       StateRotate();
+       ~StateRotate();
+}; // END of class StateRotate
+
+extern StateRotate state_rotate;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_scale.cpp b/synfig-studio/trunk/src/gtkmm/state_scale.cpp
new file mode 100644 (file)
index 0000000..94525b3
--- /dev/null
@@ -0,0 +1,373 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_scale.cpp
+**     \brief Template File
+**
+**     $Id: state_scale.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_scale.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateScale studio::state_scale;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class DuckDrag_Scale : public DuckDrag_Base
+{
+
+       sinfg::Vector last_scale;
+       sinfg::Vector drag_offset;
+       sinfg::Vector center;
+       sinfg::Vector snap;
+
+       std::vector<sinfg::Vector> positions;
+
+       bool move_only;
+       
+       bool bad_drag;
+public:
+       bool lock_aspect;
+       DuckDrag_Scale();
+       void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin);
+       bool end_duck_drag(Duckmatic* duckmatic);
+       void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector);
+};
+
+
+class studio::StateScale_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+               
+       sinfgapp::Settings& settings;
+
+       etl::handle<DuckDrag_Scale> duck_dragger_;
+
+       Gtk::Table options_table;
+       
+       
+       Gtk::CheckButton checkbutton_aspect_lock;
+       
+public:
+
+       bool get_aspect_lock_flag()const { return checkbutton_aspect_lock.get_active(); }
+       void set_aspect_lock_flag(bool x) { return checkbutton_aspect_lock.set_active(x); refresh_aspect_lock_flag(); }
+
+       void refresh_aspect_lock_flag() { if(duck_dragger_)duck_dragger_->lock_aspect=get_aspect_lock_flag(); }
+
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+
+       StateScale_Context(CanvasView* canvas_view);
+
+       ~StateScale_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       void load_settings();
+       void save_settings();
+};     // END of class StateScale_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateScale::StateScale():
+       Smach::state<StateScale_Context>("scale")
+{
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateScale_Context::event_refresh_tool_options));
+}      
+
+StateScale::~StateScale()
+{
+}
+
+void
+StateScale_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("scale.lock_aspect",value) && value=="0")
+               set_aspect_lock_flag(false);
+       else
+               set_aspect_lock_flag(true);
+}
+
+void
+StateScale_Context::save_settings()
+{      
+       settings.set_value("scale.lock_aspect",get_aspect_lock_flag()?"1":"0");
+}
+
+StateScale_Context::StateScale_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       duck_dragger_(new DuckDrag_Scale()),
+       checkbutton_aspect_lock(_("Lock Aspect Ratio"))
+{      
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Scale Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);       
+       options_table.attach(checkbutton_aspect_lock, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       checkbutton_aspect_lock.signal_toggled().connect(sigc::mem_fun(*this,&StateScale_Context::refresh_aspect_lock_flag));
+               
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+       
+       get_work_area()->allow_layer_clicks=true;
+       get_work_area()->set_duck_dragger(duck_dragger_);
+
+//     get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::toolbox->refresh();
+
+       set_aspect_lock_flag(true);
+       load_settings();
+}
+
+void
+StateScale_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Scale Tool"));
+       App::dialog_tool_options->set_name("scale");
+}
+
+Smach::event_result
+StateScale_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateScale_Context::~StateScale_Context()
+{
+       save_settings();
+
+       get_work_area()->clear_duck_dragger();
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       App::toolbox->refresh();
+}
+
+
+
+
+DuckDrag_Scale::DuckDrag_Scale():
+       lock_aspect(true)
+{
+}
+
+#ifndef EPSILON
+#define EPSILON        0.0000001
+#endif
+
+void
+DuckDrag_Scale::begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& offset)
+{
+       last_scale=Vector(1,1);
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+       
+       //if(duckmatic->get_selected_ducks().size()<2)
+       //{
+       //      bad_drag=true;
+//             return;
+//     }
+       bad_drag=false;
+       
+               drag_offset=duckmatic->find_duck(offset)->get_trans_point();
+
+               //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset);
+               //snap=offset-drag_offset;
+               snap=Vector(0,0);
+
+       // Calculate center
+       Point vmin(100000000,100000000);
+       Point vmax(-100000000,-100000000);
+       //std::set<etl::handle<Duck> >::iterator iter;
+       positions.clear();
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               Point p((*iter)->get_trans_point());
+               vmin[0]=min(vmin[0],p[0]);
+               vmin[1]=min(vmin[1],p[1]);
+               vmax[0]=max(vmax[0],p[0]);
+               vmax[1]=max(vmax[1],p[1]);
+               positions.push_back(p);
+       }
+       if((vmin-vmax).mag()<=EPSILON)
+               move_only=true;
+       else
+               move_only=false;
+       
+       center=(vmin+vmax)*0.5;
+}
+
+
+void
+DuckDrag_Scale::duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)
+{
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+
+       if(bad_drag)
+               return;
+       
+       //std::set<etl::handle<Duck> >::iterator iter;
+       sinfg::Vector vect(duckmatic->snap_point_to_grid(vector)-center);
+       last_scale=vect;
+
+       if(move_only)
+       {
+               int i;
+               for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+               {
+                       if(((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+                       
+                       Vector p(positions[i]);
+       
+                       p[0]+=vect[0];
+                       p[1]+=vect[1];
+                       (*iter)->set_trans_point(p);
+               }
+               for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+               {
+                       if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+                       
+                       Vector p(positions[i]);
+       
+                       p[0]+=vect[0];
+                       p[1]+=vect[1];
+                       (*iter)->set_trans_point(p);
+               }
+               return;
+       }
+               
+       if(!lock_aspect)
+       {
+               if(abs(drag_offset[0]-center[0])>EPSILON)
+                       vect[0]/=drag_offset[0]-center[0];
+               else
+                       vect[0]=1;
+               if(abs(drag_offset[1]-center[1])>EPSILON)
+                       vect[1]/=drag_offset[1]-center[1];
+               else
+                       vect[1]=1;
+               }
+       else
+       {
+               //vect[0]=vect[1]=vect.mag()*0.707106781;
+               Real amount(vect.mag()/(drag_offset-center).mag());
+               vect[0]=vect[1]=amount;
+       }
+
+       if(vect[0]<EPSILON && vect[0]>-EPSILON)
+               vect[0]=1;
+       if(vect[1]<EPSILON && vect[1]>-EPSILON)
+               vect[1]=1;
+       
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+               
+               Vector p(positions[i]-center);
+
+               p[0]*=vect[0];
+               p[1]*=vect[1];
+               p+=center;
+               (*iter)->set_trans_point(p);
+       }
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+               
+               Vector p(positions[i]-center);
+
+               p[0]*=vect[0];
+               p[1]*=vect[1];
+               p+=center;
+               (*iter)->set_trans_point(p);
+       }
+       
+       last_scale=vect;
+       //snap=Vector(0,0);
+}
+
+bool
+DuckDrag_Scale::end_duck_drag(Duckmatic* duckmatic)
+{
+       if(bad_drag)return false;
+               
+       if((last_scale-Vector(1,1)).mag()>0.0001)
+       {
+               duckmatic->signal_edited_selected_ducks();
+               return true;
+       }
+       else
+       {
+               duckmatic->signal_user_click_selected_ducks(0);
+               return false;
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_scale.h b/synfig-studio/trunk/src/gtkmm/state_scale.h
new file mode 100644 (file)
index 0000000..bc715b0
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_scale.h
+**     \brief Template Header
+**
+**     $Id: state_scale.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_SCALE_H
+#define __SINFG_STUDIO_STATE_SCALE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateScale_Context;
+
+class StateScale : public Smach::state<StateScale_Context>
+{
+public:
+       StateScale();
+       ~StateScale();
+}; // END of class StateScale
+
+extern StateScale state_scale;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_sketch.cpp b/synfig-studio/trunk/src/gtkmm/state_sketch.cpp
new file mode 100644 (file)
index 0000000..743953b
--- /dev/null
@@ -0,0 +1,491 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_sketch.cpp
+**     \brief Template File
+**
+**     $Id: state_sketch.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include "state_sketch.h"
+#include "state_stroke.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+#include <sinfg/valuenode_bline.h>
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include <utility>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+
+#include <sinfgapp/blineconvert.h>
+#include <sinfgapp/main.h>
+
+#include <ETL/gaussian>
+
+#include "dialog_tooloptions.h"
+
+#include <gtkmm/table.h>
+#include <gtkmm/label.h>
+#include <gtkmm/button.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/actiongroup.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateSketch studio::state_sketch;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateSketch_Context : public sigc::trackable
+{
+       Glib::RefPtr<Gtk::ActionGroup> action_group;
+
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+
+       bool prev_table_status;
+       bool prev_workarea_layer_status_;
+       
+       Gtk::Table options_table;
+       Gtk::Button button_clear_sketch;
+       Gtk::Button button_undo_stroke;
+       Gtk::Button button_save_sketch;
+       Gtk::Button button_load_sketch;
+       Gtk::CheckButton checkbutton_show_sketch;
+
+       void clear_sketch();
+       void save_sketch();
+       void load_sketch();
+       void undo_stroke();
+       void toggle_show_sketch();
+       
+public:
+
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_down_handler(const Smach::event& x);
+
+       Smach::event_result event_stroke(const Smach::event& x);
+
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+       Smach::event_result event_yield_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+       void yield_tool_options();
+
+       StateSketch_Context(CanvasView* canvas_view);
+
+       ~StateSketch_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Time get_time()const { return get_canvas_interface()->get_time(); }
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+};     // END of class StateSketch_Context
+
+
+/* === M E T H O D S ======================================================= */
+
+StateSketch::StateSketch():
+       Smach::state<StateSketch_Context>("sketch")
+{
+       insert(event_def(EVENT_STOP,&StateSketch_Context::event_stop_handler));
+       //insert(event_def(EVENT_REFRESH,&StateSketch_Context::event_refresh_handler));
+       insert(event_def(EVENT_REFRESH_DUCKS,&StateSketch_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateSketch_Context::event_mouse_down_handler));
+       insert(event_def(EVENT_WORKAREA_STROKE,&StateSketch_Context::event_stroke));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateSketch_Context::event_refresh_tool_options)); 
+       insert(event_def(EVENT_YIELD_TOOL_OPTIONS,&StateSketch_Context::event_yield_tool_options));     
+}      
+
+StateSketch::~StateSketch()
+{
+}
+
+void
+StateSketch_Context::save_sketch()
+{
+       sinfg::String filename(basename(get_canvas()->get_file_name())+".sketch");
+       
+       while(App::dialog_save_file(_("Save Sketch"), filename))
+       {
+               // If the filename still has wildcards, then we should
+               // continue looking for the file we want
+               if(find(filename.begin(),filename.end(),'*')!=filename.end())
+                       continue;
+
+               if(get_work_area()->save_sketch(filename))
+                       break;
+
+               get_canvas_view()->get_ui_interface()->error(_("Unable to save sketch"));
+       }
+}
+
+void
+StateSketch_Context::load_sketch()
+{
+       sinfg::String filename(basename(get_canvas()->get_file_name())+".sketch");
+       
+       while(App::dialog_open_file(_("Load Sketch"), filename))
+       {
+               // If the filename still has wildcards, then we should
+               // continue looking for the file we want
+               if(find(filename.begin(),filename.end(),'*')!=filename.end())
+                       continue;
+
+               if(get_work_area()->load_sketch(filename))
+                       break;
+
+               get_canvas_view()->get_ui_interface()->error(_("Unable to load sketch"));
+       }
+       get_work_area()->queue_draw();
+}
+
+void
+StateSketch_Context::clear_sketch()
+{
+       get_work_area()->clear_persistant_strokes();
+       get_canvas_view()->get_smach().process_event(EVENT_REFRESH);
+}
+
+void
+StateSketch_Context::undo_stroke()
+{
+       if(!get_work_area()->persistant_stroke_list().empty())
+       {
+               get_work_area()->persistant_stroke_list().pop_back();
+               get_canvas_view()->get_smach().process_event(EVENT_REFRESH);
+       }
+}
+
+void
+StateSketch_Context::toggle_show_sketch()
+{
+       get_work_area()->set_show_persistant_strokes(checkbutton_show_sketch.get_active());
+       get_work_area()->queue_draw();
+}
+
+StateSketch_Context::StateSketch_Context(CanvasView* canvas_view):
+       action_group(Gtk::ActionGroup::create()),
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       button_clear_sketch(_("Clear Sketch")),
+       button_undo_stroke(_("Undo Stroke")),
+       button_save_sketch(_("Save Sketch")),
+       button_load_sketch(_("Load Sketch")),
+       checkbutton_show_sketch(_("Show Sketch"))
+{
+    Glib::ustring ui_info =
+       "<ui>"
+       "       <toolbar action='toolbar-sketch'>"
+       "       <toolitem action='sketch-undo' />"
+       "       <toolitem action='sketch-clear' />"
+       "       <toolitem action='sketch-save-as' />"
+       "       <toolitem action='sketch-open' />"
+       "       </toolbar>"
+       "</ui>";
+
+       action_group->add(Gtk::Action::create(
+               "sketch-undo",
+               Gtk::StockID("gtk-undo"),
+               _("Undo Last Stroke"),
+               _("Undo Last Stroke")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::undo_stroke
+               )
+       );
+
+       action_group->add(Gtk::Action::create(
+               "sketch-clear",
+               Gtk::StockID("gtk-clear"),
+               _("Clear Sketch"),
+               _("Clear Sketch")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::clear_sketch
+               )
+       );
+
+       action_group->add(Gtk::Action::create(
+               "sketch-save-as",
+               Gtk::StockID("gtk-save-as"),
+               _("Save Sketch As..."),
+               _("Save Sketch As...")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::save_sketch
+               )
+       );
+
+       action_group->add(Gtk::Action::create(
+               "sketch-save-as",
+               Gtk::StockID("gtk-save-as"),
+               _("Save Sketch As..."),
+               _("Save Sketch As...")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::save_sketch
+               )
+       );
+
+       action_group->add(Gtk::Action::create(
+               "sketch-open",
+               Gtk::StockID("gtk-open"),
+               _("Open a Sketch"),
+               _("Open a Sketch")
+       ),
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::load_sketch
+               )
+       );
+
+       action_group->add( Gtk::Action::create("toolbar-sketch", "Sketch Toolbar") );
+
+
+       App::ui_manager()->add_ui_from_string(ui_info);
+
+       
+       checkbutton_show_sketch.set_active(get_work_area()->get_show_persistant_strokes());
+       
+       button_clear_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::clear_sketch));
+       button_undo_stroke.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::undo_stroke));
+       button_save_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::save_sketch));
+       button_load_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::load_sketch));
+       checkbutton_show_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::toggle_show_sketch));
+       //options_table.attach(*manage(new Gtk::Label(_("Sketch Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);      
+       options_table.attach(checkbutton_show_sketch, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  
+       //options_table.attach(button_undo_stroke, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+       //options_table.attach(button_clear_sketch, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);    
+       //options_table.attach(button_save_sketch, 0, 1, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+       //options_table.attach(button_load_sketch, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+
+       
+       options_table.show_all();
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+       
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+
+       get_canvas_view()->work_area->set_cursor(Gdk::PENCIL);
+
+       // Turn off duck clicking
+       get_work_area()->allow_duck_clicks=false;
+       
+       // clear out the ducks
+       //get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       //get_work_area()->queue_draw();
+       
+       // Hide the tables if they are showing
+       prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::on_user_click));
+
+       App::toolbox->refresh();
+}
+
+StateSketch_Context::~StateSketch_Context()
+{
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+       
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+
+       // Restore duck clicking
+       get_work_area()->allow_duck_clicks=true;
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       //get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+void
+StateSketch_Context::yield_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::ui_manager()->remove_action_group(action_group);
+}
+
+void
+StateSketch_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Sketch Tool"));
+       App::dialog_tool_options->set_name("sketch");
+
+       App::ui_manager()->insert_action_group(action_group);
+       App::dialog_tool_options->set_toolbar(*dynamic_cast<Gtk::Toolbar*>(App::ui_manager()->get_widget("/toolbar-sketch")));  
+
+       /*
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-undo"),
+               _("Undo Last Stroke")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::undo_stroke
+               )
+       );
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-clear"),
+               _("Clear Sketch")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::clear_sketch
+               )
+       );
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-save"),
+               _("Save Sketch to a File")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::save_sketch
+               )
+       );
+
+       App::dialog_tool_options->add_button(
+               Gtk::StockID("gtk-open"),
+               _("Open a Sketch")
+       )->signal_clicked().connect(
+               sigc::mem_fun(
+                       *this,
+                       &studio::StateSketch_Context::load_sketch
+               )
+       );
+       */
+       //button_clear_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::clear_sketch));
+       //button_undo_stroke.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::undo_stroke));
+       //button_save_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::save_sketch));
+       //button_load_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::load_sketch));
+       //checkbutton_show_sketch.signal_clicked().connect(sigc::mem_fun(*this,&studio::StateSketch_Context::toggle_show_sketch));
+}
+
+Smach::event_result
+StateSketch_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateSketch_Context::event_yield_tool_options(const Smach::event& x)
+{
+       yield_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateSketch_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateSketch_Context::event_refresh_handler(const Smach::event& x)
+{
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateSketch_Context::event_mouse_down_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               {
+                       // Enter the stroke state to get the stroke
+                       get_canvas_view()->get_smach().push_state(&state_stroke);
+                       return Smach::RESULT_ACCEPT;
+               }
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
+
+Smach::event_result
+StateSketch_Context::event_stroke(const Smach::event& x)
+{
+       const EventStroke& event(*reinterpret_cast<const EventStroke*>(&x));
+
+       assert(event.stroke_data);
+               
+       get_work_area()->add_persistant_stroke(event.stroke_data,sinfgapp::Main::get_foreground_color());
+
+       return Smach::RESULT_ACCEPT;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_sketch.h b/synfig-studio/trunk/src/gtkmm/state_sketch.h
new file mode 100644 (file)
index 0000000..820528e
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_sketch.h
+**     \brief Template Header
+**
+**     $Id: state_sketch.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_SKETCH_H
+#define __SINFG_STUDIO_STATE_SKETCH_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateSketch_Context;
+
+class StateSketch : public Smach::state<StateSketch_Context>
+{
+public:
+       StateSketch();
+       ~StateSketch();
+}; // END of class StateSketch
+
+extern StateSketch state_sketch;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_smoothmove.cpp b/synfig-studio/trunk/src/gtkmm/state_smoothmove.cpp
new file mode 100644 (file)
index 0000000..3cda4f8
--- /dev/null
@@ -0,0 +1,322 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_smooth_move.cpp
+**     \brief Template File
+**
+**     $Id: state_smoothmove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_smoothmove.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+#include "onemoment.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateSmoothMove studio::state_smooth_move;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class DuckDrag_SmoothMove : public DuckDrag_Base
+{
+       float radius;
+
+       sinfg::Vector last_translate_;
+       sinfg::Vector drag_offset_;
+       sinfg::Vector snap;
+       
+       std::vector<sinfg::Vector> last_;
+       std::vector<sinfg::Vector> positions;
+       
+public:
+       DuckDrag_SmoothMove();
+       void begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& begin);
+       bool end_duck_drag(Duckmatic* duckmatic);
+       void duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector);
+
+       void set_radius(float x) { radius=x; }
+       float get_radius()const { return radius; }      
+};
+
+
+class studio::StateSmoothMove_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       
+       //Duckmatic::Push duckmatic_push;
+       
+       sinfgapp::Settings& settings;
+
+       etl::handle<DuckDrag_SmoothMove> duck_dragger_;
+
+       Gtk::Table options_table;
+
+       Gtk::Adjustment  adj_radius;
+       Gtk::SpinButton  spin_radius;
+       
+       float pressure;
+       
+public:
+       float get_radius()const { return adj_radius.get_value(); }
+       void set_radius(float x) { return adj_radius.set_value(x); }
+       
+       void refresh_radius() { duck_dragger_->set_radius(get_radius()*pressure); }
+       
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       void refresh_tool_options();
+
+       StateSmoothMove_Context(CanvasView* canvas_view);
+
+       ~StateSmoothMove_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       void load_settings();
+       void save_settings();
+};     // END of class StateSmoothMove_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateSmoothMove::StateSmoothMove():
+       Smach::state<StateSmoothMove_Context>("smooth_move")
+{
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateSmoothMove_Context::event_refresh_tool_options));
+}      
+
+StateSmoothMove::~StateSmoothMove()
+{
+}
+
+void
+StateSmoothMove_Context::load_settings()
+{      
+       String value;
+
+       if(settings.get_value("smooth_move.radius",value))
+               set_radius(atof(value.c_str()));
+       else
+               set_radius(1.0f);
+}
+
+void
+StateSmoothMove_Context::save_settings()
+{      
+       settings.set_value("smooth_move.radius",strprintf("%f",get_radius()));
+}
+
+StateSmoothMove_Context::StateSmoothMove_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+//     duckmatic_push(get_work_area()),
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       duck_dragger_(new DuckDrag_SmoothMove()),
+       adj_radius(1,0,100000,0.01,0.1),
+       spin_radius(adj_radius,0.1,3)
+{
+       pressure=1.0f;
+       
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("SmoothMove Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  
+       
+       options_table.attach(*manage(new Gtk::Label(_("Radius"))), 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);     
+       options_table.attach(spin_radius, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       spin_radius.signal_value_changed().connect(sigc::mem_fun(*this,&StateSmoothMove_Context::refresh_radius));
+       
+       options_table.show_all();
+       refresh_tool_options();
+       //App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->present();
+       
+       get_work_area()->allow_layer_clicks=true;
+       get_work_area()->set_duck_dragger(duck_dragger_);
+
+       App::toolbox->refresh();
+
+//     get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+       get_canvas_view()->work_area->reset_cursor();
+
+       load_settings();
+}
+
+void
+StateSmoothMove_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Smooth Move"));
+       App::dialog_tool_options->set_name("smooth_move");
+}
+
+Smach::event_result
+StateSmoothMove_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateSmoothMove_Context::~StateSmoothMove_Context()
+{
+       save_settings();
+
+       get_work_area()->clear_duck_dragger();
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       App::toolbox->refresh();
+}
+
+
+
+
+DuckDrag_SmoothMove::DuckDrag_SmoothMove():radius(1.0f)
+{
+}
+
+void
+DuckDrag_SmoothMove::begin_duck_drag(Duckmatic* duckmatic, const sinfg::Vector& offset)
+{
+       last_translate_=Vector(0,0);
+               drag_offset_=duckmatic->find_duck(offset)->get_trans_point();
+
+               //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset);
+               //snap=offset-drag_offset_;
+               snap=Vector(0,0);
+
+       last_.clear();
+       positions.clear();
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+       int i;
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               last_.push_back(Vector(0,0));
+               positions.push_back((*iter)->get_trans_point());
+       }
+}
+
+void
+DuckDrag_SmoothMove::duck_drag(Duckmatic* duckmatic, const sinfg::Vector& vector)
+{
+       const DuckList selected_ducks(duckmatic->get_selected_ducks());
+       DuckList::const_iterator iter;
+       sinfg::Vector vect(duckmatic->snap_point_to_grid(vector)-drag_offset_+snap);
+       
+       int i;
+       
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+               Point p(positions[i]);
+
+               float dist(1.0f-(p-drag_offset_).mag()/get_radius());
+               if(dist<0)
+                       dist=0;
+               
+               last_[i]=vect*dist;
+               (*iter)->set_trans_point(p+last_[i]);
+       }
+
+       for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+       {
+               if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
+               Point p(positions[i]);
+
+               float dist(1.0f-(p-drag_offset_).mag()/get_radius());
+               if(dist<0)
+                       dist=0;
+               
+               last_[i]=vect*dist;
+               (*iter)->set_trans_point(p+last_[i]);
+       }
+       
+       last_translate_=vect;
+       //snap=Vector(0,0);
+}
+
+bool
+DuckDrag_SmoothMove::end_duck_drag(Duckmatic* duckmatic)
+{
+       //sinfg::info("end_duck_drag(): Diff= %f",last_translate_.mag());
+       if(last_translate_.mag()>0.0001)
+       {
+               const DuckList selected_ducks(duckmatic->get_selected_ducks());
+               DuckList::const_iterator iter;
+
+               int i;
+               
+               smart_ptr<OneMoment> wait;if(selected_ducks.size()>20)wait.spawn();
+                       
+               for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
+               {
+                       if(last_[i].mag()>0.0001)
+                               if(!(*iter)->signal_edited()((*iter)->get_point()))
+                               {
+                                       throw String("Bad Move");
+                               }
+               }
+               //duckmatic->get_selected_ducks()=new_set;
+               //duckmatic->refresh_selected_ducks();
+               return true;
+       }
+       else
+       {
+               duckmatic->signal_user_click_selected_ducks(0);
+               return false;
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_smoothmove.h b/synfig-studio/trunk/src/gtkmm/state_smoothmove.h
new file mode 100644 (file)
index 0000000..038b9d4
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_smoothmove.h
+**     \brief Template Header
+**
+**     $Id: state_smoothmove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_SMOOTHMOVE_H
+#define __SINFG_STUDIO_STATE_SMOOTHMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateSmoothMove_Context;
+
+class StateSmoothMove : public Smach::state<StateSmoothMove_Context>
+{
+public:
+       StateSmoothMove();
+       ~StateSmoothMove();
+}; // END of class StateSmoothMove
+
+extern StateSmoothMove state_smooth_move;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_stroke.cpp b/synfig-studio/trunk/src/gtkmm/state_stroke.cpp
new file mode 100644 (file)
index 0000000..f4e91a9
--- /dev/null
@@ -0,0 +1,203 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_stroke.cpp
+**     \brief Template File
+**
+**     $Id: state_stroke.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include "state_stroke.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+#include <sinfg/valuenode_bline.h>
+#include <ETL/hermite>
+#include <ETL/calculus>
+#include <utility>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateStroke studio::state_stroke;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateStroke_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       Duckmatic::Push duckmatic_push;
+       
+       etl::smart_ptr<std::list<sinfg::Point> > stroke_data;
+
+       etl::smart_ptr<std::list<sinfg::Real> > width_data;
+
+       Gdk::ModifierType modifier;
+
+public:
+
+       Smach::event_result event_stop_handler(const Smach::event& x);
+
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_up_handler(const Smach::event& x);
+
+       Smach::event_result event_mouse_draw_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       StateStroke_Context(CanvasView* canvas_view);
+
+       ~StateStroke_Context();
+
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+};     // END of class StateStroke_Context
+
+
+/* === M E T H O D S ======================================================= */
+
+StateStroke::StateStroke():
+       Smach::state<StateStroke_Context>("stroke")
+{
+       insert(event_def(EVENT_STOP,&StateStroke_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateStroke_Context::event_refresh_handler));
+//     insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateStroke_Context::event_mouse_down_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateStroke_Context::event_mouse_up_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateStroke_Context::event_mouse_draw_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateStroke_Context::event_refresh_tool_options));
+}      
+
+StateStroke::~StateStroke()
+{
+}
+
+
+StateStroke_Context::StateStroke_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       duckmatic_push(get_work_area())
+{
+       width_data.spawn();
+       stroke_data.spawn();
+
+       get_work_area()->add_stroke(stroke_data, sinfgapp::Main::get_foreground_color());
+
+       sinfg::info("Now Scribbling...");       
+}
+
+StateStroke_Context::~StateStroke_Context()
+{
+       duckmatic_push.restore();
+       
+       App::toolbox->refresh();
+       sinfg::info("No longer scribbling");    
+
+       // Send the stroke data to whatever previously called this state.
+       if(stroke_data->size()>=2)
+               get_canvas_view()->get_smach().process_event(EventStroke(stroke_data,width_data,modifier));
+}
+
+Smach::event_result
+StateStroke_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateStroke_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::pop_exception();
+}
+
+Smach::event_result
+StateStroke_Context::event_refresh_handler(const Smach::event& x)
+{
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateStroke_Context::event_mouse_up_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               {
+                       modifier=event.modifier;
+                       throw Smach::pop_exception();
+               }
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
+
+Smach::event_result
+StateStroke_Context::event_mouse_draw_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       switch(event.button)
+       {
+       case BUTTON_LEFT:
+               {
+                       stroke_data->push_back(event.pos);
+                       width_data->push_back(event.pressure);
+                       get_work_area()->queue_draw();                  
+                       return Smach::RESULT_ACCEPT;
+               }
+       
+       case BUTTON_RIGHT: // Intercept the right-button click to short-circut the pop-up menu
+               return Smach::RESULT_ACCEPT;
+       
+       default:        
+               return Smach::RESULT_OK;
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_stroke.h b/synfig-studio/trunk/src/gtkmm/state_stroke.h
new file mode 100644 (file)
index 0000000..481ebd7
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_stroke.h
+**     \brief Template Header
+**
+**     $Id: state_stroke.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_STROKE_H
+#define __SINFG_STUDIO_STATE_STROKE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "canvasview.h"
+#include "workarea.h"
+#include <sigc++/object.h>
+#include "duckmatic.h"
+#include <sinfg/blinepoint.h>
+#include <list>
+#include <ETL/smart_ptr>
+#include "eventkey.h"
+#include <gdkmm/types.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateStroke_Context;
+
+class StateStroke : public Smach::state<StateStroke_Context>
+{
+public:
+       StateStroke();
+       ~StateStroke();
+}; // END of class StateStroke
+
+extern StateStroke state_stroke;
+
+struct EventStroke : public Smach::event
+{
+       etl::smart_ptr<std::list<sinfg::Point> > stroke_data;
+       etl::smart_ptr<std::list<sinfg::Real> > width_data;
+       Gdk::ModifierType modifier;
+       
+       EventStroke(etl::smart_ptr<std::list<sinfg::Point> > stroke_data,
+                       etl::smart_ptr<std::list<sinfg::Real> > width_data,
+                       Gdk::ModifierType modifier=Gdk::ModifierType(0)
+       ):
+               Smach::event(EVENT_WORKAREA_STROKE),
+               stroke_data(stroke_data),
+               width_data(width_data),
+               modifier(modifier)
+       { }
+}; // END of EventStroke
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_width.cpp b/synfig-studio/trunk/src/gtkmm/state_width.cpp
new file mode 100644 (file)
index 0000000..fcf20e1
--- /dev/null
@@ -0,0 +1,603 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_gradient.cpp
+**     \brief Template File
+**
+**     $Id: state_width.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+
+#include <ETL/bezier>
+
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfgapp/action_system.h>
+
+#include "state_width.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+
+#include <sinfgapp/action.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "toolbox.h"
+#include "dialog_tooloptions.h"
+#include <gtkmm/optionmenu.h>
+#include "duck.h"
+
+//#include <sinfgapp/value_desc.h>
+#include <sinfgapp/main.h>
+
+#include <ETL/clock>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+StateWidth studio::state_width;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateWidth_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       //Point mouse_pos;
+       
+       handle<Duck> center;
+       handle<Duck> radius;
+       handle<Duck> closestpoint;
+       
+       map<handle<Duck>,Real>  changetable;
+       
+       etl::clock      clocktime;
+       Real            lastt;
+       
+       bool added;
+
+       void refresh_ducks();
+       
+       bool prev_workarea_layer_clicking;
+       bool prev_workarea_duck_clicking;
+       Duckmatic::Type old_duckmask;
+               
+       //Toolbox settings
+       sinfgapp::Settings& settings;
+       
+       //Toolbox display
+       Gtk::Table options_table;
+       
+       //Gtk::Entry            entry_id; //what to name the layer
+               
+       Gtk::Adjustment adj_delta;
+       Gtk::SpinButton spin_delta;
+       
+       Gtk::Adjustment adj_radius;
+       Gtk::SpinButton spin_radius;
+       
+       Gtk::CheckButton check_relative;
+               
+       void AdjustWidth(handle<Duckmatic::Bezier> c, float t, Real mult, bool invert);
+       
+public:
+
+       Real get_delta()const { return adj_delta.get_value(); }
+       void set_delta(Real f) { adj_delta.set_value(f); }
+       
+       Real get_radius()const { return adj_radius.get_value(); }
+       void set_radius(Real f) { adj_radius.set_value(f); }
+       
+       bool get_relative() const { return check_relative.get_active(); }
+       void set_relative(bool r) { check_relative.set_active(r); }
+       
+       void refresh_tool_options(); //to refresh the toolbox   
+
+       //events
+       Smach::event_result event_stop_handler(const Smach::event& x);
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+       Smach::event_result event_mouse_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       //constructor destructor
+       StateWidth_Context(CanvasView* canvas_view);
+       ~StateWidth_Context();
+
+       //Canvas interaction
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //Modifying settings etc.
+       void load_settings();
+       void save_settings();
+       void reset();
+       
+};     // END of class StateGradient_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateWidth::StateWidth():
+       Smach::state<StateWidth_Context>("width")
+{
+       insert(event_def(EVENT_STOP,&StateWidth_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateWidth_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateWidth_Context::event_mouse_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateWidth_Context::event_mouse_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateWidth_Context::event_mouse_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateWidth_Context::event_refresh_tool_options));
+}
+
+StateWidth::~StateWidth()
+{
+}
+
+void
+StateWidth_Context::load_settings()
+{      
+       String value;
+       
+       //parse the arguments yargh!
+       if(settings.get_value("width.delta",value))
+               set_delta(atof(value.c_str()));
+       else
+               set_delta(6);
+       
+       if(settings.get_value("width.radius",value))
+               set_radius(atof(value.c_str()));
+       else
+               set_radius(15);
+       
+       //defaults to true
+       if(settings.get_value("width.relative",value) && value == "0")
+               set_relative(false);
+       else
+               set_relative(true);
+}
+
+void
+StateWidth_Context::save_settings()
+{      
+       settings.set_value("width.delta",strprintf("%f",get_delta()));
+       settings.set_value("width.radius",strprintf("%f",get_radius()));
+       settings.set_value("width.relative",get_relative()?"1":"0");
+}
+
+void
+StateWidth_Context::reset()
+{
+       refresh_ducks();
+}
+
+StateWidth_Context::StateWidth_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       prev_workarea_layer_clicking(get_work_area()->allow_layer_clicks),
+       prev_workarea_duck_clicking(get_work_area()->allow_duck_clicks),
+       old_duckmask(get_work_area()->get_type_mask()),
+
+       settings(sinfgapp::Main::get_selected_input_device()->settings()),
+       
+       adj_delta(6,0,1,0.001,0.01),
+       spin_delta(adj_delta,0.01,3),
+       
+       adj_radius(0,0,1e50,1,10),
+       spin_radius(adj_radius,1,1),
+
+       check_relative(_("Relative Growth"))
+{
+       load_settings();
+       
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Width Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);       
+       //options_table.attach(entry_id, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       //expand stuff
+       options_table.attach(*manage(new Gtk::Label(_("Growth:"))), 0, 1, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(spin_delta, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       options_table.attach(*manage(new Gtk::Label(_("Radius:"))), 0, 1, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       options_table.attach(spin_radius, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+       options_table.attach(check_relative, 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+                       
+       options_table.show_all();
+       
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       //get_work_area()->clear_ducks();
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+       
+       //Create the new ducks
+       added = false;
+       
+       if(!center)
+       {
+               center = new Duck();
+               center->set_name("p1");
+               center->set_type(Duck::TYPE_POSITION);
+       }
+
+       if(!radius)
+       {
+               radius = new Duck();
+               radius->set_origin(center);
+               radius->set_radius(true);
+               radius->set_type(Duck::TYPE_RADIUS);
+               radius->set_name("radius");
+       }
+               
+       if(!closestpoint)
+       {
+               closestpoint = new Duck();
+               closestpoint->set_name("closest");
+               closestpoint->set_type(Duck::TYPE_POSITION);
+       }
+       
+       //Disable duck clicking for the maximum coolness :)
+       get_work_area()->allow_duck_clicks = false;
+       get_work_area()->set_type_mask((Duck::Type)((int)Duck::TYPE_WIDTH + (int)Duck::TYPE_RADIUS));
+
+       // Turn the mouse pointer to crosshairs
+       get_work_area()->set_cursor(Gdk::CROSSHAIR);
+
+       // Hide the tables if they are showing
+       //prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateWidth_Context::on_user_click));
+
+       App::toolbox->refresh();
+}
+
+void
+StateWidth_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Width Tool"));
+       App::dialog_tool_options->set_name("width");
+}
+
+Smach::event_result
+StateWidth_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateWidth_Context::~StateWidth_Context()
+{
+       save_settings();
+       
+       //remove ducks if need be
+       if(added)
+       {
+               get_work_area()->erase_duck(center);
+               get_work_area()->erase_duck(radius);
+               get_work_area()->erase_duck(closestpoint);
+               added = false;
+       }
+       
+       // Restore Duck clicking
+       get_work_area()->allow_duck_clicks = prev_workarea_duck_clicking;
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks = prev_workarea_layer_clicking;
+
+       // Restore the mouse pointer
+       get_work_area()->reset_cursor();
+       
+       // Restore duck masking
+       get_work_area()->set_type_mask(old_duckmask);
+
+       // Tool options be rid of ye!!
+       App::dialog_tool_options->clear();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       //if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+}
+
+Smach::event_result
+StateWidth_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateWidth_Context::event_refresh_handler(const Smach::event& x)
+{
+       refresh_ducks();
+       return Smach::RESULT_ACCEPT;
+}
+
+void 
+StateWidth_Context::AdjustWidth(handle<Duckmatic::Bezier> c, float t, Real mult, bool invert)
+{
+       //Leave the function if there is no curve
+       if(!c)return;
+       
+       Real amount1=0,amount2=0;
+       
+       //decide how much to change each width
+       /*
+       t \in [0,1]
+       
+       both pressure and multiply amount are in mult
+               (may want to change this to allow different types of falloff)
+       
+       rsq is the squared distance from the point on the curve (also part of the falloff)
+       
+               
+       */
+       //may want to provide a different falloff function...
+       if(t <= 0.2)
+               amount1 = mult;
+       else if(t >= 0.8)
+               amount2 = mult;
+       else
+       {
+               t = (t-0.2)/0.6;
+               amount1 = (1-t)*mult;
+               amount2 = t*mult;
+       }
+       
+       if(invert)
+       {
+               amount1 *= -1;
+               amount2 *= -1;
+       }
+       
+       handle<Duck>    p1 = c->p1;
+       handle<Duck>    p2 = c->p2;
+       
+       handle<Duck>    w1,w2;
+       
+       //find w1,w2
+       {
+               const DuckList dl = get_work_area()->get_duck_list();
+               
+               DuckList::const_iterator i = dl.begin();
+               
+               for(;i != dl.end(); ++i)
+               {
+                       if((*i)->get_type() == Duck::TYPE_WIDTH)
+                       {
+                               if((*i)->get_origin_duck() == p1)
+                               {
+                                       w1 = *i;
+                               }
+                               
+                               if((*i)->get_origin_duck() == p2)
+                               {
+                                       w2 = *i;
+                               }
+                       }
+               }
+       }
+       
+       if(amount1 != 0 && w1)
+       {
+               Real width = w1->get_point().mag();
+               
+               width += amount1;
+               w1->set_point(Vector(width,0));
+               
+               //log in the list of changes...
+               //to truly be changed after everything is said and done
+               changetable[w1] = width;
+       }
+       
+       if(amount2 != 0 && w2)
+       {
+               Real width = w2->get_point().mag();
+               
+               width += amount2;
+               w2->set_point(Vector(width,0));
+               
+               //log in the list of changes...
+               //to truly be changed after everything is said and done
+               changetable[w2] = width;
+       }
+}
+
+Smach::event_result
+StateWidth_Context::event_mouse_handler(const Smach::event& x)
+{
+       const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+       
+       //handle ze click       
+       if( (event.key == EVENT_WORKAREA_MOUSE_BUTTON_DOWN || event.key == EVENT_WORKAREA_MOUSE_BUTTON_DRAG)
+                       && event.button == BUTTON_LEFT )
+       {
+               const Real pw = get_work_area()->get_pw();
+               const Real ph = get_work_area()->get_ph();
+               const Real scale = sqrt(pw*pw+ph*ph);
+               const Real rad = get_relative() ? scale * get_radius() : get_radius();
+               
+               bool invert = (event.modifier&Gdk::CONTROL_MASK);
+               
+               const Real threshold = 0.08;
+               
+               float t = 0;
+               Real rsq = 0;
+               
+               Real dtime = 1/60.0;
+                               
+               //if we're dragging get the difference in time between now and then
+               if(event.key == EVENT_WORKAREA_MOUSE_BUTTON_DRAG)
+               {
+                       dtime = min(1/15.0,clocktime());
+               }
+               clocktime.reset();
+               
+               //make way for new ducks
+               //get_work_area()->clear_ducks();
+               
+               //update positions
+               //mouse_pos = event.pos;
+               
+               center->set_point(event.pos);
+               if(!added)get_work_area()->add_duck(center);
+
+               radius->set_scalar(rad);
+               if(!added)get_work_area()->add_duck(radius);
+               
+               //the other duck is at the current duck
+               closestpoint->set_point(event.pos);
+               if(!added)get_work_area()->add_duck(closestpoint);
+                       
+               //get the closest curve...
+               handle<Duckmatic::Bezier>       c;
+               if(event.pressure >= threshold)
+                       c = get_work_area()->find_bezier(event.pos,scale*8,rad,&t);
+                       
+               //run algorithm on event.pos to get 2nd placement
+               if(!c.empty())
+               {
+                       bezier<Point> curve;
+                       Point p;
+                       
+                       curve[0] = c->p1->get_trans_point();
+                       curve[1] = c->c1->get_trans_point();
+                       curve[2] = c->c2->get_trans_point();
+                       curve[3] = c->p2->get_trans_point();
+                       
+                       p = curve(t);
+                       rsq = (p-event.pos).mag_squared();
+                       
+                       const Real r = rad*rad;
+                       
+                       if(rsq < r)
+                       {
+                               closestpoint->set_point(curve(t));
+                               
+                               //adjust the width...
+                               //squared falloff for radius... [0,1]                           
+                               
+                               Real ri = (r - rsq)/r;
+                               AdjustWidth(c,t,ri*event.pressure*get_delta()*dtime,invert);
+                       }
+               }
+               
+               //the points have been added
+               added = true;
+                               
+               //draw where it is yo!
+               get_work_area()->queue_draw();
+                               
+               return Smach::RESULT_ACCEPT;
+       }
+       
+       if(event.key == EVENT_WORKAREA_MOUSE_BUTTON_UP && event.button == BUTTON_LEFT)
+       {
+               if(added)
+               {
+                       get_work_area()->erase_duck(center);
+                       get_work_area()->erase_duck(radius);
+                       get_work_area()->erase_duck(closestpoint);
+                       added = false;
+               }
+               
+               //Affect the width changes here...
+               map<handle<Duck>,Real>::iterator i = changetable.begin();
+
+               sinfgapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Sketch Width")); 
+               for(; i != changetable.end(); ++i)
+               {
+                       //for each duck modify IT!!!
+                       ValueDesc desc = i->first->get_value_desc();
+
+                       if(     desc.get_value_type() == ValueBase::TYPE_REAL )
+                       {
+                               Action::Handle action(Action::create("value_desc_set"));
+                               assert(action);
+                               
+                               action->set_param("canvas",get_canvas());                                       
+                               action->set_param("canvas_interface",get_canvas_interface());                   
+                               
+                               action->set_param("value_desc",desc);                                   
+                               action->set_param("new_value",ValueBase(i->second));
+                               action->set_param("time",get_canvas_view()->get_time());
+                               
+                               if(!action->is_ready() || !get_canvas_view()->get_instance()->perform_action(action))
+                               {
+                                       group.cancel();
+                                       sinfg::warning("Changing the width action has failed");
+                                       return Smach::RESULT_ERROR;
+                               }
+                       }
+               }                       
+               
+               changetable.clear();
+               
+               get_work_area()->queue_draw();
+               
+               return Smach::RESULT_ACCEPT;
+       }
+
+       return Smach::RESULT_OK;
+}
+
+
+void
+StateWidth_Context::refresh_ducks()
+{
+       get_work_area()->clear_ducks();
+       get_work_area()->queue_draw();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_width.h b/synfig-studio/trunk/src/gtkmm/state_width.h
new file mode 100644 (file)
index 0000000..db0d202
--- /dev/null
@@ -0,0 +1,55 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_width.h
+**     \brief Width creation state
+**
+**     $Id: state_width.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_STATE_WIDTH_H
+#define __SINFG_STUDIO_STATE_WIDTH_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateWidth_Context;
+
+class StateWidth : public Smach::state<StateWidth_Context>
+{
+public:
+       StateWidth();
+       ~StateWidth();
+}; // END of class StateWidth
+
+extern StateWidth state_width;
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/state_zoom.cpp b/synfig-studio/trunk/src/gtkmm/state_zoom.cpp
new file mode 100644 (file)
index 0000000..35ee61e
--- /dev/null
@@ -0,0 +1,331 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_zoom.cpp
+**     \brief Zoom Toole Implementation File
+**
+**     $Id: state_zoom.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+
+#include <ETL/handle>
+#include <sinfg/vector.h>
+
+
+#include "state_zoom.h"
+#include "event_mouse.h"
+#include "canvasview.h"
+#include "workarea.h"
+#include "app.h"
+#include "dialog_tooloptions.h"
+#include "toolbox.h"
+#include <sinfgapp/main.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+StateZoom studio::state_zoom;
+
+const float ZOOMFACTOR = 1.25f;
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class studio::StateZoom_Context : public sigc::trackable
+{
+       etl::handle<CanvasView> canvas_view_;
+       CanvasView::IsWorking is_working;
+       
+       Point p1,p2;
+       
+       bool prev_workarea_layer_status_;
+               
+       //Toolbox settings
+       sinfgapp::Settings& settings;
+       
+       //Toolbox display
+       Gtk::Table options_table;
+       
+public:
+
+       void refresh_tool_options(); //to refresh the toolbox   
+
+       //events
+       Smach::event_result event_stop_handler(const Smach::event& x);
+       Smach::event_result event_refresh_handler(const Smach::event& x);
+       Smach::event_result event_mouse_click_handler(const Smach::event& x);
+       Smach::event_result event_refresh_tool_options(const Smach::event& x);
+
+       //constructor destructor
+       StateZoom_Context(CanvasView* canvas_view);
+       ~StateZoom_Context();
+
+       //Canvas interaction
+       const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
+       etl::handle<sinfgapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
+       sinfg::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
+       WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
+       
+       //Modifying settings etc.
+       void load_settings();
+       void save_settings();
+       void reset();
+       
+       //void zoom(const Point& p1, const Point& p2);
+       
+};     // END of class StateGradient_Context
+
+/* === M E T H O D S ======================================================= */
+
+StateZoom::StateZoom():
+       Smach::state<StateZoom_Context>("zoom")
+{
+       insert(event_def(EVENT_STOP,&StateZoom_Context::event_stop_handler));
+       insert(event_def(EVENT_REFRESH,&StateZoom_Context::event_refresh_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateZoom_Context::event_mouse_click_handler));
+       //insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,&StateZoom_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_BOX,&StateZoom_Context::event_mouse_click_handler));
+       //insert(event_def(EVENT_WORKAREA_BUTTON_CLICK,&StateZoom_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_UP,&StateZoom_Context::event_mouse_click_handler));
+       insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateZoom_Context::event_refresh_tool_options));
+}      
+
+StateZoom::~StateZoom()
+{
+}
+
+void
+StateZoom_Context::load_settings()
+{      
+       String value;
+       
+       //parse the arguments yargh!
+       /*if(settings.get_value("circle.feather",value))
+               set_feather(atof(value.c_str()));
+       else
+               set_feather(0);*/       
+}
+
+void
+StateZoom_Context::save_settings()
+{
+       //settings.set_value("circle.fallofftype",strprintf("%d",get_falloff()));
+}
+
+void
+StateZoom_Context::reset()
+{
+       //refresh_ducks();
+}
+
+StateZoom_Context::StateZoom_Context(CanvasView* canvas_view):
+       canvas_view_(canvas_view),
+       is_working(*canvas_view),
+       prev_workarea_layer_status_(get_work_area()->allow_layer_clicks),
+       settings(sinfgapp::Main::get_selected_input_device()->settings())
+{
+       // Set up the tool options dialog
+       //options_table.attach(*manage(new Gtk::Label(_("Zoom Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);        
+       
+       load_settings();
+
+       options_table.show_all();
+       
+       refresh_tool_options();
+       App::dialog_tool_options->present();
+
+       // Turn off layer clicking
+       get_work_area()->allow_layer_clicks=false;
+       
+       // clear out the ducks
+       get_work_area()->clear_ducks(); //???
+       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+       
+       // Hide the tables if they are showing
+       //prev_table_status=get_canvas_view()->tables_are_visible();
+       //if(prev_table_status)get_canvas_view()->hide_tables();
+               
+       // Hide the time bar
+       //get_canvas_view()->hide_timebar();
+       
+       // Connect a signal
+       //get_work_area()->signal_user_click().connect(sigc::mem_fun(*this,&studio::StateZoom_Context::on_user_click));
+       get_canvas_view()->work_area->set_cursor(Gdk::CROSSHAIR);
+
+       App::toolbox->refresh();
+}
+
+void
+StateZoom_Context::refresh_tool_options()
+{
+       App::dialog_tool_options->clear();
+       App::dialog_tool_options->set_widget(options_table);
+       App::dialog_tool_options->set_local_name(_("Zoom Tool"));
+       App::dialog_tool_options->set_name("zoom");
+}
+
+Smach::event_result
+StateZoom_Context::event_refresh_tool_options(const Smach::event& x)
+{
+       refresh_tool_options();
+       return Smach::RESULT_ACCEPT;
+}
+
+StateZoom_Context::~StateZoom_Context()
+{
+       save_settings();
+
+       // Restore layer clicking
+       get_work_area()->allow_layer_clicks=prev_workarea_layer_status_;
+       get_canvas_view()->work_area->reset_cursor();
+
+       App::dialog_tool_options->clear();
+
+       // Show the time bar
+       if(get_canvas_view()->get_canvas()->rend_desc().get_time_start()!=get_canvas_view()->get_canvas()->rend_desc().get_time_end())
+               get_canvas_view()->show_timebar();
+
+       // Bring back the tables if they were out before
+       //if(prev_table_status)get_canvas_view()->show_tables();
+                       
+       // Refresh the work area
+       get_work_area()->queue_draw();
+
+       App::toolbox->refresh();
+
+       get_canvas_view()->get_smach().process_event(EVENT_REFRESH_DUCKS);
+}
+
+Smach::event_result
+StateZoom_Context::event_stop_handler(const Smach::event& x)
+{
+       throw Smach::egress_exception();
+}
+
+Smach::event_result
+StateZoom_Context::event_refresh_handler(const Smach::event& x)
+{
+       return Smach::RESULT_ACCEPT;
+}
+
+Smach::event_result
+StateZoom_Context::event_mouse_click_handler(const Smach::event& x)
+{
+       if(x.key==EVENT_WORKAREA_BOX)
+       {
+               const EventBox& event(*reinterpret_cast<const EventBox*>(&x));
+               
+               if(event.button==BUTTON_LEFT)
+               {
+                       //respond to event box...
+                       
+                       
+                       //Center the new position at the center of the box
+                       
+                       //OH MY GOD HACK - the space is -1* and offset (by the value of the center of the canvas)...
+                       Point newpos;
+                       {
+                               const Point evcenter = (event.p1+event.p2)/2;
+                               const Point realcenter = (get_work_area()->get_window_tl() + get_work_area()->get_window_br())/2;
+                               newpos = -(evcenter - realcenter) + get_work_area()->get_focus_point();
+                       }
+                       
+                       //The zoom will be whatever the required factor to convert current box size to desired box size
+                       Point tl = get_work_area()->get_window_tl();
+                       Point br = get_work_area()->get_window_br();
+                       
+                       Vector  span = br - tl;
+                       Vector  v = event.p2 - event.p1;
+       
+                       //get the minimum zoom as long as it's greater than 1...
+                       v[0] = abs(v[0])/abs(span[0]);
+                       v[1] = abs(v[1])/abs(span[1]);
+                       
+                       float zdiv = max(v[0],v[1]);
+                       if(zdiv < 1 && zdiv > 0) //must be zoomable
+                       {
+                               get_work_area()->set_focus_point(newpos);                       
+                               get_work_area()->set_zoom(get_work_area()->get_zoom()/zdiv);
+                       }
+                       
+                       return Smach::RESULT_ACCEPT;
+               }
+       }
+       
+       if(x.key==EVENT_WORKAREA_MOUSE_BUTTON_UP)
+       {
+               const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
+               
+               if(event.button==BUTTON_LEFT)
+               {
+                       Point evpos;
+                       
+                       //make the event pos be in the same space...
+                       //   The weird ass inverted center normalized space...
+                       {
+                               const Point realcenter = (get_work_area()->get_window_tl() + get_work_area()->get_window_br())/2;
+                               evpos = -(event.pos - realcenter) + get_work_area()->get_focus_point();
+                       }
+                       
+                       /*      Zooming:
+                               focus point must zoom about the point evpos...
+                       
+                               trans about an origin not 0:
+                               p' = A(p - o) + o
+                       */
+                       
+                       Vector v = get_work_area()->get_focus_point() - evpos;
+                       
+                       if(event.modifier & Gdk::CONTROL_MASK) //zoom out...
+                       {
+                               v*=ZOOMFACTOR;
+                               //get_work_area()->zoom_out();
+                               get_work_area()->set_focus_point(evpos + v);
+                               get_work_area()->set_zoom(get_work_area()->get_zoom()/ZOOMFACTOR);
+                       }else //zoom in
+                       {
+                               v/=ZOOMFACTOR;
+                               //get_work_area()->zoom_in();
+                               get_work_area()->set_focus_point(evpos + v);
+                               get_work_area()->set_zoom(get_work_area()->get_zoom()*ZOOMFACTOR);
+                       }
+               
+                       return Smach::RESULT_ACCEPT;
+               }
+       }
+
+       return Smach::RESULT_OK;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/state_zoom.h b/synfig-studio/trunk/src/gtkmm/state_zoom.h
new file mode 100644 (file)
index 0000000..fd1b5de
--- /dev/null
@@ -0,0 +1,54 @@
+/* === S I N F G =========================================================== */
+/*!    \file state_zoom.h
+**     \brief Zoom tool Header
+**
+**     $Id: state_zoom.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STATE_ZOOM_H
+#define __SINFG_STATE_ZOOM_H
+
+/* === H E A D E R S ======================================================= */
+#include "smach.h"
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class StateZoom_Context;
+
+class StateZoom : public Smach::state<StateZoom_Context>
+{
+public:
+       StateZoom();
+       ~StateZoom();
+}; // END of class StateZoom
+
+extern StateZoom state_zoom;
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/statemanager.cpp b/synfig-studio/trunk/src/gtkmm/statemanager.cpp
new file mode 100644 (file)
index 0000000..ae88390
--- /dev/null
@@ -0,0 +1,121 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: statemanager.cpp,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "statemanager.h"
+#include <gtkmm/actiongroup.h>
+#include <gtkmm/action.h>
+#include <sinfg/string.h>
+#include "app.h"
+#include "toolbox.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+StateManager::StateManager():
+       state_group(Gtk::ActionGroup::create()),
+       merge_id(App::ui_manager()->new_merge_id())
+{
+       App::ui_manager()->insert_action_group(get_action_group());
+}
+
+StateManager::~StateManager()
+{
+       App::ui_manager()->remove_ui(merge_id);
+
+       for(;!merge_id_list.empty();merge_id_list.pop_back())
+               App::ui_manager()->remove_ui(merge_id_list.back());
+}
+
+void
+StateManager::change_state_(const Smach::state_base *state)
+{
+       App::toolbox->change_state_(state);
+}
+
+void
+StateManager::add_state(const Smach::state_base *state)
+{
+       String name(state->get_name());
+       
+       Glib::RefPtr<Gtk::Action> action(
+               Gtk::Action::create(
+                       "state-"+name,
+                       Gtk::StockID("sinfg-"+name),
+                       name,
+                       name
+               )
+       );
+       /*action->set_sensitive(false);*/
+       state_group->add(action);
+       
+       action->signal_activate().connect(
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::StateManager::change_state_),
+                       state
+               )
+       );
+       
+       App::ui_manager()->ensure_update();
+
+       /*App::ui_manager()->add_ui(
+               merge_id,
+               "/main-menu/menu-state",
+               "state-"+name,
+               "state-"+name
+       );
+       */
+       
+       String uid_def("<ui><popup action='menu-main'><menu action='menu-state'><menuitem action='state-"+name+"' /></menu></popup></ui>");
+       merge_id_list.push_back(App::ui_manager()->add_ui_from_string(uid_def));
+       
+       App::ui_manager()->ensure_update();
+
+       App::toolbox->add_state(state);
+}
+
+Glib::RefPtr<Gtk::ActionGroup>
+StateManager::get_action_group()
+{
+       return state_group;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/statemanager.h b/synfig-studio/trunk/src/gtkmm/statemanager.h
new file mode 100644 (file)
index 0000000..a255e02
--- /dev/null
@@ -0,0 +1,68 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: statemanager.h,v 1.1.1.1 2005/01/07 03:34:36 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STATEMANAGER_H
+#define __SINFG_STATEMANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <glibmm/refptr.h>
+#include <vector>
+#include "smach.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class ActionGroup; }
+
+typedef unsigned int guint;
+
+namespace studio {
+       class StateManager
+{
+private:
+       Glib::RefPtr<Gtk::ActionGroup> state_group;
+       
+       guint merge_id;
+       std::vector<guint> merge_id_list;
+
+       void change_state_(const Smach::state_base *state);
+
+public:
+       StateManager();
+
+       ~StateManager();
+       
+       void add_state(const Smach::state_base *state);
+
+       Glib::RefPtr<Gtk::ActionGroup> get_action_group();
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/toolbox.cpp b/synfig-studio/trunk/src/gtkmm/toolbox.cpp
new file mode 100644 (file)
index 0000000..2b03fa6
--- /dev/null
@@ -0,0 +1,627 @@
+/*! ========================================================================
+** Sinfg
+** Template File
+** $Id: toolbox.cpp,v 1.3 2005/01/13 20:23:01 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gtkmm/uimanager.h>
+
+#include <gtkmm/ruler.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbufloader.h>
+#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/statusbar.h>
+#include <gtkmm/menubar.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/button.h>
+#include <gtkmm/toolbar.h>
+#include <gtkmm/box.h>
+#include <gtkmm/image.h>
+#include <gtkmm/stock.h>
+#include <gtkmm/handlebox.h>
+
+#include <gtkmm/inputdialog.h>
+
+#include <sigc++/signal.h>
+#include <sigc++/hide.h>
+#include <sigc++/slot.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+
+#include <sstream>
+
+#include "toolbox.h"
+#include "instance.h"
+#include "app.h"
+#include "canvasview.h"
+#include "dialog_gradient.h"
+#include "dialog_color.h"
+#include "dialog_tooloptions.h"
+#include "dialog_preview.h"
+#include "dockable.h"
+#include "dockmanager.h"
+#include "dockdialog.h"
+
+#include "widget_defaults.h"
+
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+using namespace SigC;
+
+/* === M A C R O S ========================================================= */
+
+#define GRAB_HINT_DATA(y)      { \
+               String x; \
+               if(sinfgapp::Main::settings().get_value(String("pref.")+y+"_hints",x)) \
+               { \
+                       set_type_hint((Gdk::WindowTypeHint)atoi(x.c_str())); \
+               } \
+       }
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+#define TOGGLE_TOOLBOX_BUTTON(button,stockid,tooltip)  \
+       button = manage(new class Gtk::ToggleButton()); \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::IconSize(4)));    \
+       button->add(*icon);     \
+       tooltips.set_tip(*button,tooltip);      \
+       icon->show();   \
+       button->show()
+
+#define TOOLBOX_BUTTON(button,stockid,tooltip) \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::IconSize(4)));    \
+       button->add(*icon);     \
+       tooltips.set_tip(*button,tooltip);      \
+       icon->show();   \
+       button->show()
+
+#define ADD_TOOLBOX_BUTTON(button,stockid,tooltip)     Gtk::Button *TOOLBOX_BUTTON(button,stockid,tooltip)
+
+void
+save_selected_instance()
+{
+       if(!studio::App::get_selected_instance())
+       {
+               App::dialog_error_blocking("Cannot save","Nothing to save");
+               return;
+       }
+
+       if(!studio::App::get_selected_instance()->save())
+               App::dialog_error_blocking("Save - Error","Unable to save file");
+}
+
+void
+save_as_selected_instance()
+{
+       if(!studio::App::get_selected_instance())
+       {
+               App::dialog_error_blocking("Cannot save as","Nothing to save");
+               return;
+       }
+
+       studio::App::get_selected_instance()->dialog_save_as();
+}
+
+void
+close_selected_instance()
+{
+       etl::handle<studio::Instance> instance=studio::App::get_selected_instance();
+
+       if(!instance)
+       {
+               App::dialog_error_blocking("Cannot close","Nothing to close");
+               return;
+       }
+
+       instance->safe_close();
+       
+       //assert(instance.unique());
+}
+
+
+static void
+show_dialog_input()
+{
+       App::dialog_input->present();
+}
+
+void _create_stock_dialog1()
+{
+       DockDialog* dock_dialog(new DockDialog);
+       dock_dialog->set_contents("canvases history");
+       dock_dialog->set_composition_selector(true);
+       dock_dialog->present();
+}
+void _create_stock_dialog2()
+{
+       DockDialog* dock_dialog(new DockDialog);
+       dock_dialog->set_contents("layers children keyframes | params");
+       dock_dialog->present();
+}
+
+static void
+show_dialog_color()
+{
+       App::dialog_color->present();
+}
+
+Toolbox::Toolbox():
+       Gtk::Window(Gtk::WINDOW_TOPLEVEL),
+       dialog_settings(this,"toolbox")
+{
+       recent_files_menu= manage(new class Gtk::Menu());
+       
+       Gtk::Menu       *filemenu       =manage(new class Gtk::Menu());
+
+       dock_dialogs=manage(new class Gtk::Menu());
+
+       dock_dialogs->items().push_back(Gtk::Menu_Helpers::MenuElem("Canvases, History",sigc::ptr_fun(_create_stock_dialog1)));
+       dock_dialogs->items().push_back(Gtk::Menu_Helpers::MenuElem("Layers, Children , Params",sigc::ptr_fun(_create_stock_dialog2)));
+       dock_dialogs->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+
+       
+       filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::NEW,
+               sigc::ptr_fun(&studio::App::new_instance)));    
+       filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::OPEN,
+               sigc::ptr_fun(&studio::App::dialog_open)));     
+
+       filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Open Recent"),*recent_files_menu));
+       
+       filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-saveall"),
+               sigc::ptr_fun(&studio::App::dialog_not_implemented)));
+       filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::CLOSE,
+               sigc::ptr_fun(close_selected_instance)));
+       filemenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
+       filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Dialogs"),*dock_dialogs));
+
+       //filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Canvas Browser..."),
+       //      sigc::mem_fun(studio::App::show_comp_view)));
+       //filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Gradient Editor..."),
+       //      sigc::mem_fun(show_dialog_gradient)));
+       //filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Tool Options"),
+       //      sigc::mem_fun(show_dialog_tool_options)));
+       //filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Colors..."),
+       //      sigc::mem_fun(show_dialog_color)));
+       //filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Color Palette..."),
+       //      sigc::mem_fun(show_dialog_palette)));
+       filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Input Devices..."),
+               sigc::ptr_fun(&show_dialog_input)));
+       filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Setup..."),
+               sigc::ptr_fun(&studio::App::show_setup)));
+
+       filemenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());        
+       filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID(Gtk::Stock::QUIT),
+               sigc::ptr_fun(studio::App::quit)));     
+       
+       Gtk::Menu       *helpmenu = manage(new class Gtk::Menu());
+       helpmenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::HELP,
+               sigc::ptr_fun(studio::App::dialog_not_implemented)));   
+       helpmenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());        
+       helpmenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("sinfg-about"),
+               sigc::ptr_fun(studio::App::dialog_about)));     
+       
+       Gtk::MenuBar *menubar1 = manage(new class Gtk::MenuBar());
+       menubar1->items().push_back(Gtk::Menu_Helpers::MenuElem("_File",*filemenu));
+       menubar1->items().push_back(Gtk::Menu_Helpers::MenuElem("_Help",*helpmenu));
+
+       
+       menubar1->show();
+       
+       Gtk::Image *icon;
+       
+       ADD_TOOLBOX_BUTTON(button_new,"gtk-new","New");
+       ADD_TOOLBOX_BUTTON(button_open,"gtk-open","Open");
+       ADD_TOOLBOX_BUTTON(button_save,"gtk-save","Save");
+       ADD_TOOLBOX_BUTTON(button_saveas,"gtk-save-as","SaveAs");
+       ADD_TOOLBOX_BUTTON(button_save_all,"sinfg-saveall","Save All");
+       TOOLBOX_BUTTON(button_undo,"gtk-undo","Undo");
+       TOOLBOX_BUTTON(button_redo,"gtk-redo","Redo");
+       ADD_TOOLBOX_BUTTON(button_about,"sinfg-about","About Sinfg Studio");
+       ADD_TOOLBOX_BUTTON(button_color,"sinfg-color","Color Dialog");
+       
+       TOOLBOX_BUTTON(button_rotoscope_bline,"sinfg-rotoscope_bline",_("Old Rotoscope BLine"));
+       TOOLBOX_BUTTON(button_rotoscope_polygon,"sinfg-rotoscope_polygon",_("Rotoscope Polygon"));
+       TOOLBOX_BUTTON(button_eyedrop,"sinfg-eyedrop",_("Eyedrop Tool"));
+       TOOLBOX_BUTTON(button_rotoscope,"sinfg-rotoscope_bline",_("Rotoscope 2"));
+       
+
+
+       button_about->signal_clicked().connect(sigc::ptr_fun(studio::App::dialog_about));
+       button_new->signal_clicked().connect(sigc::ptr_fun(studio::App::new_instance));
+       button_open->signal_clicked().connect(sigc::ptr_fun(studio::App::dialog_open));
+       button_save->signal_clicked().connect(sigc::ptr_fun(save_selected_instance));
+       button_saveas->signal_clicked().connect(sigc::ptr_fun(save_as_selected_instance));
+       button_save_all->signal_clicked().connect(sigc::ptr_fun(studio::App::dialog_not_implemented));
+       button_undo->signal_clicked().connect(sigc::ptr_fun(studio::App::undo));
+       button_redo->signal_clicked().connect(sigc::ptr_fun(studio::App::redo));
+       button_color->signal_clicked().connect(sigc::ptr_fun(show_dialog_color));
+
+       // Create the file button cluster
+       Gtk::Table *file_buttons=manage(new class Gtk::Table(4, 4, false));
+       file_buttons->attach(*button_new,0,1,0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_open,1,2,0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_save,2,3,0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_saveas,3,4,0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_save_all,0,1,1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_undo,1,2,1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_redo,2,3,1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->attach(*button_about,3,4,1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       //file_buttons->attach(*button_color,0,1,2,3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       file_buttons->show();
+
+       tool_table=manage(new class Gtk::Table(4, 4, false));
+       tool_table->show();
+       Gtk::HandleBox* handle_tools(manage(new Gtk::HandleBox()));
+       handle_tools->add(*tool_table);
+       handle_tools->show();
+       handle_tools->set_handle_position(Gtk::POS_TOP);
+       handle_tools->set_snap_edge(Gtk::POS_TOP);
+       
+       Widget_Defaults* widget_defaults(manage(new Widget_Defaults()));
+       widget_defaults->show();
+       Gtk::HandleBox* handle_defaults(manage(new Gtk::HandleBox()));
+       handle_defaults->add(*widget_defaults);
+       handle_defaults->show();
+       handle_defaults->set_handle_position(Gtk::POS_TOP);
+       handle_defaults->set_snap_edge(Gtk::POS_TOP);
+       
+       // Create the toplevel table
+       Gtk::Table *table1 = manage(new class Gtk::Table(1, 2, false));
+       table1->set_row_spacings(0);
+       table1->set_col_spacings(0);
+       table1->attach(*menubar1, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK, 0, 0);
+       table1->attach(*file_buttons, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //table1->attach(*manage(new Gtk::Label(_("Tools"))), 0, 1, 2, 3, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       table1->attach(*handle_tools, 0, 1, 3, 4, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       table1->attach(*handle_defaults, 0, 1, 4, 5, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
+       table1->show_all();
+       
+       
+       
+       // Set the parameters for this window
+       add(*table1);
+       set_title("Synfig Studio");
+       set_modal(false);
+       property_window_position().set_value(Gtk::WIN_POS_NONE);
+       signal_delete_event().connect(sigc::ptr_fun(App::shutdown_request));
+       set_resizable(false);
+
+
+       
+       App::signal_instance_selected().connect(
+               sigc::hide(
+                       sigc::mem_fun(*this,&studio::Toolbox::update_undo_redo)
+               )
+       );
+
+       App::signal_recent_files_changed().connect(
+                       sigc::mem_fun(*this,&studio::Toolbox::on_recent_files_changed)
+       );
+
+       button_undo->set_sensitive(false);
+       button_redo->set_sensitive(false);      
+       button_rotoscope_bline->set_sensitive(false);
+       button_rotoscope->set_sensitive(false);
+       button_rotoscope_polygon->set_sensitive(false); 
+       button_eyedrop->set_sensitive(false);   
+
+
+       std::list<Gtk::TargetEntry> listTargets;
+       listTargets.push_back( Gtk::TargetEntry("text/plain") );
+       listTargets.push_back( Gtk::TargetEntry("image") );
+//     listTargets.push_back( Gtk::TargetEntry("image/x-sif") );
+
+       drag_dest_set(listTargets);
+       signal_drag_data_received().connect( sigc::mem_fun(*this, &studio::Toolbox::on_drop_drag_data_received) );
+       
+       App::dock_manager->signal_dockable_registered().connect(sigc::mem_fun(*this,&Toolbox::dockable_registered));
+       
+       changing_state_=false;
+       
+       GRAB_HINT_DATA("toolbox");
+       add_accel_group(App::ui_manager()->get_accel_group());
+       
+       App::signal_present_all().connect(sigc::mem_fun(*this,&Toolbox::present));
+}
+
+Toolbox::~Toolbox()
+{
+       hide();
+       //studio::App::cb.task("Toolbox: I was nailed!");
+       //studio::App::quit();
+
+       if(studio::App::toolbox==this)
+               studio::App::toolbox=NULL;
+
+}
+
+void
+Toolbox::set_active_state(const String& statename)
+{
+       std::map<sinfg::String,Gtk::ToggleButton *>::iterator iter;
+
+       changing_state_=true;
+       
+       sinfgapp::Main::set_state(statename);
+       
+       try
+       {
+               
+               for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
+               {
+                       if(iter->first==statename)
+                       {
+                               if(!iter->second->get_active())
+                                       iter->second->set_active(true);
+                       }
+                       else
+                       {
+                               if(iter->second->get_active())
+                                       iter->second->set_active(false);
+                       }
+               }
+       }
+       catch(...)
+       {
+               changing_state_=false;
+               throw;
+       }
+       changing_state_=false;
+}
+
+void
+Toolbox::change_state(const sinfg::String& statename)
+{
+       etl::handle<studio::CanvasView> canvas_view(studio::App::get_selected_canvas_view());
+       if(canvas_view)
+       {
+               if(statename==canvas_view->get_smach().get_state_name())
+               {
+                       return;
+               }
+               
+               if(state_button_map.count(statename))
+               {
+                       state_button_map[statename]->clicked();
+               }
+               else
+               {
+                       sinfg::error("Unknown state \"%s\"",statename.c_str());
+               }
+       }
+}
+
+void
+Toolbox::change_state_(const Smach::state_base *state)
+{
+       if(changing_state_)
+               return;
+       changing_state_=true;
+       
+       try
+       {
+               etl::handle<studio::CanvasView> canvas_view(studio::App::get_selected_canvas_view());
+               if(canvas_view)
+               {
+                       if(state->get_name()==String("normal"))
+                       {
+                               canvas_view->get_smach().egress();                              
+                       }
+                       else
+                       {
+                               canvas_view->get_smach().enter(state);
+                       }
+               }
+               else
+                       refresh();
+       }
+       catch(...)
+       {
+               changing_state_=false;
+               throw;
+       }
+       
+       changing_state_=false;
+}
+
+void
+Toolbox::add_state(const Smach::state_base *state)
+{
+       Gtk::Image *icon;
+
+       assert(state);
+
+       String name=state->get_name();
+       
+       Gtk::ToggleButton* button;
+       button=manage(new class Gtk::ToggleButton());
+
+       icon=manage(new Gtk::Image(Gtk::StockID("sinfg-"+name),Gtk::IconSize(4)));
+       button->add(*icon);
+       tooltips.set_tip(*button,name);
+       icon->show();
+       button->show();
+
+       
+
+       
+       int row=state_button_map.size()/4;
+       int col=state_button_map.size()%4;
+
+       tool_table->attach(*button,col,col+1,row,row+1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       
+       state_button_map[name]=button;
+       
+       button->signal_clicked().connect(
+               sigc::bind(
+                       sigc::mem_fun(*this,&studio::Toolbox::change_state_),
+                       state
+               )
+       );
+       
+       
+       refresh();
+}
+
+
+void
+Toolbox::update_undo_redo()
+{      
+       etl::handle<Instance> instance=App::get_selected_instance();
+       if(instance)
+       {
+               button_undo->set_sensitive(instance->get_undo_status());
+               button_redo->set_sensitive(instance->get_redo_status());        
+       }
+       
+       // This should probably go elsewhere, but it should
+       // work fine here with no troubles.
+       // These next several lines just adjust the rotoscope buttons
+       // so that they are only clickable when they should be.
+       if(instance && App::get_selected_canvas_view())
+       {
+               std::map<sinfg::String,Gtk::ToggleButton *>::iterator iter;
+               
+               for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
+                       iter->second->set_sensitive(true);
+       }
+       else
+       {
+               std::map<sinfg::String,Gtk::ToggleButton *>::iterator iter;
+               
+               for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
+                       iter->second->set_sensitive(false);
+       }
+
+       etl::handle<CanvasView> canvas_view=App::get_selected_canvas_view();
+       if(canvas_view && canvas_view->get_smach().get_state_name())
+       {
+               set_active_state(canvas_view->get_smach().get_state_name());
+       }
+       else
+               set_active_state("none");
+
+}
+
+void
+Toolbox::on_recent_files_changed()
+{      
+       while(recent_files_menu->get_children().size())
+               recent_files_menu->remove(**recent_files_menu->get_children().begin());
+       
+       list<string>::const_iterator iter;
+       // Check to see if the file is already on the list.
+       // If it is, then remove it from the list
+       for(iter=App::get_recent_files().begin();iter!=App::get_recent_files().end();iter++)
+               recent_files_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(basename(*iter),
+                       sigc::hide_return(sigc::bind(sigc::ptr_fun(&App::open),*iter))
+               ));
+       
+       // HACK
+       show();
+}
+
+void
+Toolbox::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data_, guint info, guint time)
+{
+       // We will make this true once we have a solid drop
+       bool success(false);
+       
+       if ((selection_data_.get_length() >= 0) && (selection_data_.get_format() == 8))
+       {
+               sinfg::String selection_data((gchar *)(selection_data_.get_data()));
+
+               // For some reason, GTK hands us a list of URL's seperated
+               // by not only Carrage-Returns, but also Line-Feeds.
+               // Line-Feeds will mess us up. Remove all the line-feeds.
+               while(selection_data.find_first_of('\r')!=sinfg::String::npos)
+                       selection_data.erase(selection_data.begin()+selection_data.find_first_of('\r'));
+
+               std::stringstream stream(selection_data);
+
+               while(stream)
+               {
+                       sinfg::String filename,URI;
+                       getline(stream,filename);
+                       
+                       // If we don't have a filename, move on.
+                       if(filename.empty())
+                               continue;
+                       
+                       // Make sure this URL is of the "file://" type.
+                       URI=String(filename.begin(),filename.begin()+sizeof("file://")-1);
+                       if(URI!="file://")
+                       {
+                               sinfg::warning("Unknown URI (%s) in \"%s\"",URI.c_str(),filename.c_str());
+                               continue;
+                       }
+                       
+                       // Strip the "file://" part from the filename
+                       filename=sinfg::String(filename.begin()+sizeof("file://")-1,filename.end());
+               
+                       sinfg::info("Attempting to open "+filename);            
+                       if(App::open(filename))
+                               success=true;
+                       else
+                               sinfg::error("Drop failed: Unable to open "+filename);
+               }
+       }
+       else
+               sinfg::error("Drop failed: bad selection data");
+
+       // Finish the drag
+       context->drag_finish(success, false, time);
+}
+
+void
+Toolbox::dockable_registered(Dockable* x)
+{
+       dock_dialogs->items().push_back(
+               Gtk::Menu_Helpers::MenuElem(
+                       x->get_local_name(),
+                       sigc::mem_fun(
+                               *x,
+                               &Dockable::present
+                       )
+               )
+       );
+}
diff --git a/synfig-studio/trunk/src/gtkmm/toolbox.h b/synfig-studio/trunk/src/gtkmm/toolbox.h
new file mode 100644 (file)
index 0000000..d45829e
--- /dev/null
@@ -0,0 +1,104 @@
+/*! ========================================================================
+** Sinfg
+** Template Header File
+** $Id: toolbox.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+** Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+** This software and associated documentation
+** are CONFIDENTIAL and PROPRIETARY property of
+** the above-mentioned copyright holder.
+**
+** You may not copy, print, publish, or in any
+** other way distribute this software without
+** a prior written agreement with
+** the copyright holder.
+**
+** === N O T E S ===========================================================
+**
+** ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_TOOLBOX_H
+#define __SINFG_GTKMM_TOOLBOX_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/window.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/button.h>
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/table.h>
+#include <sinfg/string.h>
+#include "smach.h"
+#include <map>
+#include "dialogsettings.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Dockable;
+class StateManager;
+       
+class Toolbox : public Gtk::Window
+{
+       friend class studio::StateManager;
+       
+       DialogSettings dialog_settings;
+
+       Gtk::Tooltips tooltips;
+       Gtk::Button *button_undo;
+       Gtk::Button *button_redo;
+
+       Gtk::Button *button_eyedrop;
+       Gtk::Button *button_rotoscope;
+       Gtk::Button *button_rotoscope_bline;
+       Gtk::Button *button_rotoscope_polygon;
+       
+       Gtk::Table *tool_table;
+
+       std::map<sinfg::String,Gtk::ToggleButton *> state_button_map;
+       
+       Gtk::Menu       *recent_files_menu;
+
+       Gtk::Menu       *dock_dialogs;
+
+       bool changing_state_;
+       
+       void on_recent_files_changed(); 
+       void on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time);
+
+       void change_state_(const Smach::state_base *state);
+       
+public:
+
+       void change_state(const sinfg::String& statename);
+
+       void update_undo_redo();
+
+       void refresh() { update_undo_redo(); }
+
+       void set_active_state(const sinfg::String& statename);
+
+       void add_state(const Smach::state_base *state);
+
+       
+       void dockable_registered(Dockable* x);
+       
+       Toolbox();
+       virtual ~Toolbox();
+       
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/valuelink.cpp b/synfig-studio/trunk/src/gtkmm/valuelink.cpp
new file mode 100644 (file)
index 0000000..c4e64b4
--- /dev/null
@@ -0,0 +1,168 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuelink.cpp
+**     \brief ValueBase Link Implementation File
+**
+**     $Id: valuelink.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuelink.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+using studio::ValueBaseLink;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+//structors
+ValueBaseLink::ValueBaseLink()
+{
+}
+
+ValueBaseLink::~ValueBaseLink()
+{
+}
+
+//link access
+
+ValueNode::LooseHandle ValueBaseLink::get_link_vfunc(int i)const
+{
+       /*list_type::const_iterator     it = list.begin();
+       
+       while(it != list.end() && i-- > 0)
+       {
+               ++it;
+       }
+       
+       if(it == list.end())
+       {
+               return ValueNode::LooseHandle();
+       }else
+       {
+               return *it;
+       }*/
+       if(i >= 0 && i < (int)list.size())
+       {
+               return list[i];
+       }else
+       {
+               return ValueNode::LooseHandle();
+       }
+}
+
+//more link access
+int ValueBaseLink::link_count()const
+{
+       return list.size();
+}
+
+String ValueBaseLink::link_local_name(int i)const
+{
+       ValueNode::LooseHandle h = get_link(i);
+
+       if(h)
+       {
+               return h->get_local_name();             
+       }else return String();
+}
+
+String ValueBaseLink::link_name(int i)const
+{
+       ValueNode::LooseHandle h = get_link(i);
+
+       if(h)
+       {
+               return h->get_name();
+       }else return String();
+}
+
+int ValueBaseLink::get_link_index_from_name(const String &name)const
+{
+       throw Exception::BadLinkName(name);
+}
+
+//list management stuff
+ValueBaseLink::list_type::const_iterator ValueBaseLink::findlink(ValueNode::Handle x) const
+{
+       for(list_type::const_iterator i = list.begin(); i != list.end(); ++i)
+       {
+               if(*i == x)
+               {
+                       return i;
+               }
+       }
+       
+       return list.end();
+}
+ValueBaseLink::list_type::iterator ValueBaseLink::findlink(ValueNode::Handle x)
+{
+       for(list_type::iterator i = list.begin(); i != list.end(); ++i)
+       {
+               if(*i == x)
+               {
+                       return i;
+               }
+       }
+       
+       return list.end();
+}
+
+void ValueBaseLink::add(ValueNode::Handle v)
+{
+       list_type::iterator i = findlink(v);
+       
+       if(i != list.end())
+       {
+               list.push_back(v);
+       }
+}
+
+void ValueBaseLink::remove(ValueNode::Handle v)
+{
+       list_type::iterator i = findlink(v);
+       
+       if(i != list.end())
+       {
+               if(i != list.end()-1)
+               {
+                       *i = list.back();
+               }
+               list.pop_back();
+       }       
+}
diff --git a/synfig-studio/trunk/src/gtkmm/valuelink.h b/synfig-studio/trunk/src/gtkmm/valuelink.h
new file mode 100644 (file)
index 0000000..c270831
--- /dev/null
@@ -0,0 +1,81 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuelink.h
+**     \brief ValueBase Link Header
+**
+**     $Id: valuelink.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_VALUELINK_H
+#define __SINFG_VALUELINK_H
+
+/* === H E A D E R S ======================================================= */
+#include <sinfg/valuenode.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+/* NOTE: DO NOT USE THE INDEX BASED INTERFACE... THINGS WILL CHANGE
+*/
+class ValueBaseLink : public sinfg::LinkableValueNode
+{
+       typedef std::vector<ValueNode::Handle> list_type;
+       list_type       list;
+
+protected:
+       //stuff I don't want
+       virtual bool set_link_vfunc(int i,sinfg::ValueNode::Handle x) {return false;}
+       virtual LinkableValueNode* create_new()const {return 0;}
+       
+       //new stuff I need
+       list_type::const_iterator findlink(sinfg::ValueNode::Handle x) const;
+       list_type::iterator findlink(sinfg::ValueNode::Handle x);
+       
+public: //linkable interface
+       
+       //stuff I do want       
+       virtual sinfg::ValueNode::LooseHandle get_link_vfunc(int i)const;
+       virtual int link_count()const;
+       
+       //I have to support the thing because it's too much work otherwise
+       virtual sinfg::String link_local_name(int i)const;
+       virtual sinfg::String link_name(int i)const;
+
+public:
+       ValueBaseLink();
+       virtual ~ValueBaseLink();
+
+       //don't want
+       virtual int get_link_index_from_name(const sinfg::String &name)const;
+
+       //new add and subtract stuff
+       virtual void add(sinfg::ValueNode::Handle v);
+       virtual void remove(sinfg::ValueNode::Handle v);
+
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp b/synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp
new file mode 100644 (file)
index 0000000..85bb392
--- /dev/null
@@ -0,0 +1,148 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_canvaschooser.cpp
+**     \brief Template File
+**
+**     $Id: widget_canvaschooser.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_canvaschooser.h"
+#include <gtkmm/menu.h>
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_CanvasChooser::Widget_CanvasChooser()
+{
+}
+
+Widget_CanvasChooser::~Widget_CanvasChooser()
+{
+}
+
+void
+Widget_CanvasChooser::set_parent_canvas(etl::handle<sinfg::Canvas> x)
+{
+       assert(x);
+       parent_canvas=x;
+}
+
+void
+Widget_CanvasChooser::set_value_(etl::handle<sinfg::Canvas> data)
+{
+       set_value(data);
+       activate();
+}
+
+void
+Widget_CanvasChooser::set_value(etl::handle<sinfg::Canvas> data)
+{
+       assert(parent_canvas);
+       canvas=data;
+
+       canvas_menu=manage(new class Gtk::Menu());
+
+       sinfg::Canvas::Children::iterator iter;
+       sinfg::Canvas::Children &children(parent_canvas->children());
+       String label;
+       
+       if(canvas)
+       {
+               label=canvas->get_name().empty()?canvas->get_id():canvas->get_name();
+               canvas_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(label));
+       }
+       
+       for(iter=children.begin();iter!=children.end();iter++)
+               if(*iter!=canvas)
+               {
+                       label=(*iter)->get_name().empty()?(*iter)->get_id():(*iter)->get_name();
+                       canvas_menu->items().push_back(
+                               Gtk::Menu_Helpers::MenuElem(
+                                       label,
+                                       sigc::bind(
+                                               sigc::mem_fun(
+                                                       *this,
+                                                       &Widget_CanvasChooser::set_value_
+                                               ),
+                                               *iter
+                                       )
+                               )
+                       );
+               }
+       canvas_menu->items().push_back(
+               Gtk::Menu_Helpers::MenuElem(
+                       _("Other..."),
+                       sigc::mem_fun(*this,&Widget_CanvasChooser::chooser_menu)
+               )
+       );
+       set_menu(*canvas_menu);
+
+       if(canvas)
+               set_history(0);
+}
+
+const etl::handle<sinfg::Canvas> &
+Widget_CanvasChooser::get_value()
+{
+       return canvas;
+}
+
+void
+Widget_CanvasChooser::chooser_menu()
+{
+       String canvas_name;
+       App::dialog_entry(_("Choose Canvas"),_("Enter the relative name of the canvas that you want"),canvas_name);
+       Canvas::Handle new_canvas;
+       try
+       {
+               new_canvas=parent_canvas->find_canvas(canvas_name);
+               set_value_(new_canvas);
+       }
+       catch(std::runtime_error x)
+       {
+               App::dialog_error_blocking(_("Error:Exception Thrown"),x.what());
+               set_value_(canvas);             
+       }
+       catch(...)
+       {
+               App::dialog_error_blocking(_("Error"),_("Unknown Exception"));
+               set_value_(canvas);
+       }
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_canvaschooser.h b/synfig-studio/trunk/src/gtkmm/widget_canvaschooser.h
new file mode 100644 (file)
index 0000000..575f56f
--- /dev/null
@@ -0,0 +1,66 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_canvaschooser.h
+**     \brief Template Header
+**
+**     $Id: widget_canvaschooser.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_CANVASCHOOSER_H
+#define __SINFG_STUDIO_WIDGET_CANVASCHOOSER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/canvas.h>
+#include <gtkmm/optionmenu.h>
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; };
+
+namespace studio {
+
+class Widget_CanvasChooser : public Gtk::OptionMenu
+{
+       Gtk::Menu *canvas_menu;
+       sinfg::Canvas::Handle parent_canvas;
+
+       sinfg::Canvas::Handle canvas;
+       void set_value_(sinfg::Canvas::Handle data);
+public:
+
+       Widget_CanvasChooser();
+       ~Widget_CanvasChooser();
+       
+       void set_parent_canvas(sinfg::Canvas::Handle x);
+       void set_value(sinfg::Canvas::Handle data);
+       const sinfg::Canvas::Handle &get_value();
+private:
+       void chooser_menu();
+}; // END of class Widget_CanvasChooser
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_color.cpp b/synfig-studio/trunk/src/gtkmm/widget_color.cpp
new file mode 100644 (file)
index 0000000..a016fe9
--- /dev/null
@@ -0,0 +1,197 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_color.cpp
+**     \brief Template File
+**
+**     $Id: widget_color.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_color.h"
+#include <cmath>
+#include "app.h"
+#include <gtkmm/drawingarea.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define use_colorspace_gamma() App::use_colorspace_gamma
+#define colorspace_gamma()     (2.2f)
+#define gamma_in(x)            ((x>0)?pow((float)x,1.0f/colorspace_gamma()):-pow((float)-x,1.0f/colorspace_gamma()))
+#define gamma_out(x)   ((x>0)?pow((float)x,colorspace_gamma()):-pow((float)-x,colorspace_gamma()))
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+Gdk::Color
+studio::colorconv_sinfg2gdk(const sinfg::Color &c_)
+{
+       const sinfg::Color c(c_.clamped());
+       Gdk::Color ret;
+       ret.set_rgb(
+                       256*App::gamma.r_F32_to_U8(c.get_r()),
+                       256*App::gamma.g_F32_to_U8(c.get_g()),
+                       256*App::gamma.b_F32_to_U8(c.get_b())
+               );
+       return ret;
+}
+
+void
+studio::render_color_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::Color &color)
+{
+       const int height(ca.get_height());
+       const int width(ca.get_width());
+       
+       const int square_size(height/2);
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
+       
+       if(color.get_alpha()!=1.0)
+       {
+               // In this case we need to render the alpha squares
+               
+               const Color bg1(Color::blend(color,Color(0.75, 0.75, 0.75),1.0).clamped());
+               const Color bg2(Color::blend(color,Color(0.5, 0.5, 0.5),1.0).clamped());
+       
+               Gdk::Color gdk_c1(colorconv_sinfg2gdk(bg1));
+               Gdk::Color gdk_c2(colorconv_sinfg2gdk(bg2));
+
+               bool toggle(false);
+               for(int i=0;i<width;i+=square_size)
+               {
+                       const int square_width(min(square_size,width-i));
+                       
+                       if(toggle)
+                       {
+                               gc->set_rgb_fg_color(gdk_c1);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), square_width, square_size);                          
+               
+                               gc->set_rgb_fg_color(gdk_c2);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+square_size, square_width, square_size);
+                               toggle=false;
+                       }
+                       else
+                       {
+                               gc->set_rgb_fg_color(gdk_c2);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), square_width, square_size);                          
+               
+                               gc->set_rgb_fg_color(gdk_c1);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+square_size, square_width, square_size);
+                               toggle=true;
+                       }
+               }
+       }
+       else
+       {
+               // In this case we have a solid color to use
+               Gdk::Color gdk_c1(colorconv_sinfg2gdk(color));
+
+               gc->set_rgb_fg_color(gdk_c1);   
+               window->draw_rectangle(gc, true, ca.get_x(), ca.get_y(), width-1, height-1);
+       }
+       gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+       window->draw_rectangle(gc, false, ca.get_x()+1, ca.get_y()+1, width-3, height-3);
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       window->draw_rectangle(gc, false, ca.get_x(), ca.get_y(), width-1, height-1);
+}
+
+/* === C L A S S E S ======================================================= */
+
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Color::Widget_Color()
+{
+       color=Color(0,0,0,0);
+       set_size_request(-1,16);
+
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Color::redraw));
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+
+}
+
+Widget_Color::~Widget_Color()
+{
+}
+
+void
+Widget_Color::set_value(const sinfg::Color &data)
+{
+       assert(data.is_valid());
+       color=data;
+       queue_draw();
+}
+
+const sinfg::Color &
+Widget_Color::get_value()
+{
+       assert(color.is_valid());
+       return color;
+}
+
+bool
+Widget_Color::on_event(GdkEvent *event)
+{
+       switch(event->type)
+       {
+       case GDK_BUTTON_PRESS:
+               if(event->button.button==1)
+               {
+                       signal_activate_();
+                       return true;
+               }
+               if(event->button.button==3)
+               {
+                       signal_secondary_();
+                       return true;
+               }
+               break;
+               
+       default:
+               break;
+       }
+       return false;
+}
+
+bool
+Widget_Color::redraw(GdkEventExpose*bleh)
+{
+       //Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+
+       const int h(get_height());
+       const int w(get_width());       
+       
+       render_color_to_window(get_window(),Gdk::Rectangle(0,0,w,h),color);
+
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_color.h b/synfig-studio/trunk/src/gtkmm/widget_color.h
new file mode 100644 (file)
index 0000000..14d52ce
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_color.h
+**     \brief Template Header
+**
+**     $Id: widget_color.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_COLOR_H
+#define __SINFG_STUDIO_WIDGET_COLOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/box.h>
+#include <gtkmm/table.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/drawingarea.h>
+#include <sinfg/color.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+
+Gdk::Color colorconv_sinfg2gdk(const sinfg::Color &c);
+       
+void render_color_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::Color &color);
+
+class Widget_Color : public Gtk::DrawingArea
+{
+       sinfg::Color color;
+       
+       sigc::signal<void> signal_activate_;
+       sigc::signal<void> signal_secondary_;
+
+protected:
+
+public:
+       sigc::signal<void>& signal_activate() { return signal_activate_; }
+       sigc::signal<void>& signal_clicked() { return signal_activate_; }
+       sigc::signal<void>& signal_secondary() { return signal_secondary_; }
+       
+       void set_value(const sinfg::Color &data);
+       const sinfg::Color &get_value();
+       Widget_Color();
+       ~Widget_Color();
+private:
+       bool redraw(GdkEventExpose*bleh);
+       bool on_event(GdkEvent *event);
+
+}; // END of class Widget_Color
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_coloredit.cpp b/synfig-studio/trunk/src/gtkmm/widget_coloredit.cpp
new file mode 100644 (file)
index 0000000..61dcec2
--- /dev/null
@@ -0,0 +1,550 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_coloredit.cpp
+**     \brief Template File
+**
+**     $Id: widget_coloredit.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_coloredit.h"
+#include <cmath>
+#include "app.h"
+#include <gtkmm/drawingarea.h>
+#include <pangomm/attributes.h>
+#include <pangomm/attrlist.h>
+#include <algorithm>
+#include <gtkmm/notebook.h>
+#include <gtkmm/box.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define use_colorspace_gamma() App::use_colorspace_gamma
+#define colorspace_gamma()     (2.2f)
+#define gamma_in(x)            ((x>=0)?pow((float)x,1.0f/colorspace_gamma()):-pow((float)-x,1.0f/colorspace_gamma()))
+#define gamma_out(x)   ((x>=0)?pow((float)x,colorspace_gamma()):-pow((float)-x,colorspace_gamma()))
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === C L A S S E S ======================================================= */
+
+ColorSlider::ColorSlider(const ColorSlider::Type &x):
+       type(x)
+{
+       signal_expose_event().connect(sigc::mem_fun(*this, &ColorSlider::redraw));
+       set_size_request(-1,12);
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+}
+
+void
+ColorSlider::set_type(Type x) { type=x; queue_draw(); }
+
+void
+ColorSlider::set_color(Color x) { color_=x; queue_draw(); }
+
+void
+ColorSlider::slider_color_TYPE_R(Color &color, float amount) { color.set_r(amount); }
+void
+ColorSlider::slider_color_TYPE_G(Color &color, float amount) { color.set_g(amount); }
+void
+ColorSlider::slider_color_TYPE_B(Color &color, float amount) { color.set_b(amount); }
+void
+ColorSlider::slider_color_TYPE_Y(Color &color, float amount) { color.set_y(amount); }
+void
+ColorSlider::slider_color_TYPE_U(Color &color, float amount) { color.set_u(amount-0.5f); }
+void
+ColorSlider::slider_color_TYPE_V(Color &color, float amount) { color.set_v(amount-0.5f); }
+void
+ColorSlider::slider_color_TYPE_HUE(Color &color, float amount) { color.set_uv_angle(Angle::rot(amount)); }
+void
+ColorSlider::slider_color_TYPE_SAT(Color &color, float amount) { color.set_s(amount*0.5f); }
+void
+ColorSlider::slider_color_TYPE_A(Color &color, float amount) { color.set_a(amount); }
+
+void
+ColorSlider::adjust_color(Type type, Color &color, float amount)
+{
+       static const slider_color_func jump_table[int(TYPE_END)] =
+       {
+               slider_color_TYPE_R,
+               slider_color_TYPE_G,
+               slider_color_TYPE_B,
+               slider_color_TYPE_Y,
+               slider_color_TYPE_U,
+               slider_color_TYPE_V,
+               slider_color_TYPE_HUE,
+               slider_color_TYPE_SAT,
+               slider_color_TYPE_A,
+       };
+       jump_table[int(type)](color,amount);
+}
+
+bool
+ColorSlider::redraw(GdkEventExpose*bleh)
+{
+       Color color(color_);
+
+       static const slider_color_func jump_table[int(TYPE_END)] =
+       {
+               slider_color_TYPE_R,
+               slider_color_TYPE_G,
+               slider_color_TYPE_B,
+               slider_color_TYPE_Y,
+               slider_color_TYPE_U,
+               slider_color_TYPE_V,
+               slider_color_TYPE_HUE,
+               slider_color_TYPE_SAT,
+               slider_color_TYPE_A,
+       };
+       
+       slider_color_func color_func(jump_table[int(type)]);
+       
+       float amount;
+       switch(type)
+       {
+               case TYPE_R: amount=color.get_r(); break;
+               case TYPE_G: amount=color.get_g(); break;
+               case TYPE_B: amount=color.get_b(); break;
+               case TYPE_Y: amount=color.get_y(); break;
+               case TYPE_U: amount=color.get_u()+0.5; break;
+               case TYPE_V: amount=color.get_v()+0.5; break;
+               case TYPE_HUE: amount=Angle::rot(color.get_uv_angle()).get(); amount-=floor(amount); break;
+               case TYPE_SAT: amount=color.get_s()*2.0; break;
+               case TYPE_A: amount=color.get_a(); break;
+               default: amount=0; break;
+       }
+       if(use_colorspace_gamma() && (type<TYPE_U))
+               amount=gamma_in(amount);
+       
+       const int height(get_height());
+       const int width(get_width());
+
+       Gdk::Rectangle ca(0,0,width,height);
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+       const Color bg1(0.75, 0.75, 0.75);
+       const Color bg2(0.5, 0.5, 0.5);
+       Gdk::Color gdk_c;
+       int i;
+       for(i=width-1;i>=0;i--)
+       {
+               color_func(color,float(i)/float(width));
+               const Color c1(Color::blend(color,bg1,1.0).clamped());
+               const Color c2(Color::blend(color,bg2,1.0).clamped());
+               assert(c1.is_valid());
+               assert(c2.is_valid());
+               
+               gushort r1;
+               gushort g1;
+               gushort b1;
+               gushort r2;
+               gushort g2;
+               gushort b2;
+               
+               if(use_colorspace_gamma() && (type<TYPE_U))
+               {
+                       r1=(256*App::gamma.r_F32_to_U8(gamma_out(c1.get_r())));
+                       g1=(256*App::gamma.g_F32_to_U8(gamma_out(c1.get_g())));
+                       b1=(256*App::gamma.b_F32_to_U8(gamma_out(c1.get_b())));
+                       r2=(256*App::gamma.r_F32_to_U8(gamma_out(c2.get_r())));
+                       g2=(256*App::gamma.g_F32_to_U8(gamma_out(c2.get_g())));
+                       b2=(256*App::gamma.b_F32_to_U8(gamma_out(c2.get_b())));
+               }
+               else
+               {
+                       r1=(256*App::gamma.r_F32_to_U8(c1.get_r()));
+                       g1=(256*App::gamma.g_F32_to_U8(c1.get_g()));
+                       b1=(256*App::gamma.b_F32_to_U8(c1.get_b()));
+                       r2=(256*App::gamma.r_F32_to_U8(c2.get_r()));
+                       g2=(256*App::gamma.g_F32_to_U8(c2.get_g()));
+                       b2=(256*App::gamma.b_F32_to_U8(c2.get_b()));
+               }
+                       
+               
+               if((i*2/height)&1)
+               {
+                       gdk_c.set_rgb(r1,g1,b1);
+                       gc->set_rgb_fg_color(gdk_c);
+                       get_window()->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), 1, height/2);                          
+       
+                       gdk_c.set_rgb(r2,g2,b2);
+                       gc->set_rgb_fg_color(gdk_c);
+                       get_window()->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+height/2, 1, height/2);
+               }
+               else
+               {
+                       gdk_c.set_rgb(r2,g2,b2);
+                       gc->set_rgb_fg_color(gdk_c);
+                       get_window()->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), 1, height/2);                          
+       
+                       gdk_c.set_rgb(r1,g1,b1);
+                       gc->set_rgb_fg_color(gdk_c);
+                       get_window()->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+height/2, 1, height/2);
+               }
+       }
+       
+       get_style()->paint_arrow(
+               get_window(),
+               Gtk::STATE_SELECTED,
+               Gtk::SHADOW_OUT,
+               ca,
+               *this,
+               " ",
+               Gtk::ARROW_UP,
+               1,
+               int(amount*width)-height/2,
+               0,
+               height,
+               height
+       );
+       
+       gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+       get_window()->draw_rectangle(gc, false, ca.get_x()+1, ca.get_y()+1, width-3, height-3);
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       get_window()->draw_rectangle(gc, false, ca.get_x(), ca.get_y(), width-1, height-1);
+       return true;
+}
+
+bool
+ColorSlider::on_event(GdkEvent *event)
+{
+       float pos(event->button.x/(float)get_width());
+       if(pos<0 || event->button.x<=0)pos=0;
+       if(pos>1)pos=1;
+
+       if(use_colorspace_gamma() && (type<TYPE_U))
+               pos=gamma_out(pos);
+       if(pos<0 || event->button.x<=0)pos=0;
+       if(pos>1)pos=1;
+
+       switch(event->type)
+       {
+       case GDK_BUTTON_RELEASE:
+               signal_activated_();
+               return true;
+       
+       case GDK_MOTION_NOTIFY:
+//             adjust_color(type,color_,pos);
+               signal_slider_moved_(type,pos);
+               queue_draw();
+               return true;
+               break;
+       default:
+               break;
+       }
+       return false;
+}
+
+/* === M E T H O D S ======================================================= */
+
+Widget_ColorEdit::Widget_ColorEdit():
+       R_adjustment(0,-10000000,10000000,1,10,0),
+       G_adjustment(0,-10000000,10000000,1,10,0),
+       B_adjustment(0,-10000000,10000000,1,10,0),
+       A_adjustment(0,-10000000,10000000,1,10,0)
+{
+       notebook=manage(new Gtk::Notebook);
+       
+       Gtk::Table* rgb_table(manage(new Gtk::Table()));
+       Gtk::Table* yuv_table(manage(new Gtk::Table()));
+       Gtk::Table* main_table(this);
+
+       {
+               Gtk::VBox* rgb_box(manage(new Gtk::VBox()));
+               Gtk::VBox* yuv_box(manage(new Gtk::VBox()));
+               rgb_box->pack_start(*rgb_table,false,false);
+               yuv_box->pack_start(*yuv_table,false,false);
+               notebook->append_page(*rgb_box,_("RGB"));
+               notebook->append_page(*yuv_box,_("YUV"));
+       }
+
+       color=Color(0,0,0,0);
+
+       set_size_request(150,-1);
+       hold_signals=true;              
+
+       Gtk::Label *label;
+       
+       R_adjustment.set_lower(-10000000);
+       G_adjustment.set_lower(-10000000);
+       B_adjustment.set_lower(-10000000);
+       A_adjustment.set_lower(-10000000);
+       
+       clamp_=true;
+       
+       Pango::AttrList attr_list;
+       Pango::AttrInt pango_size(Pango::Attribute::create_attr_size(Pango::SCALE*7));
+       pango_size.set_start_index(0);
+       pango_size.set_end_index(64);
+       attr_list.change(pango_size);
+       
+       widget_color.set_size_request(-1,16);
+       attach(widget_color, 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*notebook, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       
+#define SLIDER_ROW(i,n,l) \
+       slider_##n=manage(new ColorSlider(ColorSlider::TYPE_##n));      \
+       slider_##n->signal_slider_moved().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_slider_moved)); \
+       /*slider_##n->signal_activated().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::activated));*/ \
+       slider_##n->signal_activated().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_value_changed)); \
+       label=manage(new class Gtk::Label(l,0.0,0.5)); \
+       label->set_use_markup(false); \
+       label->set_use_underline(false); \
+       label->set_attributes(attr_list); \
+       table->attach(*label, 0, 1, 1+2*i, 2+2*i, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);  \
+       table->attach(*slider_##n, 0, 1, 2+2*i, 3+2*i, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0)
+
+#define ATTACH_SPIN_BUTTON(i,n) \
+       spinbutton_##n=manage(new class Gtk::SpinButton(n##_adjustment,1,0)); \
+       spinbutton_##n->set_update_policy(Gtk::UPDATE_ALWAYS); \
+       spinbutton_##n->set_size_request(48,-1); \
+       spinbutton_##n->show(); \
+       table->attach(*spinbutton_##n, 1, 2, 1+2*i, 3+2*i, Gtk::SHRINK, Gtk::EXPAND, 2, 0)
+
+       {
+               Gtk::Table* table(rgb_table);
+               SLIDER_ROW(0,R,_("Red"));
+               ATTACH_SPIN_BUTTON(0,R);
+               SLIDER_ROW(1,G,_("Green"));
+               ATTACH_SPIN_BUTTON(1,G);
+               SLIDER_ROW(2,B,_("Blue"));
+               ATTACH_SPIN_BUTTON(2,B);
+       }
+       {
+               Gtk::Table* table(yuv_table);
+               SLIDER_ROW(0,Y,_("Luma"));
+               SLIDER_ROW(1,HUE,_("Hue"));
+               SLIDER_ROW(2,SAT,_("Saturation"));
+               SLIDER_ROW(3,U,_("U"));
+               SLIDER_ROW(4,V,_("V"));
+       }
+       {
+               Gtk::Table* table(main_table);
+               SLIDER_ROW(1,A,_("Alpha"));
+               ATTACH_SPIN_BUTTON(1,A);
+       }
+       
+#undef SLIDER_ROW
+#undef ATTACH_SPIN_BUTTON      
+       
+       spinbutton_R->signal_activate().connect(sigc::mem_fun(*spinbutton_G,&Gtk::SpinButton::grab_focus));
+       spinbutton_G->signal_activate().connect(sigc::mem_fun(*spinbutton_B,&Gtk::SpinButton::grab_focus));
+       spinbutton_B->signal_activate().connect(sigc::mem_fun(*spinbutton_A,&Gtk::SpinButton::grab_focus));
+       spinbutton_A->signal_activate().connect(sigc::mem_fun(*spinbutton_R,&Gtk::SpinButton::grab_focus));
+
+       R_adjustment.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_value_changed));
+       G_adjustment.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_value_changed));
+       B_adjustment.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_value_changed));
+       A_adjustment.signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_ColorEdit::on_value_changed));
+
+       show_all_children();
+
+       set_value(color);
+
+       hold_signals=false;
+}
+
+Widget_ColorEdit::~Widget_ColorEdit()
+{
+}
+
+void
+Widget_ColorEdit::on_slider_moved(ColorSlider::Type type, float amount)
+{
+       Color color(get_value_raw());
+       
+       assert(color.is_valid());
+       ColorSlider::adjust_color(type,color,amount);
+       assert(color.is_valid());
+
+       // If a non-primary colorslider is adjusted,
+       // we want to make sure that we clamp
+       if(type>ColorSlider::TYPE_B && (color.get_r()<0 ||color.get_g()<0 ||color.get_b()<0))
+               clamp_=true;
+
+       /*
+       if(type==ColorSlider::TYPE_R && color.get_r()<0)clamp_=false;
+       if(type==ColorSlider::TYPE_G && color.get_g()<0)clamp_=false;
+       if(type==ColorSlider::TYPE_B && color.get_b()<0)clamp_=false;
+       */
+       clamp_=false;
+       
+       set_value(color);
+       assert(color.is_valid());
+}
+
+void
+Widget_ColorEdit::on_value_changed()
+{
+       if(hold_signals)
+               return;
+       
+       const Color color(get_value_raw());
+       assert(color.is_valid());
+       slider_R->set_color(color);
+       slider_G->set_color(color);
+       slider_B->set_color(color);
+       slider_Y->set_color(color);
+       slider_U->set_color(color);
+       slider_V->set_color(color);
+       slider_HUE->set_color(color);
+       slider_SAT->set_color(color);
+       slider_A->set_color(color);
+       widget_color.set_value(color);
+
+       activate();
+       signal_value_changed_();
+}
+
+void
+Widget_ColorEdit::set_has_frame(bool x)
+{
+       spinbutton_R->set_has_frame(x);
+       spinbutton_G->set_has_frame(x);
+       spinbutton_B->set_has_frame(x);
+       spinbutton_A->set_has_frame(x);
+       spinbutton_R->set_size_request(48,-1);
+       spinbutton_G->set_size_request(48,-1);
+       spinbutton_B->set_size_request(48,-1);
+       spinbutton_A->set_size_request(48,-1);
+}
+
+void
+Widget_ColorEdit::set_digits(int x)
+{
+       spinbutton_R->set_digits(x);
+       spinbutton_G->set_digits(x);
+       spinbutton_B->set_digits(x);
+       spinbutton_A->set_digits(x);
+       spinbutton_R->set_size_request(48,-1);
+       spinbutton_G->set_size_request(48,-1);
+       spinbutton_B->set_size_request(48,-1);
+       spinbutton_A->set_size_request(48,-1);
+}
+
+void
+Widget_ColorEdit::set_value(const sinfg::Color &data)
+{
+       assert(data.is_valid());
+       hold_signals=true;
+       clamp_=false;
+
+       color=data;
+
+       if(use_colorspace_gamma())
+       {
+               R_adjustment.set_value(gamma_in(color.get_r())*100);
+               G_adjustment.set_value(gamma_in(color.get_g())*100);
+               B_adjustment.set_value(gamma_in(color.get_b())*100);
+       }
+       else
+       {
+               R_adjustment.set_value(color.get_r()*100);
+               G_adjustment.set_value(color.get_g()*100);
+               B_adjustment.set_value(color.get_b()*100);
+       }
+       A_adjustment.set_value(color.get_a()*100);
+
+       slider_R->set_color(color);
+       slider_G->set_color(color);
+       slider_B->set_color(color);
+       slider_Y->set_color(color);
+       slider_U->set_color(color);
+       slider_V->set_color(color);
+       slider_HUE->set_color(color);
+       slider_SAT->set_color(color);
+       slider_A->set_color(color);
+       widget_color.set_value(color);
+
+       hold_signals=false;
+}
+
+sinfg::Color
+Widget_ColorEdit::get_value_raw()
+{
+       Color color;
+       if(use_colorspace_gamma())
+       {
+               color.set_r(gamma_out(R_adjustment.get_value()/100.0f));
+               color.set_g(gamma_out(G_adjustment.get_value()/100.0f));
+               color.set_b(gamma_out(B_adjustment.get_value()/100.0f));
+               assert(color.is_valid());
+       }
+       else
+       {
+               color.set_r(R_adjustment.get_value()/100);
+               color.set_g(G_adjustment.get_value()/100);
+               color.set_b(B_adjustment.get_value()/100);
+               assert(color.is_valid());
+       }
+       color.set_a(A_adjustment.get_value()/100);
+       assert(color.is_valid());
+       
+       return color;
+}
+
+const sinfg::Color &
+Widget_ColorEdit::get_value()
+{
+       if(use_colorspace_gamma())
+       {
+               color.set_r(gamma_out(R_adjustment.get_value()/100.0f));
+               color.set_g(gamma_out(G_adjustment.get_value()/100.0f));
+               color.set_b(gamma_out(B_adjustment.get_value()/100.0f));
+               assert(color.is_valid());
+       }
+       else
+       {
+               color.set_r(R_adjustment.get_value()/100);
+               color.set_g(G_adjustment.get_value()/100);
+               color.set_b(B_adjustment.get_value()/100);
+               assert(color.is_valid());
+       }
+       color.set_a(A_adjustment.get_value()/100);
+       assert(color.is_valid());
+       
+       if(notebook->get_current_page()!=0)
+               color=color.clamped();
+       
+       /*{
+               // Clamp out negative values
+               color.set_r(std::max(0.0f,(float)color.get_r()));
+               color.set_g(std::max(0.0f,(float)color.get_g()));
+               color.set_b(std::max(0.0f,(float)color.get_b()));
+       }*/
+       
+       return color;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_coloredit.h b/synfig-studio/trunk/src/gtkmm/widget_coloredit.h
new file mode 100644 (file)
index 0000000..77342ae
--- /dev/null
@@ -0,0 +1,183 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_coloredit.h
+**     \brief Template Header
+**
+**     $Id: widget_coloredit.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_COLOREDIT_H
+#define __SINFG_STUDIO_WIDGET_COLOREDIT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/box.h>
+#include <gtkmm/table.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/drawingarea.h>
+#include <sinfg/color.h>
+#include "widget_color.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk {
+       class Notebook;
+};
+
+namespace studio {
+
+class ColorSlider : public Gtk::DrawingArea
+{
+public:
+       enum Type
+       {
+               TYPE_R,
+               TYPE_G,
+               TYPE_B,
+               TYPE_Y,
+               TYPE_U,
+               TYPE_V,
+               TYPE_HUE,
+               TYPE_SAT,
+               TYPE_A,
+               
+               TYPE_END
+       };
+       
+private:
+
+       sigc::signal<void,Type,float> signal_slider_moved_;
+       sigc::signal<void> signal_activated_;
+
+       Type type;
+       sinfg::Color color_;
+
+public:
+
+       sigc::signal<void,Type,float>& signal_slider_moved() { return signal_slider_moved_; }
+       sigc::signal<void>& signal_activated() { return signal_activated_; }
+
+       Type
+       get_type()const { return type; }
+
+       const sinfg::Color&
+       get_color()const { return color_; }
+
+
+       ColorSlider(const Type &x=TYPE_Y);
+
+       void
+       set_type(Type x);
+
+       void
+       set_color(sinfg::Color x);
+
+       static void adjust_color(Type type, sinfg::Color &color, float amount);
+
+private:
+       typedef void (*slider_color_func)(sinfg::Color &,float);
+
+       static void slider_color_TYPE_R(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_G(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_B(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_Y(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_U(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_V(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_HUE(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_SAT(sinfg::Color &color, float amount);
+       static void slider_color_TYPE_A(sinfg::Color &color, float amount);
+       
+
+       bool
+       redraw(GdkEventExpose*bleh);
+       bool on_event(GdkEvent *event);
+}; // END of class ColorSlider
+
+       
+class Widget_ColorEdit : public Gtk::Table
+{
+       sigc::signal<void> signal_activated_;
+       sigc::signal<void> signal_value_changed_;
+
+       ColorSlider *slider_R;
+       ColorSlider *slider_G;
+       ColorSlider *slider_B;
+       ColorSlider *slider_A;
+       ColorSlider *slider_Y;
+       ColorSlider *slider_U;
+       ColorSlider *slider_V;
+       ColorSlider *slider_SAT;
+       ColorSlider *slider_HUE;
+       
+       Widget_Color widget_color;
+       
+       bool hold_signals;
+       
+       bool clamp_;
+       
+       Gtk::SpinButton *spinbutton_R;
+       Gtk::SpinButton *spinbutton_G;
+       Gtk::SpinButton *spinbutton_B;
+       Gtk::SpinButton *spinbutton_A;
+
+       Gtk::Adjustment R_adjustment;
+       Gtk::Adjustment G_adjustment;
+       Gtk::Adjustment B_adjustment;
+       Gtk::Adjustment A_adjustment;
+       
+       sinfg::Color color;
+
+       Gtk::Notebook* notebook;
+
+protected:
+       
+       void on_value_changed();
+
+public:
+
+       sigc::signal<void>& signal_activated() { return signal_activated_; }
+
+       sigc::signal<void>& signal_activate() { return signal_activated_; }
+
+       void on_slider_moved(ColorSlider::Type type, float amount);
+
+       //Glib::SignalProxy0<void> signal_activate() { return spinbutton_A->signal_activate(); }
+       
+       sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+       
+       void activated() { signal_activated_(); }
+       void activate() { signal_activated_(); }
+       void set_value(const sinfg::Color &data);
+       const sinfg::Color &get_value();
+       sinfg::Color get_value_raw();
+       void set_has_frame(bool x);
+       void set_digits(int x);
+       Widget_ColorEdit();
+       ~Widget_ColorEdit();
+}; // END of class Widget_ColorEdit
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_compselect.cpp b/synfig-studio/trunk/src/gtkmm/widget_compselect.cpp
new file mode 100644 (file)
index 0000000..9b342f5
--- /dev/null
@@ -0,0 +1,170 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_compselect.cpp
+**     \brief Template File
+**
+**     $Id: widget_compselect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/menu.h>
+#include "widget_compselect.h"
+#include <ETL/stringf>
+#include <sinfg/valuenode.h>
+#include "instance.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_CompSelect::Widget_CompSelect()
+{
+       App::signal_instance_created().connect(sigc::mem_fun(*this,&studio::Widget_CompSelect::new_instance));
+       App::signal_instance_deleted().connect(sigc::mem_fun(*this,&studio::Widget_CompSelect::delete_instance));
+       App::signal_instance_selected().connect(sigc::mem_fun(*this,&studio::Widget_CompSelect::set_selected_instance_signal));
+
+       set_menu(instance_list_menu);
+       refresh();
+}
+
+Widget_CompSelect::~Widget_CompSelect()
+{
+}
+
+void
+Widget_CompSelect::set_selected_instance_signal(etl::handle<studio::Instance> x)
+{
+       set_selected_instance(x);
+}
+
+void
+Widget_CompSelect::set_selected_instance_(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       selected_instance=instance;
+}
+
+void
+Widget_CompSelect::set_selected_instance(etl::loose_handle<studio::Instance> x)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       // if it's already selected, don't select it again
+       if (x==selected_instance)
+               return;
+
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+
+       if(x)
+       {
+               int i;
+               for(i=0,iter=studio::App::instance_list.begin();iter!=studio::App::instance_list.end() && ((*iter)!=x);iter++,i++);
+
+               assert(*iter==x);
+
+               set_history(i);
+       }
+       else
+               set_history(0);
+
+       set_selected_instance_(x);      
+}
+
+void
+Widget_CompSelect::new_instance(etl::handle<studio::Instance> instance)
+{
+       if(studio::App::shutdown_in_progress)
+               return;
+       
+       assert(instance);
+       
+       etl::loose_handle<studio::Instance> loose_instance(instance);
+       
+       instance->sinfgapp::Instance::signal_filename_changed().connect(sigc::mem_fun(*this,&Widget_CompSelect::refresh));
+       instance->sinfgapp::Instance::signal_filename_changed().connect(
+               sigc::bind<etl::loose_handle<studio::Instance> >(
+                       sigc::mem_fun(*this,&Widget_CompSelect::set_selected_instance),
+                       loose_instance
+               )
+       );
+
+       {
+               std::string name=basename(instance->get_file_name());
+
+               instance_list_menu.items().push_back(Gtk::Menu_Helpers::MenuElem(name,
+                       sigc::bind<etl::loose_handle<studio::Instance> >(sigc::ptr_fun(&studio::App::set_selected_instance),loose_instance)     ));
+       }
+       
+}
+
+void
+Widget_CompSelect::delete_instance(etl::handle<studio::Instance> instance)
+{
+       DEBUGPOINT();
+       refresh();
+
+       if(selected_instance==instance)
+       {
+               set_selected_instance(0);
+               set_history(0);
+       }
+}
+
+void
+Widget_CompSelect::refresh()
+{
+       remove_menu();
+
+       if(!instance_list_menu.items().empty())
+               instance_list_menu.items().clear();
+
+       if(studio::App::shutdown_in_progress)
+               return;
+
+       std::list<etl::handle<studio::Instance> >::iterator iter;
+       for(iter=studio::App::instance_list.begin();iter!=studio::App::instance_list.end();iter++)
+       {
+               std::string name=basename((*iter)->get_file_name());
+
+               instance_list_menu.items().push_back(Gtk::Menu_Helpers::MenuElem(name,
+                       sigc::bind<etl::loose_handle<studio::Instance> >(sigc::ptr_fun(&studio::App::set_selected_instance),*iter)      ));
+       }
+       set_menu(instance_list_menu);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_compselect.h b/synfig-studio/trunk/src/gtkmm/widget_compselect.h
new file mode 100644 (file)
index 0000000..c21eb08
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_compselect.h
+**     \brief Template Header
+**
+**     $Id: widget_compselect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_COMPSELECT_H
+#define __SINFG_STUDIO_WIDGET_COMPSELECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/menu.h>
+#include "app.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; };
+
+namespace studio {
+
+class Widget_CompSelect : public Gtk::OptionMenu
+{
+       Gtk::Menu       instance_list_menu;
+       
+
+       etl::loose_handle<studio::Instance>     selected_instance;
+       void set_selected_instance_(etl::handle<studio::Instance> x);
+       
+       void new_instance(etl::handle<studio::Instance> x);
+
+       void delete_instance(etl::handle<studio::Instance> x);
+
+       void set_selected_instance(etl::loose_handle<studio::Instance> x);
+
+       void set_selected_instance_signal(etl::handle<studio::Instance> x);
+               
+public:
+
+       Widget_CompSelect();
+       ~Widget_CompSelect();
+       
+       etl::loose_handle<studio::Instance> get_selected_instance() { return selected_instance; }
+
+       void refresh();
+}; // END of class Widget_CompSelect
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_curves.cpp b/synfig-studio/trunk/src/gtkmm/widget_curves.cpp
new file mode 100644 (file)
index 0000000..45f68cf
--- /dev/null
@@ -0,0 +1,542 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_curves.cpp
+**     \brief Template File
+**
+**     $Id: widget_curves.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_curves.h"
+#include <cmath>
+#include "app.h"
+#include <gtkmm/drawingarea.h>
+#include <map>
+#include <vector>
+#include <ETL/misc>
+#include <sigc++/object.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/*
+void
+studio::render_color_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::Color &color)
+{
+       const int height(ca.get_height());
+       const int width(ca.get_width());
+       
+       const int square_size(height/2);
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
+       
+       if(color.get_alpha()!=1.0)
+       {
+               // In this case we need to render the alpha squares
+               
+               const Color bg1(Color::blend(color,Color(0.75, 0.75, 0.75),1.0).clamped());
+               const Color bg2(Color::blend(color,Color(0.5, 0.5, 0.5),1.0).clamped());
+       
+               Gdk::Color gdk_c1(colorconv_sinfg2gdk(bg1));
+               Gdk::Color gdk_c2(colorconv_sinfg2gdk(bg2));
+
+               bool toggle(false);
+               for(int i=0;i<width;i+=square_size)
+               {
+                       const int square_width(min(square_size,width-i));
+                       
+                       if(toggle)
+                       {
+                               gc->set_rgb_fg_color(gdk_c1);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), square_width, square_size);                          
+               
+                               gc->set_rgb_fg_color(gdk_c2);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+square_size, square_width, square_size);
+                               toggle=false;
+                       }
+                       else
+                       {
+                               gc->set_rgb_fg_color(gdk_c2);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y(), square_width, square_size);                          
+               
+                               gc->set_rgb_fg_color(gdk_c1);
+                               window->draw_rectangle(gc, true, ca.get_x()+i, ca.get_y()+square_size, square_width, square_size);
+                               toggle=true;
+                       }
+               }
+       }
+       else
+       {
+               // In this case we have a solid color to use
+               Gdk::Color gdk_c1(colorconv_sinfg2gdk(color));
+
+               gc->set_rgb_fg_color(gdk_c1);   
+               window->draw_rectangle(gc, true, ca.get_x(), ca.get_y(), width-1, height-1);
+       }
+       gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+       window->draw_rectangle(gc, false, ca.get_x()+1, ca.get_y()+1, width-3, height-3);
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       window->draw_rectangle(gc, false, ca.get_x(), ca.get_y(), width-1, height-1);
+}
+*/
+
+/* === C L A S S E S ======================================================= */
+
+
+
+struct studio::Widget_Curves::Channel
+{
+       sinfg::String name;
+       Gdk::Color color;
+       std::map<sinfg::Real,sinfg::Real> values;
+};
+
+struct studio::Widget_Curves::CurveStruct : sigc::trackable
+{
+       sinfgapp::ValueDesc value_desc;
+       std::vector<Channel> channels;
+
+       CurveStruct(const sinfgapp::ValueDesc& x):
+               value_desc(x)
+       {
+               switch(value_desc.get_value_type())
+               {
+                       case ValueBase::TYPE_REAL:
+                               channels.push_back(Channel());
+                               channels.back().name="real";
+                               channels.back().color=Gdk::Color("#007f7f");
+                               break;
+                       case ValueBase::TYPE_TIME:
+                               channels.push_back(Channel());
+                               channels.back().name="time";
+                               channels.back().color=Gdk::Color("#7f7f00");
+                               break;
+                       case ValueBase::TYPE_INTEGER:
+                               channels.push_back(Channel());
+                               channels.back().name="int";
+                               channels.back().color=Gdk::Color("#7f0000");
+                               break;
+                       case ValueBase::TYPE_BOOL:
+                               channels.push_back(Channel());
+                               channels.back().name="bool";
+                               channels.back().color=Gdk::Color("#ff7f00");
+                               break;
+                       case ValueBase::TYPE_ANGLE:
+                               channels.push_back(Channel());
+                               channels.back().name="theta";
+                               channels.back().color=Gdk::Color("#004f4f");
+                               break;
+                       case ValueBase::TYPE_COLOR:
+                               channels.push_back(Channel());
+                               channels.back().name="red";
+                               channels.back().color=Gdk::Color("#7f0000");
+                               channels.push_back(Channel());
+                               channels.back().name="green";
+                               channels.back().color=Gdk::Color("#007f00");
+                               channels.push_back(Channel());
+                               channels.back().name="blue";
+                               channels.back().color=Gdk::Color("#00007f");
+                               channels.push_back(Channel());
+                               channels.back().name="alpha";
+                               channels.back().color=Gdk::Color("#000000");
+                               break;
+                       case ValueBase::TYPE_VECTOR:
+                               channels.push_back(Channel());
+                               channels.back().name="x";
+                               channels.back().color=Gdk::Color("#7f007f");
+                               channels.push_back(Channel());
+                               channels.back().name="y";
+                               channels.back().color=Gdk::Color("#007f7f");
+                               break;
+                       case ValueBase::TYPE_BLINEPOINT:
+                               channels.push_back(Channel());
+                               channels.back().name="v.x";
+                               channels.back().color=Gdk::Color("#ff7f00");
+                               channels.push_back(Channel());
+                               channels.back().name="v.y";
+                               channels.back().color=Gdk::Color("#7f3f00");
+                               
+                               channels.push_back(Channel());
+                               channels.back().name="width";
+                               channels.back().color=Gdk::Color("#000000");
+
+                               channels.push_back(Channel());
+                               channels.back().name="origin";
+                               channels.back().color=Gdk::Color("#ffffff");
+
+                               channels.push_back(Channel());
+                               channels.back().name="tsplit";
+                               channels.back().color=Gdk::Color("#ff00ff");
+                       
+                               channels.push_back(Channel());
+                               channels.back().name="t1.x";
+                               channels.back().color=Gdk::Color("#ff0000");
+                               channels.push_back(Channel());
+                               channels.back().name="t1.y";
+                               channels.back().color=Gdk::Color("#7f0000");
+
+                               channels.push_back(Channel());
+                               channels.back().name="t2.x";
+                               channels.back().color=Gdk::Color("#ffff00");
+                               channels.push_back(Channel());
+                               channels.back().name="t2.y";
+                               channels.back().color=Gdk::Color("#7f7f00");
+                               break;
+                       default:
+                               throw sinfg::Exception::BadType("Bad type for curves");
+               }
+       }
+       
+       void clear_all_values()
+       {
+               DEBUGPOINT();
+               std::vector<Channel>::iterator iter;
+               for(iter=channels.begin();iter!=channels.end();++iter)
+                       iter->values.clear();
+       }
+       
+       sinfg::Real get_value(int chan, sinfg::Real time, sinfg::Real tolerance)
+       {
+               std::map<sinfg::Real,sinfg::Real>::iterator iter;
+               
+               // First check to see if we have a value
+               // that is "close enough" to the time
+               // we are looking for
+               iter=channels[chan].values.lower_bound(time);
+               if(iter!=channels[chan].values.end() && iter->first-time<=tolerance)
+                       return -iter->second;
+               
+               // Since that didn't work, we now need
+               // to go ahead and figure out what the
+               // actual value is at that time.
+               ValueBase value(value_desc.get_value(time));
+               switch(value.get_type())
+               {
+                       case ValueBase::TYPE_REAL:
+                               channels[0].values[time]=value.get(Real());
+                               break;
+                       case ValueBase::TYPE_TIME:
+                               channels[0].values[time]=value.get(Time());
+                               break;
+                       case ValueBase::TYPE_INTEGER:
+                               channels[0].values[time]=value.get(int());
+                               break;
+                       case ValueBase::TYPE_BOOL:
+                               channels[0].values[time]=value.get(bool());
+                               break;
+                       case ValueBase::TYPE_ANGLE:
+                               channels[0].values[time]=Angle::rad(value.get(Angle())).get();
+                               break;
+                       case ValueBase::TYPE_COLOR:
+                               channels[0].values[time]=value.get(Color()).get_r();
+                               channels[1].values[time]=value.get(Color()).get_g();
+                               channels[2].values[time]=value.get(Color()).get_b();
+                               channels[3].values[time]=value.get(Color()).get_a();
+                               break;
+                       case ValueBase::TYPE_VECTOR:
+                               channels[0].values[time]=value.get(Vector())[0];
+                               channels[1].values[time]=value.get(Vector())[1];
+                               break;
+                       case ValueBase::TYPE_BLINEPOINT:
+                               channels[0].values[time]=value.get(BLinePoint()).get_vertex()[0];
+                               channels[1].values[time]=value.get(BLinePoint()).get_vertex()[1];
+                               channels[2].values[time]=value.get(BLinePoint()).get_width();
+                               channels[3].values[time]=value.get(BLinePoint()).get_origin();
+                               channels[4].values[time]=value.get(BLinePoint()).get_split_tangent_flag();
+                               channels[5].values[time]=value.get(BLinePoint()).get_tangent1()[0];
+                               channels[6].values[time]=value.get(BLinePoint()).get_tangent1()[1];
+                               channels[7].values[time]=value.get(BLinePoint()).get_tangent2()[0];
+                               channels[8].values[time]=value.get(BLinePoint()).get_tangent2()[1];
+                               break;
+                       default:
+                               return 0;
+               }
+               
+               return -channels[chan].values[time];
+       }
+};
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Curves::Widget_Curves():
+       range_adjustment_(new Gtk::Adjustment(-1,-2,2,0.1,0.1,2))
+{
+       set_size_request(64,64);
+
+       range_adjustment_->signal_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Widget_Curves::queue_draw
+               )
+       );
+       range_adjustment_->signal_value_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Widget_Curves::queue_draw
+               )
+       );
+       //set_vadjustment(*range_adjustment_);
+       
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Curves::redraw));
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       
+}
+
+Widget_Curves::~Widget_Curves()
+{
+}
+
+void
+Widget_Curves::set_time_adjustment(Gtk::Adjustment&x)
+{
+       time_adjustment_=&x;
+       time_adjustment_->signal_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Widget_Curves::queue_draw
+               )
+       );
+       time_adjustment_->signal_value_changed().connect(
+               sigc::mem_fun(
+                       *this,
+                       &Widget_Curves::queue_draw
+               )
+       );
+       //set_hadjustment(*time_adjustment_);
+}
+
+void
+Widget_Curves::clear()
+{
+       curve_list_.clear();
+}
+
+void
+Widget_Curves::refresh()
+{
+       std::list<CurveStruct>::iterator curve_iter;
+       for(curve_iter=curve_list_.begin();curve_iter!=curve_list_.end();++curve_iter)
+       {
+               curve_iter->clear_all_values();
+       }
+       queue_draw();
+}
+
+void
+Widget_Curves::set_value_descs(std::list<sinfgapp::ValueDesc> value_descs)
+{
+       curve_list_.clear();
+       
+       std::list<sinfgapp::ValueDesc>::iterator iter;
+       for(iter=value_descs.begin();iter!=value_descs.end();++iter)
+       {
+               try {
+                       curve_list_.push_back(*iter);
+                       if(iter->is_value_node())
+                       {
+                               DEBUGPOINT();
+                               iter->get_value_node()->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &studio::Widget_Curves::refresh
+                                       )
+                               );
+                       }
+                       if(iter->parent_is_value_node())
+                       {
+                               DEBUGPOINT();
+                               iter->get_parent_value_node()->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &studio::Widget_Curves::refresh
+                                       )
+                               );
+                       }
+                       if(iter->parent_is_layer_param())
+                       {
+                               DEBUGPOINT();
+                               iter->get_layer()->signal_changed().connect(
+                                       sigc::mem_fun(
+                                               *this,
+                                               &studio::Widget_Curves::refresh
+                                       )
+                               );
+                       }
+               }catch(sinfg::Exception::BadType)
+               {
+                       continue;
+               }
+       }
+       queue_draw();
+}
+
+bool
+Widget_Curves::on_event(GdkEvent *event)
+{
+       switch(event->type)
+       {
+       case GDK_SCROLL:
+               switch(event->scroll.direction)
+               {
+                       case GDK_SCROLL_UP:
+                               range_adjustment_->set_page_size(range_adjustment_->get_page_size()/1.25);
+                               range_adjustment_->changed();
+                               break;
+                       case GDK_SCROLL_DOWN:
+                               range_adjustment_->set_page_size(range_adjustment_->get_page_size()*1.25);
+                               range_adjustment_->changed();
+                               break;
+                       default:
+                               break;
+               }
+               break;
+       default:
+               return Gtk::DrawingArea::on_event(event);
+               break;
+       }
+
+       return true;
+       
+/*     switch(event->type)
+       {
+       case GDK_BUTTON_PRESS:
+               if(event->button.button==1)
+               {
+                       signal_activate_();
+                       return true;
+               }
+               if(event->button.button==3)
+               {
+                       signal_secondary_();
+                       return true;
+               }
+               break;
+               
+       default:
+               break;
+       }
+       return false;
+*/
+}
+
+bool
+Widget_Curves::redraw(GdkEventExpose*bleh)
+{
+       const int h(get_height());
+       const int w(get_width());       
+       get_window()->clear();
+       
+       if(!time_adjustment_ || !range_adjustment_ || !h || !w)
+               return false;
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+       
+       const Real t_begin(time_adjustment_->get_lower());
+       const Real t_end(time_adjustment_->get_upper());
+       const Real dt((t_end-t_begin)/w);
+
+       const Real r_bottom(range_adjustment_->get_value());
+       const Real r_top(r_bottom+range_adjustment_->get_page_size());
+       const Real dr((r_top-r_bottom)/h);
+       Real r_max(-100000000);
+       Real r_min(100000000);
+       
+       std::list<CurveStruct>::iterator curve_iter;
+
+       vector<Gdk::Point> points[10];
+
+       gc->set_function(Gdk::COPY);
+       gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+       // Draw zero mark
+       gc->set_rgb_fg_color(Gdk::Color("#4f4f4f"));
+       get_window()->draw_rectangle(gc, false, 0, round_to_int((0-r_bottom)/dr), w, 0);
+
+       // Draw current time
+       gc->set_rgb_fg_color(Gdk::Color("#00007f"));
+       get_window()->draw_rectangle(gc, false, round_to_int((time_adjustment_->get_value()-t_begin)/dt), 0, 0, h);
+
+       for(curve_iter=curve_list_.begin();curve_iter!=curve_list_.end();++curve_iter)
+       {
+               Real t;
+               int i;
+               int channels(curve_iter->channels.size());
+               for(i=0;i<channels;i++)
+                       points[i].clear();
+
+               for(i=0,t=t_begin;i<w;i++,t+=dt)
+               {
+                       for(int chan=0;chan<channels;chan++)
+                       {
+                               Real x(curve_iter->get_value(chan,t,dt));
+                               r_max=max(r_max,x);
+                               r_min=min(r_min,x);
+                               points[chan].push_back(
+                                       Gdk::Point(
+                                               i,
+                                               round_to_int(
+                                                       (
+                                                               x-r_bottom
+                                                       )/dr
+                                               )
+                                       )
+                               );
+                       }
+               }
+
+               for(int chan=0;chan<channels;chan++)
+               {
+                       gc->set_rgb_fg_color(curve_iter->channels[chan].color);
+       
+                       // Draw the curve
+                       get_window()->draw_lines(gc, Glib::ArrayHandle<Gdk::Point>(points[chan]));
+
+                       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_pango_context()));
+                                               
+                       layout->set_text(curve_iter->channels[chan].name);              
+                       get_window()->draw_layout(gc, 1, points[chan][0].get_y()+1, layout);                    
+               }
+       }
+       
+       if(!curve_list_.empty())
+       {
+               range_adjustment_->set_upper(r_max+range_adjustment_->get_page_size()/2);
+               range_adjustment_->set_lower(r_min-range_adjustment_->get_page_size()/2);
+       }
+       get_window()->get_update_area();
+       
+       return true;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_curves.h b/synfig-studio/trunk/src/gtkmm/widget_curves.h
new file mode 100644 (file)
index 0000000..ffdd4ac
--- /dev/null
@@ -0,0 +1,80 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_curves.h
+**     \brief Template Header
+**
+**     $Id: widget_curves.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_CURVES_H
+#define __SINFG_STUDIO_WIDGET_CURVES_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/box.h>
+#include <gtkmm/table.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/layout.h>
+#include <sinfg/color.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_Curves : public Gtk::DrawingArea
+{
+       struct Channel;
+       struct CurveStruct;
+
+       Gtk::Adjustment* time_adjustment_;
+       Gtk::Adjustment* range_adjustment_;
+               
+       std::list<CurveStruct> curve_list_;
+       
+public:
+
+       Widget_Curves();
+       ~Widget_Curves();
+
+       void set_value_descs(std::list<sinfgapp::ValueDesc> value_descs);
+       void clear();
+       void refresh();
+
+       Gtk::Adjustment& get_range_adjustment() { return *range_adjustment_; }
+       Gtk::Adjustment& get_time_adjustment() { return *time_adjustment_; }
+       void set_time_adjustment(Gtk::Adjustment&);
+
+private:
+       bool redraw(GdkEventExpose*bleh);
+       bool on_event(GdkEvent *event);
+
+}; // END of class Widget_Curves
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_defaults.cpp b/synfig-studio/trunk/src/gtkmm/widget_defaults.cpp
new file mode 100644 (file)
index 0000000..13b6552
--- /dev/null
@@ -0,0 +1,599 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_defaults.cpp
+**     \brief Template File
+**
+**     $Id: widget_defaults.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_defaults.h"
+#include "widget_color.h"
+#include "widget_gradient.h"
+#include "dialog_color.h"
+#include "dialog_gradient.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <gtkmm/scale.h>
+#include <sinfg/exception.h>
+#include <sinfgapp/main.h>
+#include "canvasview.h"
+#include "widget_distance.h"
+#include "widget_enum.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define GRADIENT_HEIGHT                16
+#define DEFAULT_INCREMENT      (0.25)
+#define DEFAULT_WIDTH          (sinfg::Distance(3,sinfg::Distance::SYSTEM_POINTS))
+
+/* === G L O B A L S ======================================================= */
+
+class studio::Widget_Brush : public Gtk::DrawingArea
+{
+public:
+       Widget_Brush()
+       {
+               signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Brush::redraw));
+
+               set_size_request(24,24);
+               add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+               add_events(Gdk::BUTTON1_MOTION_MASK);
+
+               sinfgapp::Main::signal_foreground_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Brush::queue_draw));
+               sinfgapp::Main::signal_background_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Brush::queue_draw));
+               sinfgapp::Main::signal_bline_width_changed().connect(sigc::mem_fun(*this,&studio::Widget_Brush::queue_draw));
+               studio::App::signal_instance_selected().connect(sigc::hide(sigc::mem_fun(*this,&studio::Widget_Brush::queue_draw)));
+       }
+       
+       bool
+       redraw(GdkEventExpose*bleh)
+       {
+               Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+               
+               const int h(get_height());
+               const int w(get_width());       
+
+               float pixelsize(0);
+               if(App::get_selected_canvas_view())
+               {
+                       const RendDesc& rend_desc(App::get_selected_canvas_view()->get_canvas()->rend_desc());
+                       pixelsize=sinfgapp::Main::get_bline_width().get(Distance::SYSTEM_PIXELS,rend_desc);
+               }
+               else 
+               {
+                       RendDesc rend_desc;
+                       pixelsize=sinfgapp::Main::get_bline_width().get(Distance::SYSTEM_PIXELS,rend_desc);
+               }
+               // Fill in the background color
+               render_color_to_window(get_window(),Gdk::Rectangle(0,0,w,h),sinfgapp::Main::get_background_color());
+
+/*
+               gc->set_rgb_fg_color(colorconv_sinfg2gdk(sinfgapp::Main::get_background_color()));
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);       
+               get_window()->draw_rectangle(
+                       gc,
+                       true,   // Fill?
+                       0,0,    // x,y
+                       w,h     //w,h
+               );
+*/
+               
+               // Draw in the circle
+               gc->set_rgb_fg_color(colorconv_sinfg2gdk(sinfgapp::Main::get_foreground_color()));
+               gc->set_function(Gdk::COPY);
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+               get_window()->draw_arc(
+                       gc,
+                       true,
+                       round_to_int(((float)w/2.0f)-pixelsize/2.0f),
+                       round_to_int(((float)h/2.0f)-pixelsize/2.0f),
+                       round_to_int(pixelsize+0.6),
+                       round_to_int(pixelsize+0.6),
+                       0,
+                       360*64
+               );  
+                       
+               return true;
+       }
+
+       bool
+       on_event(GdkEvent *event)
+       {
+//             const int x(static_cast<int>(event->button.x));
+               const int y(static_cast<int>(event->button.y));
+               
+               const int h(get_height());
+//             const int w(get_width());       
+               
+               switch(event->type)
+               {
+                       case GDK_MOTION_NOTIFY:
+                               break;
+                       case GDK_BUTTON_RELEASE:
+                               if(event->button.button==1) // Left click
+                               {
+                                       Distance dist(sinfgapp::Main::get_bline_width());
+                                       
+                                       if(y<h/2) // increase BLine size
+                                       {
+                                               dist+=DEFAULT_INCREMENT;
+                                       }
+                                       else // Decrease BLine size
+                                       {
+                                               dist-=DEFAULT_INCREMENT;
+                                       }
+                                       sinfgapp::Main::set_bline_width(dist);
+                                       return true;
+                               }
+                               if(event->button.button==3)
+                               {
+                                       // right click on bline width
+                                       sinfgapp::Main::set_bline_width(DEFAULT_WIDTH);
+                                       return true;
+                               }
+                               break;
+                       case GDK_SCROLL:
+                               {
+                                       Distance dist(sinfgapp::Main::get_bline_width());
+                                       
+                                       if(event->scroll.direction==GDK_SCROLL_UP)
+                                       {
+                                               dist+=DEFAULT_INCREMENT;
+                                       }
+                                       else if(event->scroll.direction==GDK_SCROLL_DOWN)
+                                       {
+                                               dist-=DEFAULT_INCREMENT;
+                                       }
+                                       sinfgapp::Main::set_bline_width(dist);
+                                       return true;
+                               }
+                       default:
+                               break;
+               }
+               
+               return false;
+       }
+
+};
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Defaults::Widget_Defaults()
+{
+       //set_size_request(48,48+GRADIENT_HEIGHT+16);
+       //set_size_request(48,-1);
+       
+       {
+               Gtk::Table* subtable(manage(new Gtk::Table()));
+       
+               // Foreground Color
+               widget_fg_color=manage(new Widget_Color());
+               widget_fg_color->show();
+               widget_fg_color->set_size_request(16,16);
+               widget_fg_color->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Defaults::on_fg_color_clicked));
+               subtable->attach(*widget_fg_color, 0, 2, 0, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+               tooltips_.set_tip(*widget_fg_color,_("Foreground Color"));
+       
+               // Background Color
+               widget_bg_color=manage(new Widget_Color());
+               widget_bg_color->show();
+               widget_bg_color->set_size_request(16,16);
+               widget_bg_color->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Defaults::on_bg_color_clicked));
+               subtable->attach(*widget_bg_color, 1, 3, 1, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+               tooltips_.set_tip(*widget_bg_color,_("Background Color"));
+
+               Gtk::Image* icon;
+               
+               // Swap button
+               Gtk::Button* button_swap(manage(new Gtk::Button()));
+               button_swap->show();
+               button_swap->set_relief(Gtk::RELIEF_NONE);
+               button_swap->set_border_width(0);
+               icon=manage(new Gtk::Image(Gtk::StockID("sinfg-swap_colors"),Gtk::IconSize(1)));
+               icon->show();
+               button_swap->add(*icon);
+               //button_swap->get_child()->set_size_request(16/3,16/3);
+               //button_swap->set_size_request(16/3,16/3);
+               dynamic_cast<Gtk::Misc*>(button_swap->get_child())->set_padding(0,0);
+               button_swap->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Defaults::on_swap_color_clicked));
+               subtable->attach(*button_swap, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+               tooltips_.set_tip(*button_swap,_("Swap Background and\nForeground Colors"));
+
+               // Reset button
+               Gtk::Button* button_reset(manage(new Gtk::Button("R")));
+               button_reset->show();
+               button_reset->set_relief(Gtk::RELIEF_NONE);
+               button_reset->set_border_width(0);
+               dynamic_cast<Gtk::Misc*>(button_reset->get_child())->set_padding(0,0);
+               //button_reset->set_size_request(16/3,16/3);
+               button_reset->signal_clicked().connect(sigc::mem_fun(*this,&Widget_Defaults::on_reset_color_clicked));
+               subtable->attach(*button_reset, 0,1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+               tooltips_.set_tip(*button_reset,_("Reset Colors to Black and White"));
+
+               
+               attach(*subtable, 0, 1, 0, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 1, 1);
+               subtable->set_size_request(36,36);
+               subtable->set_homogeneous(true);
+               subtable->show();
+       }
+       widget_brush=manage(new Widget_Brush());
+       widget_brush->show();
+       widget_brush->set_size_request(36,36);
+       attach(*widget_brush,1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 1, 1);
+       tooltips_.set_tip(*widget_brush,_("Brush Preview"));
+
+       widget_bline_width=manage(new Widget_Distance());
+       widget_bline_width->show();
+       widget_bline_width->set_digits(2);
+       widget_bline_width->set_size_request(24,-1);
+       widget_bline_width->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::on_bline_width_changed));
+       attach(*widget_bline_width,1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       tooltips_.set_tip(*widget_bline_width,_("Brush Size"));
+
+
+       widget_blend_method=manage(new Widget_Enum());
+       widget_blend_method->show();
+       widget_blend_method->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::on_blend_method_changed));
+       widget_blend_method->set_param_desc(ParamDesc(Color::BLEND_COMPOSITE,"blend_method"));
+       attach(*widget_blend_method,0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 1, 1);
+       tooltips_.set_tip(*widget_blend_method,_("Default Blend Method"));
+
+       widget_interpolation=manage(new Widget_Enum());
+       widget_interpolation->show();
+       widget_interpolation->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::on_interpolation_changed));
+       widget_interpolation->set_param_desc(
+               ParamDesc("interpolation")
+                       .set_hint("enum")
+                       .add_enum_value(INTERPOLATION_TCB,"auto",_("TBC"))
+                       .add_enum_value(INTERPOLATION_CONSTANT,"constant",_("Constant"))
+                       .add_enum_value(INTERPOLATION_HALT,"ease",_("Ease in/out"))
+                       .add_enum_value(INTERPOLATION_LINEAR,"linear",_("Linear"))
+       );
+       attach(*widget_interpolation,0, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 1, 1);
+       tooltips_.set_tip(*widget_interpolation,_("Default Interpolation"));
+
+       widget_opacity=manage(new Gtk::HScale(0.0f,1.01f,0.01f));
+       widget_opacity->show();
+       widget_opacity->set_digits(2);
+       widget_opacity->set_value_pos(Gtk::POS_LEFT);
+       widget_opacity->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::on_opacity_changed));
+       attach(*widget_opacity,0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 1, 1);
+       tooltips_.set_tip(*widget_opacity,_("Default Opacity"));
+
+       widget_gradient=manage(new Widget_Gradient());
+       widget_gradient->show();
+       widget_gradient->set_size_request(-1,GRADIENT_HEIGHT);
+       widget_gradient->signal_clicked().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::on_gradient_clicked));
+       attach(*widget_gradient,0, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 1, 1);
+       tooltips_.set_tip(*widget_gradient,_("Default Gradient"));
+
+
+       // Signals
+       sinfgapp::Main::signal_opacity_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::opacity_refresh));
+       sinfgapp::Main::signal_bline_width_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::bline_width_refresh));
+       sinfgapp::Main::signal_foreground_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::fg_color_refresh));
+       sinfgapp::Main::signal_background_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::bg_color_refresh));
+       sinfgapp::Main::signal_gradient_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::gradient_refresh));
+       sinfgapp::Main::signal_blend_method_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::blend_method_refresh));
+       sinfgapp::Main::signal_interpolation_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::interpolation_refresh));
+
+       fg_color_refresh();
+       bg_color_refresh();
+       gradient_refresh();
+       bline_width_refresh();
+       blend_method_refresh();
+       opacity_refresh();
+       interpolation_refresh();
+/*
+       set_size_request(48,48+GRADIENT_HEIGHT);
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Defaults::redraw));
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+
+       sinfgapp::Main::signal_foreground_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::queue_draw));
+       sinfgapp::Main::signal_background_color_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::queue_draw));
+       sinfgapp::Main::signal_gradient_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::queue_draw));
+       sinfgapp::Main::signal_bline_width_changed().connect(sigc::mem_fun(*this,&studio::Widget_Defaults::queue_draw));
+
+       if(App::dialog_gradient)
+       {
+               App::dialog_gradient->set_gradient(sinfgapp::Main::get_gradient());
+               App::dialog_gradient->reset();
+               App::dialog_gradient->signal_edited().connect(sigc::mem_fun(sinfgapp::Main::set_gradient));
+       }
+       
+       if(App::dialog_color)
+       {
+               App::dialog_color->set_color(sinfgapp::Main::get_foreground_color());
+               App::dialog_color->reset();
+               App::dialog_color->signal_edited().connect(sigc::mem_fun(sinfgapp::Main::set_foreground_color));
+       }
+*/
+}
+       
+Widget_Defaults::~Widget_Defaults()
+{
+}
+
+void
+Widget_Defaults::fg_color_refresh()
+{
+       widget_fg_color->set_value(sinfgapp::Main::get_foreground_color());
+}
+
+void
+Widget_Defaults::bg_color_refresh()
+{
+       widget_bg_color->set_value(sinfgapp::Main::get_background_color());
+}
+
+void
+Widget_Defaults::gradient_refresh()
+{
+       widget_gradient->set_value(sinfgapp::Main::get_gradient());
+}
+
+void
+Widget_Defaults::bline_width_refresh()
+{
+       widget_bline_width->set_value(sinfgapp::Main::get_bline_width());
+}
+
+void
+Widget_Defaults::blend_method_refresh()
+{
+       widget_blend_method->set_value(sinfgapp::Main::get_blend_method());
+}
+
+void
+Widget_Defaults::interpolation_refresh()
+{
+       widget_interpolation->set_value(sinfgapp::Main::get_interpolation());
+}
+
+void
+Widget_Defaults::opacity_refresh()
+{
+       widget_opacity->set_value(sinfgapp::Main::get_opacity());
+}
+
+void
+Widget_Defaults::on_opacity_changed()
+{
+       sinfgapp::Main::set_opacity(widget_opacity->get_value());
+}
+
+void
+Widget_Defaults::on_blend_method_changed()
+{
+       sinfgapp::Main::set_blend_method(Color::BlendMethod(widget_blend_method->get_value()));
+}
+
+void
+Widget_Defaults::on_interpolation_changed()
+{
+       sinfgapp::Main::set_interpolation(Waypoint::Interpolation(widget_interpolation->get_value()));
+}
+
+void
+Widget_Defaults::on_bline_width_changed()
+{
+       sinfgapp::Main::set_bline_width(widget_bline_width->get_value());
+}
+
+void
+Widget_Defaults::on_fg_color_clicked()
+{
+       // Left click on foreground
+       App::dialog_color->set_color(sinfgapp::Main::get_foreground_color());
+       App::dialog_color->reset();
+       App::dialog_color->signal_edited().connect(sigc::ptr_fun(sinfgapp::Main::set_foreground_color));
+       App::dialog_color->present();
+}
+
+void
+Widget_Defaults::on_bg_color_clicked()
+{
+       // Left click on background
+       App::dialog_color->set_color(sinfgapp::Main::get_background_color());
+       App::dialog_color->reset();
+       App::dialog_color->signal_edited().connect(sigc::ptr_fun(sinfgapp::Main::set_background_color));
+       App::dialog_color->present();
+}
+
+void
+Widget_Defaults::on_swap_color_clicked()
+{
+       sinfgapp::Main::color_swap();
+}
+
+void
+Widget_Defaults::on_reset_color_clicked()
+{
+       sinfgapp::Main::set_background_color(Color::white());
+       sinfgapp::Main::set_foreground_color(Color::black());
+}
+
+void
+Widget_Defaults::on_gradient_clicked()
+{
+       App::dialog_gradient->set_gradient(sinfgapp::Main::get_gradient());
+       App::dialog_gradient->reset();
+       App::dialog_gradient->signal_edited().connect(sigc::ptr_fun(sinfgapp::Main::set_gradient));
+       App::dialog_gradient->present();
+}
+
+/*
+bool
+Widget_Defaults::redraw(GdkEventExpose*bleh)
+{
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+
+       const int h(get_height());
+       const int w(get_width());       
+       const int size=std::min(h-GRADIENT_HEIGHT,w);
+       
+       render_color_to_window(get_window(),Gdk::Rectangle(size/4,size/4,size/4*3-1,size/4*3-1),sinfgapp::Main::get_background_color());
+       render_color_to_window(get_window(),Gdk::Rectangle(0,0,size/4*3-1,size/4*3-1),sinfgapp::Main::get_foreground_color());
+       render_gradient_to_window(get_window(),Gdk::Rectangle(0,h-GRADIENT_HEIGHT,w,GRADIENT_HEIGHT-1),sinfgapp::Main::get_gradient());
+
+       
+
+
+
+       Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_pango_context()));
+       
+       gc->set_rgb_fg_color(Gdk::Color("#FF0000"));
+       layout->set_text(sinfgapp::Main::get_bline_width().get_string(2));              
+       layout->set_alignment(Pango::ALIGN_CENTER);
+       layout->set_width(w/2);
+       get_window()->draw_layout(gc, w*3/4, (h-GRADIENT_HEIGHT)-16, layout);
+
+       return true;
+}
+
+bool
+Widget_Defaults::on_event(GdkEvent *event)
+{
+       const int x(static_cast<int>(event->button.x));
+       const int y(static_cast<int>(event->button.y));
+
+       const int h(get_height());
+       const int w(get_width());       
+       const int size=std::min(h-GRADIENT_HEIGHT,w);
+
+       switch(event->type)
+       {
+       case GDK_MOTION_NOTIFY:
+               break;
+       case GDK_BUTTON_PRESS:
+//                     if(event->button.button==1 && y>get_height()-CONTROL_HEIGHT)
+               break;
+       case GDK_BUTTON_RELEASE:
+               if(event->button.button==1)
+               {
+                       if(y>size)
+                       {
+                               // Left click on gradient
+                               App::dialog_gradient->set_gradient(sinfgapp::Main::get_gradient());
+                               App::dialog_gradient->reset();
+                               App::dialog_gradient->signal_edited().connect(sigc::mem_fun(sinfgapp::Main::set_gradient));
+                               App::dialog_gradient->present();
+                               return true;
+                       }
+                       if(x>0 && x<=size)
+                       {
+                               if(x<size*3/4 && y<size*3/4)
+                               {
+                                       // Left click on foreground
+                                       App::dialog_color->set_color(sinfgapp::Main::get_foreground_color());
+                                       App::dialog_color->reset();
+                                       App::dialog_color->signal_edited().connect(sigc::mem_fun(sinfgapp::Main::set_foreground_color));
+                                       App::dialog_color->present();
+                                       return true;
+                               }
+                               if(x>size*3/4 && y>size/4)
+                               {
+                                       // Left click on background
+                                       App::dialog_color->set_color(sinfgapp::Main::get_background_color());
+                                       App::dialog_color->reset();
+                                       App::dialog_color->signal_edited().connect(sigc::mem_fun(sinfgapp::Main::set_background_color));
+                                       App::dialog_color->present();
+                                       return true;
+                               }
+                       }
+                       if(x>size) // Left click on BLine Width
+                       {
+                               Distance dist(sinfgapp::Main::get_bline_width());
+                               
+                               if(y<size/2) // increase BLine size
+                               {
+                                       dist+=DEFAULT_INCREMENT;
+                               }
+                               else // Decrease BLine size
+                               {
+                                       dist-=DEFAULT_INCREMENT;
+                               }
+                               sinfgapp::Main::set_bline_width(dist);
+                       }
+               }
+               if(event->button.button==3)
+               {
+                       if(y>size)
+                       {
+                               // right click on gradient
+                               sinfgapp::Main::set_gradient_default_colors();
+                               return true;
+                       }
+                       else
+                       {
+                               if(x<size)
+                               {
+                                       // right click on colors
+                                       sinfgapp::Main::color_swap();
+                                       return true;
+                               }
+                               
+                               if(x>w/2)
+                               {
+                                       // right click on bline width
+                                       sinfgapp::Main::set_bline_width(DEFAULT_WIDTH);
+                               }
+                               
+                       }
+               }
+               break;
+       case GDK_SCROLL:
+               {
+                       Distance dist(sinfgapp::Main::get_bline_width());
+                       
+                       if(event->scroll.direction==GDK_SCROLL_UP)
+                       {
+                               dist+=DEFAULT_INCREMENT;
+                       }
+                       else if(event->scroll.direction==GDK_SCROLL_DOWN)
+                       {
+                               dist-=DEFAULT_INCREMENT;
+                       }
+                       sinfgapp::Main::set_bline_width(dist);
+               }
+       default:
+               break;
+       }
+       
+       return false;
+}
+*/
diff --git a/synfig-studio/trunk/src/gtkmm/widget_defaults.h b/synfig-studio/trunk/src/gtkmm/widget_defaults.h
new file mode 100644 (file)
index 0000000..6bd54b4
--- /dev/null
@@ -0,0 +1,98 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_defaults.h
+**     \brief Template Header
+**
+**     $Id: widget_defaults.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_DEFAULTS_H
+#define __SINFG_STUDIO_WIDGET_DEFAULTS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/table.h>
+#include <sinfg/gradient.h>
+#include "widget_gradient.h"
+#include <gtkmm/tooltips.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class HScale; }
+
+namespace studio {
+
+class Widget_Brush;
+class Widget_Color;
+class Widget_Distance;
+class Widget_Enum;
+       
+class Widget_Defaults : public Gtk::Table
+{
+       Widget_Brush *widget_brush;
+       Widget_Color *widget_fg_color;
+       Widget_Color *widget_bg_color;
+       Widget_Distance *widget_bline_width;
+       Widget_Gradient *widget_gradient;
+       Widget_Enum     *widget_blend_method;
+       Widget_Enum     *widget_interpolation;
+       Gtk::HScale *widget_opacity;
+       
+       void fg_color_refresh();
+       void bg_color_refresh();
+       void gradient_refresh();
+       void bline_width_refresh();
+       void interpolation_refresh();
+       
+       void on_bline_width_changed();
+       void on_fg_color_clicked();
+       void on_bg_color_clicked();
+       void on_swap_color_clicked();
+       void on_reset_color_clicked();
+       void on_gradient_clicked();
+       void on_interpolation_changed();
+
+       void blend_method_refresh();
+       void on_blend_method_changed();
+
+       void opacity_refresh();
+       void on_opacity_changed();
+
+       Gtk::Tooltips tooltips_;
+       
+public:
+       
+       Widget_Defaults();
+       
+       ~Widget_Defaults();
+
+//     bool redraw(GdkEventExpose*bleh=NULL);
+
+//     bool on_event(GdkEvent *event);
+}; // END of class BlackLevelSelector
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_distance.cpp b/synfig-studio/trunk/src/gtkmm/widget_distance.cpp
new file mode 100644 (file)
index 0000000..0e81829
--- /dev/null
@@ -0,0 +1,100 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_time.cpp
+**     \brief Template File
+**
+**     $Id: widget_distance.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include "widget_distance.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Distance::Widget_Distance():
+       Gtk::SpinButton(0.05,5),
+       adjustment(0,-100000000,100000000,1,1,1)
+//     adjustment(0,-100000000,100000000,1,2,0)
+{
+       set_adjustment(adjustment);
+       set_numeric(false);
+}
+
+Widget_Distance::~Widget_Distance()
+{
+}
+
+int
+Widget_Distance::on_input(double* new_value)
+{
+       distance_=sinfg::String(get_text());
+       *new_value=distance_.get();
+       return 1;
+}
+
+bool
+Widget_Distance::on_output()
+{
+       try{
+       distance_=get_adjustment()->get_value();
+       set_text(distance_.get_string(get_digits()));
+       } catch (...) { /* sinfg::error("Widget_Distance::on_output(): Caught something..."); */ }
+       return true;
+}
+
+void
+Widget_Distance::set_value(const sinfg::Distance &data)
+{
+       distance_=data;
+       get_adjustment()->set_value(distance_.get());
+}
+
+sinfg::Distance
+Widget_Distance::get_value() const
+{
+       distance_=get_adjustment()->get_value();
+       return distance_;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_distance.h b/synfig-studio/trunk/src/gtkmm/widget_distance.h
new file mode 100644 (file)
index 0000000..61d6c82
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_distance.h
+**     \brief Template Header
+**
+**     $Id: widget_distance.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_DISTANCE_H
+#define __SINFG_STUDIO_WIDGET_DISTANCE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/signal.h>
+#include <sigc++/slot.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/adjustment.h>
+#include <sinfg/distance.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Entry; class Button; };
+
+namespace studio {
+
+class Widget_Distance : public Gtk::SpinButton
+{
+       //sigc::signal<void> signal_value_changed_;
+       
+       mutable sinfg::Distance distance_;
+
+       Gtk::Adjustment adjustment;
+       
+protected:
+       
+       int     on_input(double* new_value);
+       bool on_output();
+
+public:
+       //sigc::signal<void> &signal_value_changed() { return signal_value_changed_; }
+       
+       void set_value(const sinfg::Distance &data);
+       sinfg::Distance get_value()const;
+       Widget_Distance();
+       ~Widget_Distance();
+}; // END of class Widget_Distance
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_enum.cpp b/synfig-studio/trunk/src/gtkmm/widget_enum.cpp
new file mode 100644 (file)
index 0000000..9d346fd
--- /dev/null
@@ -0,0 +1,112 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_enum.cpp
+**     \brief Template File
+**
+**     $Id: widget_enum.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/menu.h>
+#include "widget_enum.h"
+#include <ETL/stringf>
+#include <sinfg/valuenode.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Enum::Widget_Enum()
+{
+}
+
+Widget_Enum::~Widget_Enum()
+{
+}
+
+void
+Widget_Enum::set_param_desc(const sinfg::ParamDesc &x)
+{
+       param_desc=x;
+       //refresh();
+}
+
+void
+Widget_Enum::set_value_(int data)
+{
+       set_value(data);
+       activate();
+}
+
+void
+Widget_Enum::refresh()
+{
+       enum_menu = manage(new class Gtk::Menu());
+
+       std::list<sinfg::ParamDesc::EnumData> enum_list=param_desc.get_enum_list();
+       std::list<sinfg::ParamDesc::EnumData>::iterator iter;
+       
+       String name=strprintf("(%d)",value);
+       
+       for(iter=enum_list.begin();iter!=enum_list.end();iter++)
+               if(iter->value!=value)
+                       enum_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->local_name,
+                               sigc::bind(sigc::mem_fun(*this,&Widget_Enum::set_value_),iter->value)
+                       ));
+               else
+                       name=iter->local_name;
+
+       enum_menu->items().push_front(Gtk::Menu_Helpers::MenuElem(name));
+               
+       set_menu(*enum_menu);   
+}
+
+void
+Widget_Enum::set_value(int data)
+{
+       value=data;
+       
+       refresh();
+       
+       set_history(0);
+}
+
+int
+Widget_Enum::get_value() const
+{
+       return value;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_enum.h b/synfig-studio/trunk/src/gtkmm/widget_enum.h
new file mode 100644 (file)
index 0000000..17576e9
--- /dev/null
@@ -0,0 +1,66 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_enum.h
+**     \brief Template Header
+**
+**     $Id: widget_enum.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_ENUM_H
+#define __SINFG_STUDIO_WIDGET_ENUM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <gtkmm/optionmenu.h>
+#include <sinfg/paramdesc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Menu; };
+
+namespace studio {
+
+class Widget_Enum : public Gtk::OptionMenu
+{
+       Gtk::Menu *enum_menu;
+       sinfg::ParamDesc param_desc;
+       
+       int value;
+       void set_value_(int data);
+public:
+
+       Widget_Enum();
+       ~Widget_Enum();
+       
+       void set_param_desc(const sinfg::ParamDesc &x);
+       void refresh();
+
+       void set_value(int data);
+       int get_value() const;
+}; // END of class Widget_Enum
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_filename.cpp b/synfig-studio/trunk/src/gtkmm/widget_filename.cpp
new file mode 100644 (file)
index 0000000..25da8a3
--- /dev/null
@@ -0,0 +1,116 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_filename.cpp
+**     \brief Template File
+**
+**     $Id: widget_filename.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include "widget_filename.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+//using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Filename::Widget_Filename()
+{
+       entry_filename=manage(new Gtk::Entry());
+       button_choose=manage(new Gtk::Button(_("Find")));
+
+       pack_start(*entry_filename);
+       pack_start(*button_choose);
+       entry_filename->show();
+       button_choose->show();
+
+       button_choose->signal_clicked().connect(sigc::mem_fun(*this, &studio::Widget_Filename::on_button_choose_pressed));
+       //entry_filename->signal_value_changed().connect(sigc::mem_fun(*this, &studio::Widget_Filename::on_value_changed));
+       entry_filename->signal_activate().connect(sigc::mem_fun(*this, &studio::Widget_Filename::on_value_changed));
+}
+
+Widget_Filename::~Widget_Filename()
+{
+}
+
+void
+Widget_Filename::set_has_frame(bool x)
+{
+       entry_filename->set_has_frame(x);
+}
+
+
+void
+Widget_Filename::set_value(const string &data)
+{
+       entry_filename->set_text(data);
+}
+
+string
+Widget_Filename::get_value() const
+{
+       try
+       {
+               return entry_filename->get_text();
+       }
+       catch(...)
+       {
+               throw string("Caught unknown exception");
+       }
+}
+
+void
+Widget_Filename::on_value_changed()
+{
+       signal_value_changed()();
+}
+
+void
+Widget_Filename::on_button_choose_pressed()
+{
+       string filename=entry_filename->get_text();
+       if(filename.empty())
+               filename=".";
+       if(App::dialog_open_file(_("Choose File"),filename))
+               entry_filename->set_text(filename);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_filename.h b/synfig-studio/trunk/src/gtkmm/widget_filename.h
new file mode 100644 (file)
index 0000000..cb906cf
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_filename.h
+**     \brief Template Header
+**
+**     $Id: widget_filename.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_FILENAME_H
+#define __SINFG_STUDIO_WIDGET_FILENAME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/signal.h>
+#include <sigc++/slot.h>
+#include <gtkmm/box.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Entry; class Button; };
+
+namespace studio {
+
+class Widget_Filename : public Gtk::HBox
+{
+       Gtk::Entry *entry_filename;
+       Gtk::Button *button_choose;
+
+       void on_button_choose_pressed();
+
+       sigc::signal<void> signal_value_changed_;
+
+public:
+       sigc::signal<void> &signal_value_changed() { return signal_value_changed_; }
+       Glib::SignalProxy0<void> signal_activate() { return entry_filename->signal_activate(); }
+
+       void on_value_changed();
+       
+       void set_value(const  std::string &data);
+       std::string get_value() const;
+       void set_has_frame(bool x);
+       Widget_Filename();
+       ~Widget_Filename();
+}; // END of class Widget_Filename
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_gradient.cpp b/synfig-studio/trunk/src/gtkmm/widget_gradient.cpp
new file mode 100644 (file)
index 0000000..da07589
--- /dev/null
@@ -0,0 +1,363 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_gradient.cpp
+**     \brief Template File
+**
+**     $Id: widget_gradient.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_gradient.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <sinfg/exception.h>
+#include <ETL/misc>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+void
+studio::render_gradient_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::Gradient &gradient)
+{
+       int     height = ca.get_height();
+       int     width = ca.get_width()-4;
+
+       float sample_width(1.0f/(float)width);
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
+       const Color bg1(0.25, 0.25, 0.25);
+       const Color bg2(0.5, 0.5, 0.5);
+       Gdk::Color gdk_c;
+       int i;
+       for(i=0;i<width;i++)
+       {
+               const Color c(gradient(float(i)/float(width),sample_width));
+               const Color c1(Color::blend(c,bg1,1.0).clamped());
+               const Color c2(Color::blend(c,bg2,1.0).clamped());
+               gushort r1(256*App::gamma.r_F32_to_U8(c1.get_r()));
+               gushort g1(256*App::gamma.g_F32_to_U8(c1.get_g()));
+               gushort b1(256*App::gamma.b_F32_to_U8(c1.get_b()));
+               gushort r2(256*App::gamma.r_F32_to_U8(c2.get_r()));
+               gushort g2(256*App::gamma.g_F32_to_U8(c2.get_g()));
+               gushort b2(256*App::gamma.b_F32_to_U8(c2.get_b()));
+                               
+               if((i*2/height)&1)
+               {
+                       gdk_c.set_rgb(r1,g1,b1);
+                       gc->set_rgb_fg_color(gdk_c);
+                       window->draw_rectangle(gc, true, ca.get_x()+i+2, ca.get_y(), 1, height/2);                              
+       
+                       gdk_c.set_rgb(r2,g2,b2);
+                       gc->set_rgb_fg_color(gdk_c);
+                       window->draw_rectangle(gc, true, ca.get_x()+i+2, ca.get_y()+height/2, 1, height/2);
+               }
+               else
+               {
+                       gdk_c.set_rgb(r2,g2,b2);
+                       gc->set_rgb_fg_color(gdk_c);
+                       window->draw_rectangle(gc, true, ca.get_x()+i+2, ca.get_y(), 1, height/2);                              
+       
+                       gdk_c.set_rgb(r1,g1,b1);
+                       gc->set_rgb_fg_color(gdk_c);
+                       window->draw_rectangle(gc, true, ca.get_x()+i+2, ca.get_y()+height/2, 1, height/2);
+               }
+       }
+       gc->set_rgb_fg_color(Gdk::Color("#ffffff"));
+       window->draw_rectangle(gc, false, ca.get_x()+1, ca.get_y()+1, ca.get_width()-3, height-3);
+       gc->set_rgb_fg_color(Gdk::Color("#000000"));
+       window->draw_rectangle(gc, false, ca.get_x(), ca.get_y(), ca.get_width()-1, height-1);
+}
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Gradient::Widget_Gradient():
+       editable_(false)
+{
+       set_size_request(-1,64);
+       signal_expose_event().connect(sigc::mem_fun(*this, &studio::Widget_Gradient::redraw));
+       add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       add_events(Gdk::BUTTON1_MOTION_MASK);
+
+}
+       
+Widget_Gradient::~Widget_Gradient()
+{
+}
+
+#define CONTROL_HEIGHT         16
+bool
+Widget_Gradient::redraw(GdkEventExpose*bleh)
+{
+       const int h(get_height());
+       const int w(get_width());
+       
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(get_window()));
+       Gdk::Rectangle area(0,0,w,h);
+       if(!editable_)
+       {
+               render_gradient_to_window(get_window(),area,gradient_);
+               return true;
+       }
+
+       render_gradient_to_window(get_window(),Gdk::Rectangle(0,0,w,h-CONTROL_HEIGHT),gradient_);
+
+       gc->set_rgb_fg_color(Gdk::Color("#7f7f7f"));
+       get_window()->draw_rectangle(gc, false, 0, h-CONTROL_HEIGHT, w, CONTROL_HEIGHT);
+
+       Gradient::iterator iter,selected_iter;
+       bool show_selected(false);
+       for(iter=gradient_.begin();iter!=gradient_.end();iter++)
+       {
+               if(*iter!=selected_cpoint)
+               get_style()->paint_arrow(
+                       get_window(),
+                       (*iter==selected_cpoint)?Gtk::STATE_SELECTED:Gtk::STATE_ACTIVE,
+                       Gtk::SHADOW_OUT,
+                       area,
+                       *this,
+                       " ",
+                       Gtk::ARROW_UP,
+                       1,
+                       int(iter->pos*w)-CONTROL_HEIGHT/2+1,
+                       h-CONTROL_HEIGHT,
+                       CONTROL_HEIGHT,
+                       CONTROL_HEIGHT
+               );
+               else
+               {
+                       selected_iter=iter;
+                       show_selected=true;
+               }
+       }
+       
+       // we do this so that we can be sure that
+       // the selected marker is shown on top
+       if(show_selected)
+       {
+               get_style()->paint_arrow(
+                       get_window(),
+                       Gtk::STATE_SELECTED,
+                       Gtk::SHADOW_OUT,
+                       area,
+                       *this,
+                       " ",
+                       Gtk::ARROW_UP,
+                       1,
+                       round_to_int(selected_iter->pos*w)-CONTROL_HEIGHT/2+1,
+                       h-CONTROL_HEIGHT,
+                       CONTROL_HEIGHT,
+                       CONTROL_HEIGHT
+               );
+       }
+       
+       return true;
+}
+
+void
+Widget_Gradient::insert_cpoint(float x)
+{
+       Gradient::CPoint new_cpoint;
+       new_cpoint.pos=x;
+       new_cpoint.color=gradient_(x);
+       gradient_.push_back(new_cpoint);
+       gradient_.sort();
+       gradient_.sort();
+       set_selected_cpoint(new_cpoint);
+       queue_draw();
+}
+
+void
+Widget_Gradient::remove_cpoint(float x)
+{
+       gradient_.erase(gradient_.proximity(x));
+       queue_draw();
+}
+
+void
+Widget_Gradient::popup_menu(float x)
+{
+       Gtk::Menu* menu(manage(new Gtk::Menu()));
+       
+       menu->items().clear();
+
+       menu->items().push_back(
+               Gtk::Menu_Helpers::MenuElem(
+                       _("Insert CPoint"),
+                       sigc::bind(
+                               sigc::mem_fun(*this,&studio::Widget_Gradient::insert_cpoint),
+                               x
+                       )
+               )
+       );
+
+       if(!gradient_.empty())
+       {
+               menu->items().push_back(
+                       Gtk::Menu_Helpers::MenuElem(
+                               _("Remove CPoint"),
+                               sigc::bind(
+                                       sigc::mem_fun(*this,&studio::Widget_Gradient::remove_cpoint),
+                                       x
+                               )
+                       )
+               );
+       }
+       
+       menu->popup(0,0);
+}
+
+void
+Widget_Gradient::set_value(const sinfg::Gradient& x)
+{
+       gradient_=x;
+       if(gradient_.size())
+               set_selected_cpoint(*gradient_.proximity(0.0f));
+       queue_draw();
+}
+
+void
+Widget_Gradient::set_selected_cpoint(const sinfg::Gradient::CPoint &x)
+{
+       selected_cpoint=x;
+       signal_cpoint_selected_(selected_cpoint);
+       queue_draw();
+}
+
+void
+Widget_Gradient::update_cpoint(const sinfg::Gradient::CPoint &x)
+{
+       try
+       {
+               Gradient::iterator iter(gradient_.find(x));
+               iter->pos=x.pos;
+               iter->color=x.color;
+               gradient_.sort();
+               queue_draw();
+       }
+       catch(sinfg::Exception::NotFound)
+       {
+               // Yotta...
+       }
+}
+
+bool
+Widget_Gradient::on_event(GdkEvent *event)
+{
+       //if(editable_)
+       {
+               const int x(static_cast<int>(event->button.x));
+               const int y(static_cast<int>(event->button.y));
+
+               float pos((float)x/(float)get_width());
+               if(pos<0.0f)pos=0.0f;
+               if(pos>1.0f)pos=1.0f;
+       
+               switch(event->type)
+               {
+               case GDK_MOTION_NOTIFY:
+                       if(editable_ && y>get_height()-CONTROL_HEIGHT)
+                       {
+                               Gradient::iterator iter(gradient_.find(selected_cpoint));
+                               
+                               if(event->button.state&GDK_SHIFT_MASK)
+                               {
+                                       float begin(-100000000),end(100000000);
+                                       Gradient::iterator before(iter),after(iter);
+                                       after++;
+                                       if(iter!=gradient_.begin())
+                                       {
+                                               before--;
+                                               begin=before->pos;
+                                       }
+                                       if(after!=gradient_.end())
+                                       {
+                                               end=after->pos;
+                                       }
+                                       
+                                       if(pos>end)
+                                               pos=end;
+                                       if(pos<begin)
+                                               pos=begin;
+                                       
+                                       iter->pos=pos;                                  
+                               }
+                               else
+                               {
+                                       iter->pos=pos;
+                                       gradient_.sort();
+                               }
+                               
+//                             signal_value_changed_();
+                               changed_=true;
+                               queue_draw();
+                               return true;
+                       }
+                       break;
+               case GDK_BUTTON_PRESS:
+                       changed_=false;
+                       if(event->button.button==1)
+                       {
+                               if(editable_ && y>get_height()-CONTROL_HEIGHT)
+                               {
+                                       set_selected_cpoint(*gradient_.proximity(pos));
+                                       queue_draw();
+                                       return true;
+                               }
+                               else
+                               {
+                                       signal_clicked_();
+                                       return true;
+                               }
+                       }
+                       else if(editable_ && event->button.button==3)
+                       {
+                               popup_menu(pos);
+                               return true;
+                       }
+                       break;
+               case GDK_BUTTON_RELEASE:
+                       if(editable_ && event->button.button==1 && y>get_height()-CONTROL_HEIGHT)
+                       {
+                               set_selected_cpoint(*gradient_.proximity(pos));
+                               if(changed_)signal_value_changed_();
+                               return true;
+                       }
+               default:
+                       break;
+               }
+       }
+       
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_gradient.h b/synfig-studio/trunk/src/gtkmm/widget_gradient.h
new file mode 100644 (file)
index 0000000..baea381
--- /dev/null
@@ -0,0 +1,101 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_gradient.h
+**     \brief Template Header
+**
+**     $Id: widget_gradient.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_GRADIENT_H
+#define __SINFG_STUDIO_WIDGET_GRADIENT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/drawingarea.h>
+#include <sinfg/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+void render_gradient_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::Gradient &gradient);
+
+class Widget_Gradient : public Gtk::DrawingArea
+{
+       sigc::signal<void> signal_value_changed_;
+       sigc::signal<void> signal_clicked_;
+
+       sigc::signal<void,sinfg::Gradient::CPoint> signal_cpoint_selected_;
+
+       sinfg::Gradient gradient_;
+       
+       bool editable_;
+       
+       bool changed_;
+       
+       sinfg::Gradient::CPoint selected_cpoint;
+
+       void popup_menu(float x);       
+
+       void insert_cpoint(float x);    
+
+       void remove_cpoint(float x);    
+               
+public:
+       
+       Widget_Gradient();
+       
+       ~Widget_Gradient();
+
+       sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+       sigc::signal<void>& signal_clicked() { return signal_clicked_; }
+
+       sigc::signal<void,sinfg::Gradient::CPoint>& signal_cpoint_selected() { return signal_cpoint_selected_; }
+       
+       void set_value(const sinfg::Gradient& x);
+
+       const sinfg::Gradient& get_value()const { return gradient_; }   
+       
+       void set_editable(bool x=true) { editable_=x; }
+       
+       bool get_editable()const { return editable_; }
+
+
+       
+       void set_selected_cpoint(const sinfg::Gradient::CPoint &x);
+
+       const sinfg::Gradient::CPoint& get_selected_cpoint() { return selected_cpoint; }
+
+       void update_cpoint(const sinfg::Gradient::CPoint &x);
+       
+
+
+       bool redraw(GdkEventExpose*bleh=NULL);
+
+       bool on_event(GdkEvent *event);
+}; // END of class BlackLevelSelector
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_sound.cpp b/synfig-studio/trunk/src/gtkmm/widget_sound.cpp
new file mode 100644 (file)
index 0000000..c19780d
--- /dev/null
@@ -0,0 +1,320 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_sound.cpp
+**     \brief Widget Sound Implementation File
+**
+**     $Id: widget_sound.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/adjustment.h>
+
+#include <sinfg/general.h>
+#include <ETL/clock>
+
+#include "widget_sound.h"
+#include "audiocontainer.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+//using namespace sinfg;
+
+using studio::AudioProfile;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+       
+studio::Widget_Sound::Widget_Sound()
+{
+}
+
+studio::Widget_Sound::~Widget_Sound()
+{
+}
+
+void studio::Widget_Sound::set_position(double t)
+{
+       //sinfg::info("Setting position to %.2lf s", t);
+       if(adj_timescale && t != adj_timescale->get_value())
+       {
+               float upper = adj_timescale->get_upper();
+               float lower = adj_timescale->get_lower();
+               float framesize =  upper - lower;
+               
+               if(t < lower)
+               {
+                       lower -= ceil((lower-t)/framesize)*framesize;
+                       upper = lower + framesize;
+                       adj_timescale->set_lower(lower); adj_timescale->set_upper(upper);
+                       adj_timescale->set_value(t);
+                       adj_timescale->changed(); adj_timescale->value_changed(); 
+               }else
+               if(t > upper)
+               {
+                       lower += ceil((t-upper)/framesize)*framesize;
+                       upper = lower + framesize;
+                       adj_timescale->set_lower(lower); adj_timescale->set_upper(upper);
+                       adj_timescale->set_value(t);
+                       adj_timescale->changed(); adj_timescale->value_changed();
+               }else
+               {
+                       adj_timescale->set_value(t);
+                       adj_timescale->value_changed();
+               }
+       }
+}
+
+double studio::Widget_Sound::get_position() const
+{
+       if(adj_timescale)
+       {
+               return adj_timescale->get_value();
+       }
+       return 0;
+}
+
+bool studio::Widget_Sound::set_profile(etl::handle<AudioProfile>       p)
+{
+       clear();
+
+       //set the profile
+       audioprof = p;
+       
+       if(!audioprof)
+       {
+               clear();
+               return false;
+       }
+       
+       return true;
+}
+
+etl::handle<AudioProfile>      studio::Widget_Sound::get_profile() const
+{
+       return audioprof;
+}
+
+void studio::Widget_Sound::clear()
+{
+       audioprof.detach();
+}
+
+void studio::Widget_Sound::draw()
+{
+       on_expose_event();
+}
+
+bool studio::Widget_Sound::on_expose_event(GdkEventExpose *heh)
+{      
+       if(!get_window()) return false; 
+
+       //clear the background to dark grey
+       Glib::RefPtr<Gdk::GC>   gc = Gdk::GC::create(get_window());
+       
+       if(!gc) return false;
+
+       {
+               Gdk::Rectangle r(0,0,get_width(),get_height());
+               get_window()->begin_paint_rect(r);
+       }
+       Gdk::Color      c("#3f3f3f");   
+       gc->set_rgb_fg_color(c);
+       gc->set_background(c);
+
+       int w = get_width();
+       int baseline = get_height()/2;
+       get_window()->draw_rectangle(gc,true,0,0,w,get_height());
+       
+       //set up the color to be blue
+       c.set_rgb_p(0,0.5,1);
+       gc->set_rgb_fg_color(c);
+       
+       //draw the base line
+       get_window()->draw_line(gc,0,baseline,w,baseline);
+       
+       //redraw all the samples from begin to end, but only if we have samples to draw (or there is no space to draw)
+       
+       //sinfg::warning("Ok rendered everything, now must render actual sound wave");
+       if(!audioprof || !adj_timescale || !w) 
+       {
+               get_window()->end_paint();
+               return true;
+       }
+       
+       //draw you fool!
+       float framesize = adj_timescale->get_upper() - adj_timescale->get_lower();
+       if(framesize)
+       {
+               float delta=0,cum=0;
+               
+               //position in sample space
+               int begin=0,end=0;
+               int     cur=0,maxs=0,mins=0;
+               
+               int       i=0; //pixel counter
+               
+               //etl::clock    check; check.reset();
+               
+               float position = adj_timescale->get_value();
+               float samplerate = audioprof->get_samplerate();
+               int             posi = 0;               
+               //enforce position inside of frame size 
+               {
+                       float offset = audioprof->get_offset();
+               
+                       //clamp begin and end to framesize
+                       float beginf = adj_timescale->get_lower();
+                       float endf = adj_timescale->get_upper();
+                       
+                       posi = round_to_int((position-beginf)*w/framesize);
+                       //posi = (int)((position-beginf)*w/framesize);
+                       
+                       //calculate in sample space from seconds
+                       begin = round_to_int((beginf - offset)*samplerate);
+                       end = round_to_int((endf - offset)*samplerate);
+                       //begin = (int)((beginf - offset)*samplerate);
+                       //end = (int)((endf - offset)*samplerate);
+               }
+               
+               delta = (end - begin)/(float)w; //samples per pixel
+               
+               /*sinfg::warning("Rendering a framesize of %f secs from [%d,%d) samples to %d samples, took %f sec", 
+                                               framesize, begin, end, w, check());*/
+               
+               cur = begin;
+               i = 0; cum = 0;
+               for(int i=0;i<w;++i)
+               {
+                       //get the maximum of the collected samples
+                       maxs = 0;
+                       mins = 0;
+                       for(;cum < delta; ++cum, ++cur)
+                       {
+                               maxs = std::max(maxs,(int)(*audioprof)[cur]);
+                               mins = std::min(mins,(int)(*audioprof)[cur]);
+                       }
+                       cum -= delta;
+                       
+                       //draw spike if not needed be
+                       if(maxs||mins)
+                       {
+                               int top = maxs * baseline / 64;
+                               int bot = mins * baseline / 64;
+                               
+                               get_window()->draw_line(gc,i,baseline+bot,i,baseline+top);
+                       }
+               }
+               
+               //sinfg::warning("Drawing audio line");
+               c.set_rgb_p(1,0,0);
+               gc->set_rgb_fg_color(c);
+               get_window()->draw_line(gc,posi,0,posi,get_height());
+       }
+       get_window()->end_paint();
+               
+       return true;
+}
+
+//--- Handle the single clicking and dragging for scrubbing
+
+bool studio::Widget_Sound::on_motion_notify_event(GdkEventMotion* event)
+{
+       Gdk::ModifierType       mod = Gdk::ModifierType(event->state);
+
+       //if we are scrubbing
+       if(mod & Gdk::BUTTON1_MASK)
+       {
+               //Can't do this if we don't have a time frame (heheh...)
+               if(!adj_timescale) return false;
+                       
+               double beg = adj_timescale->get_lower(), end = adj_timescale->get_upper();
+               
+               //find event position in time
+               double t = beg + event->x * (end-beg) / get_width();
+
+               //signal that we are scrubbing to this new value...
+               signal_scrub()(t);
+                               
+               
+               // We should be able to just call
+               // Widget_Timeslider::on_motion_notify_event(),
+               // but that seems to cause the program to halt
+               // for some reason. So for now, let's do the job ourselves
+               //adj_timescale->set_value(t);
+               //adj_timescale->changed();
+               //return true;
+       }
+       
+       return Widget_Timeslider::on_motion_notify_event(event);
+}
+
+bool studio::Widget_Sound::on_button_press_event(GdkEventButton *event)
+{
+       //Assume button PRESS
+       
+       //if we are starting... using left click
+       if(event->button == 1)
+       {
+               if(!adj_timescale) return false;
+                       
+               double beg = adj_timescale->get_lower(), end = adj_timescale->get_upper();
+               
+               //find event position in time
+               double t = beg + event->x * (end-beg) / get_width();
+
+               //signal the attached scrubbing devices...
+               signal_start_scrubbing()(t);
+                               
+               return true;
+       }
+       
+       return Widget_Timeslider::on_button_press_event(event);
+}
+
+bool studio::Widget_Sound::on_button_release_event(GdkEventButton *event)
+{
+       //Assume button RELEASE
+       
+       //if we are ending... using left click
+       if(event->button == 1)
+       {
+               //signal the scrubbing device... to stop
+               signal_stop_scrubbing()();
+                               
+               return true;
+       }
+       
+       return Widget_Timeslider::on_button_release_event(event);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_sound.h b/synfig-studio/trunk/src/gtkmm/widget_sound.h
new file mode 100644 (file)
index 0000000..dbaa9c9
--- /dev/null
@@ -0,0 +1,98 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_sound.h
+**     \brief Widget Sound Header
+**
+**     $Id: widget_sound.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_WIDGET_SOUND_H
+#define __SINFG_WIDGET_SOUND_H
+
+/* === H E A D E R S ======================================================= */
+#include <ETL/handle>
+
+#include <gtkmm/drawingarea.h>
+
+#include "widget_timeslider.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+class AudioProfile;
+class AudioContainer;
+
+/*     What can widget sound do?
+       Options:
+       1. Just draw the sound
+       2. Scroll time and draw the sound
+       3. Play, stop, and scrub the sound... (full interaction...)
+       4. Provide hooks for scrubbing to work... (and possibly play and stop in the future)
+
+       Going with 4 for now...
+*/
+class Widget_Sound : public Widget_Timeslider
+{
+       etl::handle<AudioProfile>       audioprof;
+       
+       //event override interface
+       virtual bool on_expose_event(GdkEventExpose *heh = 0);
+       
+       //for scrubbing... (click is start, drag is scrub, and release is stop...)
+       virtual bool on_motion_notify_event(GdkEventMotion* event);
+       virtual bool on_button_press_event(GdkEventButton *event);
+       virtual bool on_button_release_event(GdkEventButton *event);
+       
+       //Might want a signal setup for scrubbing... and here it is
+       sigc::signal1<void,double>      signal_start_scrubbing_;
+       sigc::signal1<void,double>      signal_scrub_;
+       sigc::signal0<void>                     signal_stop_scrubbing_;
+       
+public: //structors
+       Widget_Sound();
+       ~Widget_Sound();
+
+public: //accessors
+       bool set_profile(etl::handle<AudioProfile>      p);
+       etl::handle<AudioProfile>       get_profile() const;
+
+       //for signal interface
+       sigc::signal1<void,double>      &       signal_start_scrubbing()        {return signal_start_scrubbing_;}
+       sigc::signal1<void,double>      &       signal_scrub()                          {return signal_scrub_;}
+       sigc::signal0<void>                     &       signal_stop_scrubbing()         {return signal_stop_scrubbing_;}
+
+public: //get set interface
+       void set_position(double t);
+       double get_position() const;
+
+public: //interface
+       void draw();
+       
+       void clear();
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_time.cpp b/synfig-studio/trunk/src/gtkmm/widget_time.cpp
new file mode 100644 (file)
index 0000000..634d880
--- /dev/null
@@ -0,0 +1,157 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_time.cpp
+**     \brief Template File
+**
+**     $Id: widget_time.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/entry.h>
+#include <gtkmm/button.h>
+#include "widget_time.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+//using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#if ! defined(_)
+#define _(x)   (x)
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Time::Widget_Time():
+       fps_(0),
+       time_(0)
+{
+       signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Time::refresh_value));
+       signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Time::refresh_text));
+}
+
+Widget_Time::~Widget_Time()
+{
+}
+
+void
+Widget_Time::refresh_text()
+{
+       set_text(time_.get_string(fps_,App::get_time_format()));
+}
+
+
+void
+Widget_Time::set_value(const sinfg::Time &data)
+{
+       time_=data;
+       refresh_text();
+}
+
+sinfg::Time
+Widget_Time::get_value() const
+{
+       return time_;
+}
+
+void
+Widget_Time::set_fps(float x)
+{
+       fps_=Time(x);
+       refresh_text();
+}
+
+void
+Widget_Time::refresh_value()
+{
+       try
+       {
+               Time newtime(get_text(),fps_);
+               if(abs(newtime-time_)>=0.001)
+               {
+                       time_=newtime;
+                       refresh_text();         
+                       signal_value_changed()();
+               }
+       }
+       catch(...)
+       {
+               throw string("Caught unknown exception");
+       }
+}
+
+bool
+Widget_Time::on_event(GdkEvent* event)
+{
+       const Time scroll_amount(0.25);
+       
+       switch(event->type)
+       {
+       case GDK_SCROLL:
+               if(event->scroll.direction==GDK_SCROLL_DOWN)
+               {
+                       time_-=scroll_amount;
+                       refresh_text();
+                       signal_value_changed()();
+               }
+               else if(event->scroll.direction==GDK_SCROLL_UP)
+               {
+                       time_+=scroll_amount;
+                       refresh_text();
+                       signal_value_changed()();
+               }
+               return true;
+               break;
+       default:
+               break;
+       }
+       
+       return Gtk::Entry::on_event(event);
+}
+
+bool
+Widget_Time::on_focus_out_event(GdkEventFocus* event)
+{
+       refresh_value();
+       refresh_text();         
+       return Gtk::Entry::on_focus_out_event(event);
+}
+
+bool
+Widget_Time::on_focus_in_event(GdkEventFocus* event)
+{
+       set_text(time_.get_string(fps_,App::get_time_format()|Time::FORMAT_FULL));
+       return Gtk::Entry::on_focus_in_event(event);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_time.h b/synfig-studio/trunk/src/gtkmm/widget_time.h
new file mode 100644 (file)
index 0000000..1cb0bc2
--- /dev/null
@@ -0,0 +1,83 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_time.h
+**     \brief Template Header
+**
+**     $Id: widget_time.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_TIME_H
+#define __SINFG_STUDIO_WIDGET_TIME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sigc++/signal.h>
+#include <sigc++/slot.h>
+#include <gtkmm/entry.h>
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class Entry; class Button; };
+
+namespace studio {
+
+class Widget_Time : public Gtk::Entry
+{
+
+
+       sigc::signal<void> signal_value_changed_;
+       
+       float fps_;
+       
+       sinfg::Time time_;
+       
+protected:
+       bool on_focus_out_event(GdkEventFocus* event);
+
+       bool on_focus_in_event(GdkEventFocus* event);
+       
+       //void on_activate();
+       
+       void refresh_text();
+
+       void refresh_value();
+       
+       bool on_event(GdkEvent* event);
+
+public:
+       sigc::signal<void> &signal_value_changed() { return signal_value_changed_; }
+
+
+       
+       void set_value(const sinfg::Time &data);
+       sinfg::Time get_value()const;
+       void set_fps(float x);
+       Widget_Time();
+       ~Widget_Time();
+}; // END of class Widget_Time
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_timeslider.cpp b/synfig-studio/trunk/src/gtkmm/widget_timeslider.cpp
new file mode 100644 (file)
index 0000000..8e7e860
--- /dev/null
@@ -0,0 +1,853 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_timeslider.cpp
+**     \brief Time Slider Widget Implementation File
+**
+**     $Id: widget_timeslider.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "widget_timeslider.h"
+
+#include <ETL/misc>
+
+#include <cmath>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+using studio::Widget_Timeslider;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+const double zoominfactor = 0.75;
+const double zoomoutfactor = 1/zoominfactor;
+
+/* === P R O C E D U R E S ================================================= */
+
+Gdk::Color get_interp_color(sinfg::Interpolation x)
+{
+       switch(x)
+       {
+       case INTERPOLATION_TCB:
+               return Gdk::Color("#00B000");
+
+               break;
+
+       case INTERPOLATION_LINEAR:
+               return Gdk::Color("#B0B000");
+               break;
+
+       case INTERPOLATION_CONSTANT:
+               return Gdk::Color("#C70000");
+               break;
+
+       case INTERPOLATION_HALT:
+               return Gdk::Color("#00b0b0");
+               break;
+
+       case INTERPOLATION_MANUAL:
+               return Gdk::Color("#B000B0");
+               break;
+
+       case INTERPOLATION_UNDEFINED: default:
+               return Gdk::Color("#808080");
+               break;
+       }
+}
+
+static Gdk::Color
+color_darken(Gdk::Color x, float amount)
+{
+       x.set_rgb_p(
+               x.get_red_p()*amount,
+               x.get_green_p()*amount,
+               x.get_blue_p()*amount
+       );
+       return x;
+}
+
+void
+studio::render_time_point_to_window(
+       const Glib::RefPtr<Gdk::Drawable>& window,
+       const Gdk::Rectangle& area,
+       const sinfg::TimePoint &tp,
+       bool selected
+)
+{
+       Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
+       const Gdk::Color black("#000000");
+       
+       if(selected)
+               gc->set_line_attributes(2,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+       else
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
+
+       Gdk::Color color;
+       std::vector<Gdk::Point> points;
+       
+/*-    BEFORE ------------------------------------- */
+
+       color=get_interp_color(tp.get_before());
+       color=color_darken(color,1.0f);
+       if(selected)color=color_darken(color,1.3f);
+       gc->set_rgb_fg_color(color);
+
+       switch(tp.get_before())
+       {
+       case INTERPOLATION_TCB:
+               window->draw_arc(
+                       gc,
+                       true,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height(),
+                       64*90,
+                       64*180
+               );
+               gc->set_rgb_fg_color(black);
+               window->draw_arc(
+                       gc,
+                       false,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height(),
+                       64*90,
+                       64*180
+               );
+               break;
+
+       case INTERPOLATION_HALT:
+               window->draw_arc(
+                       gc,
+                       true,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height()*2,
+                       64*90,
+                       64*90
+               );
+               gc->set_rgb_fg_color(black);
+               window->draw_arc(
+                       gc,
+                       false,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height()*2,
+                       64*90,
+                       64*90
+               );
+               break;
+
+       case INTERPOLATION_LINEAR:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x(),area.get_y()+area.get_height()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+
+       case INTERPOLATION_CONSTANT:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/4,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/4,area.get_y()+area.get_height()/2));
+               points.push_back(Gdk::Point(area.get_x(),area.get_y()+area.get_height()/2));
+               points.push_back(Gdk::Point(area.get_x(),area.get_y()+area.get_height()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+
+       case INTERPOLATION_UNDEFINED: default:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/3,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x(),area.get_y()+area.get_height()/3));
+               points.push_back(Gdk::Point(area.get_x(),area.get_y()+area.get_height()*2/3));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/3,area.get_y()+area.get_height()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+       }
+       
+/*-    AFTER -------------------------------------- */
+
+       color=get_interp_color(tp.get_after());
+       color=color_darken(color,0.8f);
+       if(selected)color=color_darken(color,1.3f);
+       gc->set_rgb_fg_color(color);
+
+
+       switch(tp.get_after())
+       {
+       case INTERPOLATION_TCB:
+               window->draw_arc(
+                       gc,
+                       true,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height(),
+                       64*270,
+                       64*180
+               );
+               gc->set_rgb_fg_color(black);
+               window->draw_arc(
+                       gc,
+                       false,
+                       area.get_x(),
+                       area.get_y(),
+                       area.get_width(),
+                       area.get_height(),
+                       64*270,
+                       64*180
+               );
+               break;
+
+       case INTERPOLATION_HALT:
+               window->draw_arc(
+                       gc,
+                       true,
+                       area.get_x(),
+                       area.get_y()-area.get_height(),
+                       area.get_width(),
+                       area.get_height()*2,
+                       64*270,
+                       64*90
+               );
+               gc->set_rgb_fg_color(black);
+               window->draw_arc(
+                       gc,
+                       false,
+                       area.get_x(),
+                       area.get_y()-area.get_height(),
+                       area.get_width(),
+                       area.get_height()*2,
+                       64*270,
+                       64*90
+               );
+               break;
+
+       case INTERPOLATION_LINEAR:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width(),area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+
+       case INTERPOLATION_CONSTANT:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width(),area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width(),area.get_y()+area.get_height()/2));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()*3/4,area.get_y()+area.get_height()/2));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()*3/4,area.get_y()+area.get_height()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+
+       case INTERPOLATION_UNDEFINED: default:
+               points.clear();
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()*2/3,area.get_y()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width(),area.get_y()+area.get_height()/3));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width(),area.get_y()+area.get_height()*2/3));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()*2/3,area.get_y()+area.get_height()));
+               points.push_back(Gdk::Point(area.get_x()+area.get_width()/2,area.get_y()+area.get_height()));
+               window->draw_polygon(gc,true,points);
+               gc->set_rgb_fg_color(black);
+               window->draw_lines(gc,points);  
+               break;
+       }
+
+}
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+double defaultfps = 0;
+const int fullheight = 20;
+
+Widget_Timeslider::Widget_Timeslider()
+:layout(Pango::Layout::create(get_pango_context())),
+adj_default(0,0,2,1/defaultfps,10/defaultfps),
+adj_timescale(0),
+//invalidated(false),
+fps(defaultfps),
+dragscroll(false)
+{
+       set_size_request(-1,fullheight);
+       
+       //                click                    scroll                     zoom
+       add_events( Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK 
+                               | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK );
+       
+       set_time_adjustment(&adj_default);
+       //update_times();
+}
+
+Widget_Timeslider::~Widget_Timeslider()
+{
+}
+
+void Widget_Timeslider::set_time_adjustment(Gtk::Adjustment *x)
+{
+       //disconnect old connections
+       time_value_change.disconnect();
+       time_other_change.disconnect();
+       
+       //connect update function to new adjustment
+       adj_timescale = x;
+       
+       if(x)
+       {
+               time_value_change = x->signal_value_changed().connect(sigc::mem_fun(*this,&Widget_Timeslider::queue_draw));
+               time_other_change = x->signal_changed().connect(sigc::mem_fun(*this,&Widget_Timeslider::queue_draw));   
+               //invalidated = true;
+               //refresh();
+       }
+}
+
+void Widget_Timeslider::set_global_fps(float d)
+{
+       if(fps != d)
+       {
+               fps = d;
+               
+               //update everything since we need to redraw already
+               //invalidated = true;
+               //refresh();
+               queue_draw();
+       }
+}
+
+/*void Widget_Timeslider::update_times()
+{
+       if(adj_timescale)
+       {
+               start = adj_timescale->get_lower();
+               end = adj_timescale->get_upper();
+               current = adj_timescale->get_value();
+       }
+}*/
+
+void Widget_Timeslider::refresh() 
+{
+}
+/*     
+{
+       if(invalidated)
+       {
+               queue_draw();
+       }else if(adj_timescale)
+       {
+               double  l = adj_timescale->get_lower(),
+                               u = adj_timescale->get_upper(),
+                               v = adj_timescale->get_value();
+               
+               bool invalid = (l != start) || (u != end) || (v != current);
+               
+               start = l;
+               end = u;
+               current = v;
+               
+               if(invalid) queue_draw();
+       }
+}*/
+
+bool Widget_Timeslider::redraw(bool doublebuffer)
+{
+       Glib::RefPtr<Gdk::Window> window = get_window();
+       
+       if(!window) return false;
+       
+       Glib::RefPtr<Gdk::GC>   gc = Gdk::GC::create(window);   
+       if(!gc) return false;
+       
+       //sinfg::info("Drawing Timeslider");
+       //clear and update to current values
+       //invalidated = false;
+       //update_times();       
+       
+       //draw grey rectangle
+       Gdk::Color      c("#7f7f7f");
+       gc->set_rgb_fg_color(c);
+       gc->set_background(c);
+       
+       //Get the data for the window and the params to draw it...
+       int w = get_width(), h = get_height();
+       
+       window->draw_rectangle(gc,true,0,0,w,h);                
+       
+       const double EPSILON = 1e-6;
+       if(!adj_timescale || w == 0) return true;
+
+       //Get the time information since we now know it's valid
+       double  start = adj_timescale->get_lower(),
+                       end = adj_timescale->get_upper(),
+                       current = adj_timescale->get_value();
+       
+       if(end-start < EPSILON) return true;
+       
+       //sinfg::info("Drawing Lines");
+       
+       //draw all the time stuff
+       double dtdp = (end - start)/get_width();
+       double dpdt = 1/dtdp;
+       
+       //lines
+       
+       //Draw the time line...
+       double tpx = (current-start)*dpdt;
+       gc->set_rgb_fg_color(Gdk::Color("#ffaf00"));
+       window->draw_line(gc,round_to_int(tpx),0,round_to_int(tpx),fullheight);
+       
+       //normal line/text color
+       gc->set_rgb_fg_color(Gdk::Color("#333333"));    
+
+       //draw these lines... (always 5 between) maybe 6?
+       const int subdiv = 4;
+
+       //1h 45 30 20 10 5
+       //..., 3m, 2m, 1m30s, 1m, 30s, 20s, 10s, 5s, 3s, 2s, 1s, 0.5s
+       //frames... (how???)
+       double ranges[] = 
+       { 1.0/fps,subdiv/fps,0.25,0.5, 1, 2, 3, 5, 10, 20, 30, 60, 90, 120, 180, 300, 600, 1200, 1800, 2700, 3600 };
+       //{ 3600, 2700, 1800, 1200, 600, 300, 180, 120, 90, 60, 30, 20, 10, 5, 3, 2, 1, 0.5 };
+       const int ranges_size = sizeof(ranges)/sizeof(double);
+       
+       double lowerrange = dtdp*75, upperrange = dtdp*150;
+       double midrange = (lowerrange + upperrange)/2;
+       
+       //find most ideal scale
+       double scale = ranges[0];
+       {
+               double *val = binary_find(ranges, ranges+ranges_size, midrange);
+               double *after = val+1;
+               
+               if(val >= ranges+ranges_size)
+               {
+                       val = ranges+ranges_size-1;
+               }
+                       
+               if(after >= ranges+ranges_size)
+               {
+                       after = ranges+ranges_size-1;
+               }
+               
+               scale = *val;
+               
+               double diff = abs(scale - midrange), diff2 = abs(*after - midrange);
+               if(diff2 < diff)
+                       scale = *after;
+       }
+               
+       //sinfg::info("Range found: (l %.2lf,u %.2lf - m %.2lf) -> %.2lf",lowerrange,upperrange,midrange,scale);        
+       
+       //search around this area to get the right one          
+       
+       
+       //get first valid line and it's position in pixel space
+       double time = 0;
+       double pixel = 0;
+       
+       int sdindex = 0;
+
+       double subr = scale / subdiv;
+       
+       //get it's position inside...
+       time = ceil(start/subr)*subr - start;
+       pixel = time*dpdt;
+       
+       //absolute time of the line to be drawn
+       time += start;
+       
+       { //inside the big'n
+               double t = (time/scale - floor(time/scale))*subdiv; // the difference from the big mark in 0:1
+               //sdindex = (int)floor(t + 0.5); //get how far through the range it is...
+               sdindex = round_to_int(t); //get how far through the range it is...
+               
+               //sinfg::info("Extracted fr %.2lf -> %d", t, sdindex);
+       }
+       
+       //sinfg::info("Initial values: %.4lf t, %.1lf pixels, %d i", time,pixel,sdindex);
+       
+       //loop to draw
+       const int heightbig = 12;
+       const int heightsmall = 4;
+       
+       int width = get_width();
+       while( pixel < width )
+       {
+               int xpx = round_to_int(pixel);
+               
+               //draw big              
+               if(sdindex == 0)
+               {
+                       window->draw_line(gc,xpx,0,xpx,heightbig);
+                       //round the time to nearest frame and draw the text
+                       Time tm((double)time);
+                       if(get_global_fps()) tm.round(get_global_fps());
+                       Glib::ustring timecode(tm.get_string(get_global_fps(),App::get_time_format()));
+                       
+                       //gc->set_rgb_fg_color(Gdk::Color("#000000"));
+                       layout->set_text(timecode);
+                       window->draw_layout(gc,xpx+2,heightsmall,layout);
+               }else
+               {
+                       window->draw_line(gc,xpx,0,xpx,heightsmall);                    
+               }
+               
+               //increment time and position
+               pixel += subr / dtdp;
+               time += subr;
+               
+               //increment index
+               if(++sdindex >= subdiv) sdindex -= subdiv;
+       }
+       
+       return true;
+}
+
+bool Widget_Timeslider::on_motion_notify_event(GdkEventMotion* event) //for dragging
+{      
+       if(!adj_timescale) return false;
+               
+       Gdk::ModifierType mod = Gdk::ModifierType(event->state);
+       
+       //scrolling...
+       
+       //NOTE: we might want to address the possibility of dragging with both buttons held down
+       
+       if(mod & Gdk::BUTTON2_MASK)
+       {
+
+               //we need this for scrolling by dragging
+               double  curx = event->x;
+               
+               double  start = adj_timescale->get_lower(),
+                               end = adj_timescale->get_upper();
+               
+               
+               if(dragscroll)
+               {
+                       if(event->time-last_event_time<30)
+                               return false;
+                       else
+                               last_event_time=event->time;
+
+                       if(abs(lastx - curx) < 1 && end != start) return true;
+                       //translate the window and correct it
+                       
+                       //update our stuff so we are operating correctly
+                       //invalidated = true;
+                       //update_times();
+                       
+                       //Note: Use inverse of mouse movement because of conceptual space relationship
+                       double diff = lastx - curx; //curx - lastx;
+                       
+                       //NOTE: This might be incorrect...
+                       //fraction to move...
+                       double dpx = (end - start)/get_width();
+                       lastx = curx;
+                       
+                       diff *= dpx;
+                       
+                       //Adjust...
+                       start += diff;
+                       end += diff;
+                       
+                       //But clamp to bounds if they exist...
+                       //HACK - bounds should not be required for this slider
+                       if(adj_bounds)
+                       {
+                               if(start < adj_bounds->get_lower())
+                               {
+                                       diff = adj_bounds->get_lower() - start;
+                                       start += diff;
+                                       end += diff;
+                               }
+                               
+                               if(end > adj_bounds->get_upper())
+                               {
+                                       diff = adj_bounds->get_upper() - end;
+                                       start += diff;
+                                       end += diff;
+                               }
+                       }               
+                       
+                       //sinfg::info("Scrolling timerange to (%.4f,%.4f)",start,end);
+                       
+                       adj_timescale->set_lower(start);
+                       adj_timescale->set_upper(end);
+
+                       adj_timescale->changed();
+               }else
+               {
+                       dragscroll = true;
+                       lastx = curx;
+                       //lasty = cury;
+               }
+               
+               return true;                            
+       }
+       
+       if(mod & Gdk::BUTTON1_MASK)
+       {
+               double curx = event->x;
+               
+               //get time from drag...
+               double  start = adj_timescale->get_lower(),
+                               end = adj_timescale->get_upper(),
+                               current = adj_timescale->get_value();
+               double t = start + curx*(end - start)/get_width();
+               
+               //snap it to fps - if they exist...
+               if(fps)
+               {
+                       t = floor(t*fps + 0.5)/fps;
+               }
+               
+               //set time if needed
+               if(current != t)
+               {                       
+                       adj_timescale->set_value(t);
+                       
+                       //Fixed this to actually do what it's supposed to...
+                       if(event->time-last_event_time>50)
+                       {
+                               adj_timescale->value_changed();
+                               last_event_time = event->time;
+                       }
+               }
+               
+               return true;
+       }
+       
+       return false;
+}
+
+bool Widget_Timeslider::on_scroll_event(GdkEventScroll* event) //for zooming
+{
+       if(!adj_timescale) return false;
+       
+       //Update so we are calculating based on current values
+       //update_times();       
+       
+       //figure out if we should center ourselves on the current time
+       bool center = false;
+
+       //we want to zoom in on the time value if control is held down
+       if(Gdk::ModifierType(event->state) & Gdk::CONTROL_MASK)
+       {
+               center = true;
+       }
+       
+       switch(event->direction)
+       {
+               case GDK_SCROLL_UP: //zoom in
+               {
+                       zoom_in(center);
+                       
+                       return true;
+               }
+               case GDK_SCROLL_DOWN: //zoom out
+               {
+                       zoom_out(center);
+                       
+                       return true;
+               }
+               
+               default: 
+               {
+                       return false;
+               }
+       }
+}
+
+void Widget_Timeslider::zoom_in(bool centerontime)
+{
+       if(!adj_timescale) return;
+               
+       double  start = adj_timescale->get_lower(),
+                       end = adj_timescale->get_upper(),
+                       current = adj_timescale->get_value();
+       
+       double focuspoint = centerontime ? current : (start + end)/2;
+       
+       //calculate new beginning and end
+       end = focuspoint + (end-focuspoint)*zoominfactor;
+       start = focuspoint + (start-focuspoint)*zoominfactor;
+       
+       //sinfg::info("Zooming in timerange to (%.4f,%.4f)",start,end);
+       if(adj_bounds)
+       {
+               if(start < adj_bounds->get_lower())
+               {
+                       start = adj_bounds->get_lower();
+               }
+               
+               if(end > adj_bounds->get_upper())
+               {
+                       end = adj_bounds->get_upper();
+               }
+       }
+       
+       //reset values
+       adj_timescale->set_lower(start);
+       adj_timescale->set_upper(end);
+       
+       //call changed function
+       adj_timescale->changed();
+}
+
+void Widget_Timeslider::zoom_out(bool centerontime)
+{
+       if(!adj_timescale) return;
+               
+       double  start = adj_timescale->get_lower(),
+                       end = adj_timescale->get_upper(),
+                       current = adj_timescale->get_value();
+       
+       double focuspoint = centerontime ? current : (start + end)/2;
+       
+       //calculate new beginning and end
+       end = focuspoint + (end-focuspoint)*zoomoutfactor;
+       start = focuspoint + (start-focuspoint)*zoomoutfactor;
+       
+       //sinfg::info("Zooming out timerange to (%.4f,%.4f)",start,end);
+       if(adj_bounds)
+       {
+               if(start < adj_bounds->get_lower())
+               {
+                       start = adj_bounds->get_lower();
+               }
+               
+               if(end > adj_bounds->get_upper())
+               {
+                       end = adj_bounds->get_upper();  
+               }
+       }
+       
+       //reset values
+       adj_timescale->set_lower(start);
+       adj_timescale->set_upper(end);
+       
+       //call changed function
+       adj_timescale->changed();
+}
+
+bool Widget_Timeslider::on_button_press_event(GdkEventButton *event) //for clicking
+{
+       switch(event->button)
+       {
+               //time click...
+               case 1:
+               {
+                       double  start = adj_timescale->get_lower(),
+                                       end = adj_timescale->get_upper(),
+                                       current = adj_timescale->get_value();
+                       
+                       double w = get_width();
+                       double t = start + (end - start) * event->x / w;
+                       
+                       t = floor(t*fps + 0.5)/fps;
+                       
+                       /*sinfg::info("Clicking time from %.3lf to %.3lf [(%.2lf,%.2lf) %.2lf / %.2lf ... %.2lf", 
+                                               current, vt, start, end, event->x, w, fps);*/
+                       
+                       if(t != current)
+                       {                       
+                               current = t;
+                               
+                               if(adj_timescale)
+                               {
+                                       adj_timescale->set_value(current);
+                                       adj_timescale->value_changed();
+                               }
+                       }
+                               
+                       break;
+               }
+               
+               //scroll click
+               case 2:
+               {
+                       //start dragging
+                       dragscroll = true;
+                       lastx = event->x;
+                       //lasty = event->y;
+                       
+                       return true;
+               }
+               
+               default:
+               {
+                       break;
+               }
+       }
+       
+       return false;
+}
+
+bool Widget_Timeslider::on_button_release_event(GdkEventButton *event) //end drag
+{      
+       switch(event->button)
+       {               
+               case 2:
+               {
+                       //start dragging
+                       dragscroll = false;
+                       return true;
+               }
+               
+               default:
+               {
+                       break;
+               }
+       }
+       
+       return false;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_timeslider.h b/synfig-studio/trunk/src/gtkmm/widget_timeslider.h
new file mode 100644 (file)
index 0000000..0138bcf
--- /dev/null
@@ -0,0 +1,131 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_timeslider.h
+**     \brief Time Slider Widget Header
+**
+**     $Id: widget_timeslider.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_WIDGET_TIMESLIDER_H
+#define __SINFG_WIDGET_TIMESLIDER_H
+
+/* === H E A D E R S ======================================================= */
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/adjustment.h>
+
+#include <sinfg/time.h>
+#include "canvasview.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+void render_time_point_to_window(const Glib::RefPtr<Gdk::Drawable>& window,const Gdk::Rectangle& ca,const sinfg::TimePoint &tp,bool selected=false);
+
+       
+/* Design for the timeslider...
+
+       Concept: Scalable ruler
+               Ticks are done every so often (30 s, 10 frames, 5 frames, etc.) 
+               Print out frame numbers next to the big ticks
+               Show blue pills in separate area (above or below)
+*/
+
+class Widget_Timeslider : public Gtk::DrawingArea
+{
+protected: //implementation that other interfaces can see
+       Glib::RefPtr<Pango::Layout> layout; //implementation awesomeness for text drawing
+
+       Gtk::Adjustment adj_default;
+       Gtk::Adjustment *adj_timescale;
+
+       //HACK - I should not have to see this...
+       Gtk::Adjustment *adj_bounds;
+       
+       //Statistics used for drawing stuff (and making sure we don't if we don't need to)
+       /*double start,end;
+       double current;
+       
+       bool invalidated;*/
+       
+       guint32 last_event_time;
+
+       float fps;
+       
+       sigc::connection time_value_change;
+       sigc::connection time_other_change;
+       
+       //TODO: fill out blue pill stuff
+       
+       //input functions
+       
+       virtual bool on_motion_notify_event(GdkEventMotion* event); //for dragging
+       virtual bool on_scroll_event(GdkEventScroll* event); //for zooming
+       virtual bool on_button_press_event(GdkEventButton *event); //for clicking
+       virtual bool on_button_release_event(GdkEventButton *event); //for clicking
+       
+       virtual bool on_expose_event(GdkEventExpose *event) {redraw(); return true;}//for drawing
+       
+       virtual bool redraw(bool doublebuffer = false);
+       
+       //void update_times();
+       
+       void zoom_in(bool centerontime = false);
+       void zoom_out(bool centerontime = false);
+       
+       //Drag the Frame
+       bool dragscroll;
+       
+       /*NOTE: if we can set the mouse position to the original position
+                       this would only have to be set once (and it would be good otherwise too)
+       */
+       double lastx; //last mouse position for dragging
+               
+public: //structors
+       Widget_Timeslider();
+       ~Widget_Timeslider();
+
+public: //Normal Interface
+       
+       void draw() {redraw();}
+       virtual void refresh(); //reget bluepills, time values and queue_draw if need be
+
+public: //Time Interface
+
+       //Run FPS stuff through it to the MAX
+       double get_global_fps() const {return fps;}
+       void set_global_fps(float d);
+
+       //accessors for the time adjustment
+       Gtk::Adjustment &get_time_adjustment() const {return *adj_timescale;}   
+       void set_time_adjustment(Gtk::Adjustment *x);
+       
+       //HACK - I should not have to see these bounds (should be boundless)
+       Gtk::Adjustment &get_bounds_adjustment() const {return *adj_bounds;}    
+       void set_bounds_adjustment(Gtk::Adjustment *x) {adj_bounds = x;}
+};
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_value.cpp b/synfig-studio/trunk/src/gtkmm/widget_value.cpp
new file mode 100644 (file)
index 0000000..ddf28fa
--- /dev/null
@@ -0,0 +1,484 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_value.cpp
+**     \brief Template File
+**
+**     $Id: widget_value.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include "widget_value.h"
+#include <ETL/stringf>
+#include <gtkmm/celleditable.h>
+#include <gtkmm/editable.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/eventbox.h>
+#include <gtk/gtkentry.h> /* see XXX below */
+#include "app.h"
+
+
+#include "widget_vector.h"
+#include "widget_filename.h"
+#include "widget_enum.h"
+#include "widget_coloredit.h"
+#include "widget_canvaschooser.h"
+#include "widget_time.h"
+#include "app.h"
+#include "widget_distance.h"
+
+#endif
+
+using namespace sinfg;
+using namespace etl;
+using namespace std;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define DIGITS         15
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_ValueBase::Widget_ValueBase():
+       Glib::ObjectBase        (typeid(Widget_ValueBase)),
+       Gtk::HBox(),
+       real_adjustment(0,-2000000000,2000000000,0.05,0.05,0.05),
+       integer_adjustment(0,-2000000000,2000000000,1,1,1),
+       angle_adjustment(0,-2000000000,2000000000,1,1,1)
+{
+       set_no_show_all();
+       
+       label=manage(new class Gtk::Label("Unknown Datatype"));
+       pack_start(*label);
+       label->show();
+
+       vector_widget=manage(new class Widget_Vector());
+       pack_start(*vector_widget);
+
+       color_widget=manage(new class Widget_ColorEdit());
+       pack_start(*color_widget);
+
+       enum_widget=manage(new class Widget_Enum());
+       pack_start(*enum_widget);
+
+       real_widget=manage(new class Gtk::SpinButton(real_adjustment,0.05,DIGITS));
+       pack_start(*real_widget);
+
+       integer_widget=manage(new class Gtk::SpinButton(integer_adjustment,1,0));
+       pack_start(*integer_widget);
+
+       angle_widget=manage(new class Gtk::SpinButton(angle_adjustment,15,2));
+       pack_start(*angle_widget);
+
+       bool_widget=manage(new class Gtk::CheckButton());                     
+       pack_start(*bool_widget);
+
+       //color_widget=manage(new class Gtk::ColorSelection());
+       //pack_start(*color_widget);
+
+       string_widget=manage(new class Gtk::Entry());
+       pack_start(*string_widget);
+       
+       canvas_widget=manage(new class Widget_CanvasChooser());
+       pack_start(*canvas_widget);
+
+       filename_widget=manage(new class Widget_Filename());
+       pack_start(*filename_widget);
+
+       time_widget=manage(new class Widget_Time());
+       pack_start(*time_widget);
+
+       distance_widget=manage(new class Widget_Distance());
+       pack_start(*distance_widget);
+
+       
+       vector_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       color_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       enum_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       real_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       integer_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       angle_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       string_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       canvas_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       filename_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       time_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       distance_widget->signal_activate().connect(sigc::mem_fun(*this,&Widget_ValueBase::activate));
+       
+       /*signal_focus_in_event().connect(
+               sigc::bind_return(
+               sigc::hide(
+                       sigc::mem_fun(*this,&Widget_ValueBase::grab_focus)
+               ),false
+               )
+       );*/
+}
+
+Widget_ValueBase::~Widget_ValueBase()
+{
+}
+
+void
+Widget_ValueBase::activate()
+{
+       //DEBUGPOINT();
+       signal_activate()();
+}
+
+void
+Widget_ValueBase::inside_cellrenderer()
+{
+       string_widget->set_has_frame(false);
+       string_widget->gobj()->is_cell_renderer = true; // XXX
+
+       real_widget->set_has_frame(false);
+       //static_cast<Gtk::Entry*>(real_widget)->gobj()->is_cell_renderer = true; // XXX
+
+       distance_widget->set_has_frame(false);
+       //static_cast<Gtk::Entry*>(distance_widget)->gobj()->is_cell_renderer = true; // XXX
+       
+       integer_widget->set_has_frame(false);
+       //static_cast<Gtk::Entry*>(integer_widget)->gobj()->is_cell_renderer = true; // XXX
+       vector_widget->set_has_frame(false);
+    //vector_widget->set_digits(10);
+
+       color_widget->set_has_frame(false);
+    //color_widget->set_digits(10);
+       filename_widget->set_has_frame(false);
+       time_widget->set_has_frame(false);
+}
+
+void
+Widget_ValueBase::set_sensitive(bool x)
+{
+       Gtk::HBox::set_sensitive(x);
+       label->set_sensitive(x);
+       vector_widget->set_sensitive(x);
+       real_widget->set_sensitive(x);
+       integer_widget->set_sensitive(x);
+       bool_widget->set_sensitive(x);
+    color_widget->set_sensitive(x);
+       string_widget->set_sensitive(x);
+       canvas_widget->set_sensitive(x);
+       enum_widget->set_sensitive(x);
+       angle_widget->set_sensitive(x);
+       filename_widget->set_sensitive(x);
+       time_widget->set_sensitive(x);
+       distance_widget->set_sensitive(x);
+}
+
+void
+Widget_ValueBase::set_value(const sinfg::ValueBase &data)
+{
+       label->hide();
+       vector_widget->hide();
+       real_widget->hide();
+       integer_widget->hide();
+       bool_widget->hide();
+    color_widget->hide();
+       string_widget->hide();
+       canvas_widget->hide();
+       enum_widget->hide();
+       angle_widget->hide();
+       filename_widget->hide();
+       time_widget->hide();
+       distance_widget->hide();
+       
+       value=data;
+       try{
+       switch(value.get_type())
+       {
+       case ValueBase::TYPE_VECTOR:
+               vector_widget->set_canvas(canvas);
+               vector_widget->set_value(value.get(Vector()));
+               vector_widget->show();
+               break;
+       case ValueBase::TYPE_REAL:
+               if(param_desc.get_is_distance() && canvas)
+               {
+                       Distance dist(value.get(Real()),Distance::SYSTEM_UNITS);
+                       dist.convert(App::distance_system,canvas->rend_desc());
+                       distance_widget->set_value(dist);
+                       distance_widget->show();
+               }
+               else
+               {
+                       real_widget->set_value(value.get(Real()));
+                       real_widget->show();
+               }
+               break;
+       case ValueBase::TYPE_TIME:
+               if(canvas)time_widget->set_fps(canvas->rend_desc().get_frame_rate());
+               time_widget->set_value(value.get(Time()));
+               time_widget->show();
+               break;
+       case ValueBase::TYPE_ANGLE:
+               angle_widget->set_value(Angle::deg(value.get(Angle())).get());
+               angle_widget->show();
+               break;
+       case ValueBase::TYPE_INTEGER:
+               if(param_desc.get_hint()!="enum")
+               {
+                       integer_widget->set_value(value.get(int()));
+                       integer_widget->show();
+               }
+               else
+               {
+                       enum_widget->set_param_desc(param_desc);
+                       enum_widget->set_value(value.get(int()));
+                       enum_widget->show();
+               }
+               break;
+       case ValueBase::TYPE_CANVAS:
+               assert(canvas);
+               canvas_widget->set_parent_canvas(canvas);
+               canvas_widget->set_value(value.get(etl::loose_handle<sinfg::Canvas>()));
+               canvas_widget->show();
+               break;
+       case ValueBase::TYPE_BOOL:
+               bool_widget->set_active(value.get(bool()));
+               bool_widget->show();
+               break;
+       case ValueBase::TYPE_STRING:
+               if(param_desc.get_hint()!="filename")
+               {
+                       string_widget->set_text(value.get(string()));
+                       string_widget->show();
+               }
+               else
+               {
+                       filename_widget->set_value(value.get(string()));
+                       filename_widget->show();
+               }
+               break;
+       case ValueBase::TYPE_COLOR:
+        {
+               color_widget->set_value(value.get(sinfg::Color()));
+               color_widget->show();
+/*
+                       Gdk::Color gdkcolor;
+                       sinfg::Color color=value.get(sinfg::Color());
+                       gdkcolor.set_rgb_p(color.get_r(),color.get_g(),color.get_b());
+                       color_widget->set_current_color(gdkcolor);
+                       color_widget->set_has_opacity_control(true);
+                       color_widget->set_current_alpha((unsigned short)(color.get_a()*65535.0));
+                       color_widget->show();
+*/
+               }
+               break;
+       default:
+               label->show();
+               break;
+       }
+       }catch(...) { sinfg::error(__FILE__":%d: Caught something that was thrown",__LINE__); }
+}
+
+const sinfg::ValueBase &
+Widget_ValueBase::get_value()
+{
+       switch(value.get_type())
+       {
+       case ValueBase::TYPE_VECTOR:
+               value=vector_widget->get_value();
+               break;
+       case ValueBase::TYPE_REAL:
+               if(param_desc.get_is_distance() && canvas)
+                       value=distance_widget->get_value().units(canvas->rend_desc());
+               else
+                       value=real_widget->get_value();
+               break;
+       case ValueBase::TYPE_TIME:
+               value=time_widget->get_value();
+               break;
+       case ValueBase::TYPE_ANGLE:
+               value=Angle::deg(angle_widget->get_value());
+               break;
+       case ValueBase::TYPE_CANVAS:
+               value=canvas_widget->get_value();
+               break;
+       case ValueBase::TYPE_INTEGER:
+               if(param_desc.get_hint()!="enum")
+               {
+                       value=integer_widget->get_value_as_int();
+               }
+               else
+               {
+                       value=enum_widget->get_value();
+               }
+                       
+               break;
+       case ValueBase::TYPE_BOOL:
+               value=bool_widget->get_active();
+               break;
+       case ValueBase::TYPE_STRING:
+               if(param_desc.get_hint()!="filename")
+               {
+                       value=string(string_widget->get_text());
+               }
+               else
+               {
+                       value=string(filename_widget->get_value());
+               }
+               break;
+       case ValueBase::TYPE_COLOR:
+        {
+                       value=color_widget->get_value();
+/*
+                       Gdk::Color gdkcolor;
+                       sinfg::Color color;
+                       gdkcolor=color_widget->get_current_color();
+                       color.set_r(gdkcolor.get_red_p());
+            color.set_g(gdkcolor.get_green_p());
+            color.set_b(gdkcolor.get_blue_p());
+                       color.set_a(color_widget->get_current_alpha()/65535.0);
+                       
+                       value=color;
+*/
+               }
+               break;
+       default:
+               break;
+       }
+
+       return value;
+}
+       
+
+void
+Widget_ValueBase::on_grab_focus()
+{
+       switch(value.get_type())
+       {
+       case ValueBase::TYPE_VECTOR:
+               vector_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_REAL:
+               if(param_desc.get_is_distance()&& canvas)
+                       distance_widget->grab_focus();
+               else
+                       real_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_TIME:
+               time_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_ANGLE:
+               angle_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_CANVAS:
+               canvas_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_INTEGER:
+               if(param_desc.get_hint()!="enum")
+               {
+                       integer_widget->grab_focus();
+               }
+               else
+               {
+                       enum_widget->grab_focus();
+               }
+                       
+               break;
+       case ValueBase::TYPE_BOOL:
+               bool_widget->grab_focus();
+               break;
+       case ValueBase::TYPE_STRING:
+               if(param_desc.get_hint()!="filename")
+               {
+                       string_widget->grab_focus();
+               }
+               else
+               {
+                       filename_widget->grab_focus();
+               }
+               break;
+       case ValueBase::TYPE_COLOR:
+        {
+                       color_widget->grab_focus();
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+/*
+Glib::SignalProxy0<void>
+Widget_ValueBase::signal_activate()
+{
+       switch(value.get_type())
+       {
+       case ValueBase::TYPE_VECTOR:
+               return vector_widget->signal_activate();
+               break;
+       case ValueBase::TYPE_REAL:
+               if(param_desc.get_is_distance()&& canvas)
+                       return distance_widget->signal_activate();
+               else
+                       return real_widget->signal_activate();
+               
+               break;
+       case ValueBase::TYPE_TIME:
+               return time_widget->signal_activate();
+               break;
+       case ValueBase::TYPE_ANGLE:
+               return angle_widget->signal_activate();
+               break;
+       case ValueBase::TYPE_CANVAS:
+               return canvas_widget->signal_activate();
+               break;
+       case ValueBase::TYPE_INTEGER:
+               if(param_desc.get_hint()!="enum")
+                       return integer_widget->signal_activate();
+               else
+                       return enum_widget->signal_activate();
+                       
+               break;
+       case ValueBase::TYPE_BOOL:
+               return string_widget->signal_activate();
+               break;
+       case ValueBase::TYPE_STRING:
+               if(param_desc.get_hint()!="filename")
+               {
+                       return string_widget->signal_activate();
+               }
+               else
+               {
+                       return filename_widget->signal_activate();
+               }
+               break;
+       case ValueBase::TYPE_COLOR:
+        {
+                       return color_widget->signal_activate();
+               }
+               break;
+       default:
+               return string_widget->signal_activate();
+               break;
+       }
+}
+*/
diff --git a/synfig-studio/trunk/src/gtkmm/widget_value.h b/synfig-studio/trunk/src/gtkmm/widget_value.h
new file mode 100644 (file)
index 0000000..fa812b7
--- /dev/null
@@ -0,0 +1,136 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_value.cpp
+**     \brief Template File
+**
+**     $Id: widget_value.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_VALUE_H
+#define __SINFG_GTKMM_VALUE_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include <gtk/gtk.h>
+//#include <gtkmm/ruler.h>
+//#include <gtkmm/arrow.h>
+//#include <gtkmm/image.h>
+//#include <gdkmm/pixbufloader.h>
+//#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+//#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+//#include <gtkmm/statusbar.h>
+#include <gtkmm/button.h>
+#include <gtkmm/label.h>
+//#include <atkmm/stateset.h>
+//#include <gtkmm/paned.h>
+//#include <gtkmm/treeview.h>
+//#include <gtkmm/treestore.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+//#include <gtkmm/cellrenderer.h>
+#include <gtkmm/checkbutton.h>
+
+//#include <gtkmm/colorselection.h>
+#include <gtkmm/optionmenu.h>
+
+//#include <sinfg/sinfg.h>
+#include <sinfg/paramdesc.h>
+#include <sinfg/value.h>
+#include <sinfg/canvas.h>
+
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_Color;
+class Widget_ColorEdit;
+class Widget_CanvasChooser;
+class Widget_Enum;
+class Widget_Filename;
+class Widget_Vector;
+class Widget_Time;
+class Widget_Distance;
+       
+class Widget_ValueBase : public Gtk::HBox
+{
+       Gtk::Label *label;
+       sinfg::ValueBase value;
+
+       Widget_Vector *vector_widget;
+       Gtk::SpinButton *real_widget;
+       Gtk::Adjustment real_adjustment;
+       Gtk::SpinButton *integer_widget;
+       Gtk::Adjustment integer_adjustment;
+       Gtk::SpinButton *angle_widget;
+       Gtk::Adjustment angle_adjustment;
+
+       Gtk::CheckButton *bool_widget;
+       //Gtk::ColorSelection *color_widget;
+       Widget_ColorEdit *color_widget;
+       Widget_CanvasChooser *canvas_widget;
+       Widget_Enum *enum_widget;
+       Widget_Filename *filename_widget;
+       Widget_Time *time_widget;
+       Gtk::Entry *string_widget;
+       Widget_Distance *distance_widget;
+       
+//     std::string hint;
+       
+       sinfg::ParamDesc param_desc;
+       etl::handle<sinfg::Canvas> canvas;
+       sigc::signal<void> signal_value_changed_;
+       sigc::signal<void> signal_activate_;
+
+public:
+       sigc::signal<void> &signal_value_changed() { return signal_value_changed_; }
+       
+       void activate();
+       
+       sigc::signal<void>& signal_activate() { return signal_activate_; }
+
+       void set_value(const sinfg::ValueBase &data);
+       const sinfg::ValueBase &get_value();
+
+       void on_grab_focus();
+       
+       void set_param_desc(const sinfg::ParamDesc &x) { param_desc=x; }
+       const sinfg::ParamDesc &get_param_desc() { return param_desc; }
+
+       void set_sensitive(bool x);
+       
+       //void set_hint(std::string x) { hint=x; }
+//     std::string get_hint() { return hint; }
+
+       void set_canvas(etl::handle<sinfg::Canvas> x) { canvas=x; assert(canvas); }
+       void inside_cellrenderer();
+       Widget_ValueBase();
+       ~Widget_ValueBase();
+};
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_vector.cpp b/synfig-studio/trunk/src/gtkmm/widget_vector.cpp
new file mode 100644 (file)
index 0000000..4b9b6bb
--- /dev/null
@@ -0,0 +1,238 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_vector.cpp
+**     \brief Template File
+**
+**     $Id: widget_vector.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/spinbutton.h>
+#include "widget_vector.h"
+#include "widget_distance.h"
+#include "app.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define DIGITS         10
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Vector::Widget_Vector():
+       x_adjustment(0,-100000000,100000000,0.05,0.05,0.05),
+       y_adjustment(0,-100000000,100000000,0.05,0.05,0.05)
+{
+       Gtk::Label *label;
+       
+       label=manage(new class Gtk::Label("x:"));
+       label->show();
+       pack_start(*label, Gtk::PACK_SHRINK);
+
+       spinbutton_x=manage(new class Gtk::SpinButton(x_adjustment,0.05,DIGITS));
+       spinbutton_x->set_update_policy(Gtk::UPDATE_ALWAYS);
+       spinbutton_x->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
+       pack_start(*spinbutton_x, Gtk::PACK_EXPAND_WIDGET);
+
+       distance_x=manage(new Widget_Distance());
+       distance_x->set_digits(4);
+       distance_x->set_update_policy(Gtk::UPDATE_ALWAYS);
+       distance_x->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
+       pack_start(*distance_x, Gtk::PACK_EXPAND_WIDGET);
+
+       label=manage(new class Gtk::Label("y:"));
+       label->show();
+       pack_start(*label, Gtk::PACK_SHRINK);
+
+       spinbutton_y=manage(new class Gtk::SpinButton(y_adjustment,0.05,DIGITS));
+       spinbutton_y->set_update_policy(Gtk::UPDATE_ALWAYS);
+       spinbutton_y->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
+       spinbutton_y->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Vector::activate));
+       pack_start(*spinbutton_y, Gtk::PACK_EXPAND_WIDGET);
+
+       distance_y=manage(new Widget_Distance());
+       distance_y->set_digits(4);
+       distance_y->set_update_policy(Gtk::UPDATE_ALWAYS);
+       distance_y->signal_value_changed().connect(sigc::mem_fun(*this,&studio::Widget_Vector::on_value_changed));
+       distance_y->signal_activate().connect(sigc::mem_fun(*this,&studio::Widget_Vector::activate));
+       pack_start(*distance_y, Gtk::PACK_EXPAND_WIDGET);
+
+       spinbutton_x->show();
+       spinbutton_y->show();
+       
+       spinbutton_x->signal_activate().connect(sigc::mem_fun(*spinbutton_y,&Gtk::SpinButton::grab_focus));
+       distance_x->signal_activate().connect(sigc::mem_fun(*distance_y,&Gtk::SpinButton::grab_focus));
+}
+
+Widget_Vector::~Widget_Vector()
+{
+}
+
+void
+Widget_Vector::on_grab_focus()
+{
+       if(canvas_)
+               distance_x->grab_focus();
+       else
+               spinbutton_x->grab_focus();
+}
+
+void
+Widget_Vector::set_has_frame(bool x)
+{
+       if(spinbutton_x)
+       {
+               spinbutton_x->set_has_frame(x);
+               spinbutton_y->set_has_frame(x);
+               spinbutton_x->set_size_request(48,-1);
+               spinbutton_y->set_size_request(48,-1);
+       }
+
+       distance_x->set_has_frame(x);
+       distance_y->set_has_frame(x);
+       distance_x->set_size_request(48,-1);
+       distance_y->set_size_request(48,-1);
+}
+
+void
+Widget_Vector::set_digits(int x)
+{
+       if(spinbutton_x)
+       {
+               spinbutton_x->set_digits(x);
+               spinbutton_y->set_digits(x);
+               spinbutton_x->set_size_request(48,-1);
+               spinbutton_y->set_size_request(48,-1);
+       }
+       
+       distance_x->set_digits(x);
+       distance_y->set_digits(x);
+       distance_x->set_size_request(48,-1);
+       distance_y->set_size_request(48,-1);
+}
+
+void
+Widget_Vector::set_value(const sinfg::Vector &data)
+{
+       vector=data;
+
+       if(canvas_){try
+       {
+               Distance distx(vector[0],Distance::SYSTEM_UNITS),disty(vector[1],Distance::SYSTEM_UNITS);
+               distx.convert(App::distance_system,canvas_->rend_desc());
+               disty.convert(App::distance_system,canvas_->rend_desc());
+               distance_x->set_value(distx);
+               distance_y->set_value(disty);
+               spinbutton_x->hide();
+               spinbutton_y->hide();
+       }catch(...) { sinfg::error("Widget_Vector::set_value(): Caught something that was thrown"); }}
+       else
+       {
+               spinbutton_x->set_value(vector[0]);
+               spinbutton_y->set_value(vector[1]);
+               distance_x->hide();
+               distance_y->hide();
+       }
+}
+
+const sinfg::Vector &
+Widget_Vector::get_value()
+{
+       if(!canvas_ && spinbutton_x)
+       {
+               vector[0]=spinbutton_x->get_value();
+               vector[1]=spinbutton_y->get_value();
+               distance_x->hide();
+               distance_y->hide();
+       }
+       else try
+       {
+               vector[0]=distance_x->get_value().units(canvas_->rend_desc());
+               vector[1]=distance_y->get_value().units(canvas_->rend_desc());
+               spinbutton_x->hide();
+               spinbutton_y->hide();
+       }catch(...) { sinfg::error("Widget_Vector::set_value(): Caught something that was thrown"); }
+       return vector;
+}
+
+void
+Widget_Vector::on_value_changed()
+{
+       signal_value_changed()();
+}
+
+void
+Widget_Vector::set_canvas(Canvas::LooseHandle x)
+{
+       canvas_=x;
+       if(x)
+       {
+               if(spinbutton_x)
+               {
+                       spinbutton_x->hide();
+                       spinbutton_y->hide();
+//                     delete spinbutton_x;
+//                     delete spinbutton_y;
+               }
+               distance_x->show();
+               distance_y->show();
+       }
+       else
+       {
+               if(spinbutton_x)
+               {
+                       spinbutton_x->show();
+                       spinbutton_y->show();
+               }
+               distance_x->hide();
+               distance_y->hide();
+       }
+}
+
+void
+Widget_Vector::show_all_vfunc()
+{
+       if(canvas_)
+       {
+               distance_x->show();
+               distance_y->show();
+       }
+       else
+       {
+               spinbutton_x->show();
+               spinbutton_y->show();
+       }
+       show();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_vector.h b/synfig-studio/trunk/src/gtkmm/widget_vector.h
new file mode 100644 (file)
index 0000000..7a2911a
--- /dev/null
@@ -0,0 +1,95 @@
+/* === S I N F G =========================================================== */
+/*!    \file widget_vector.h
+**     \brief Template Header
+**
+**     $Id: widget_vector.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_WIDGET_VECTOR_H
+#define __SINFG_STUDIO_WIDGET_VECTOR_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/box.h>
+#include <gtkmm/adjustment.h>
+#include <sinfg/vector.h>
+#include <sinfg/distance.h>
+#include <sinfg/canvas.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace Gtk { class SpinButton; };
+
+namespace studio {
+
+class Widget_Distance;
+       
+class Widget_Vector : public Gtk::HBox
+{
+       Gtk::SpinButton* spinbutton_x;
+       Gtk::SpinButton* spinbutton_y;
+
+       Widget_Distance* distance_x;
+       Widget_Distance* distance_y;
+       
+       Gtk::Adjustment x_adjustment;
+       Gtk::Adjustment y_adjustment;
+
+       sinfg::Vector vector;
+
+       sigc::signal<void> signal_value_changed_;
+
+       sigc::signal<void> signal_activate_;
+       
+       sinfg::Canvas::LooseHandle canvas_;
+
+public:
+       
+       void activate() { signal_activate_(); }
+       
+       void set_canvas(sinfg::Canvas::LooseHandle);
+       sinfg::Canvas::LooseHandle get_canvas()const { return canvas_; }
+       
+       sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
+
+       sigc::signal<void>& signal_activate() { return signal_activate_; }
+
+       void on_value_changed();
+       void on_grab_focus();
+
+       void set_value(const sinfg::Vector &data);
+       const sinfg::Vector &get_value();
+       void set_has_frame(bool x);
+       void set_digits(int x);
+       Widget_Vector();
+       ~Widget_Vector();
+       
+protected:
+       void show_all_vfunc();
+}; // END of class Widget_Vector
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_waypoint.cpp b/synfig-studio/trunk/src/gtkmm/widget_waypoint.cpp
new file mode 100644 (file)
index 0000000..f8fae32
--- /dev/null
@@ -0,0 +1,198 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypoint.cpp
+**     \brief Template Header
+**
+**     $Id: widget_waypoint.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include "dialog_waypoint.h"
+#include <gtk/gtk.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/combo.h>
+#include <ETL/stringf>
+#include "widget_value.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <gtkmm/optionmenu.h>
+#include "widget_time.h"
+#include "widget_waypoint.h"
+#endif
+
+using namespace sinfg;
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_Waypoint::Widget_Waypoint(etl::handle<sinfg::Canvas> canvas):
+       Gtk::Table(4,3,false),
+       waypoint(sinfg::ValueBase(),0),
+       adj_tension(0.0,-20,20,0.1,1),
+       adj_continuity(0.0,-20,20,0.1,1),
+       adj_bias(0.0,-20,20,0.1,1),
+       adj_temporal_tension(0.0,-20,20,0.1,1)
+{
+       value_widget=manage(new Widget_ValueBase());
+       value_widget->set_canvas(canvas);
+       value_widget->show();
+       
+       value_node_label=manage(new Gtk::Label(_("(Non-static value)")));
+       
+       
+       time_widget=manage(new Widget_Time());
+       time_widget->set_fps(canvas->rend_desc().get_frame_rate());
+       //spinbutton=manage(new Gtk::SpinButton(time_adjustment,0.05,3));
+       //spinbutton->set_update_policy(Gtk::UPDATE_ALWAYS);
+       //spinbutton->show();
+
+       before_options=manage(new class Gtk::Menu());
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("TCB Smooth"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Constant"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Linear"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Ease In"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Manual"));
+
+       after_options=manage(new class Gtk::Menu());
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("TCB Smooth"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Constant"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Linear"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Ease Out"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Manual"));
+
+       before=manage(new class Gtk::OptionMenu());
+       before->show();
+       before->set_menu(*before_options);
+
+       after=manage(new class Gtk::OptionMenu());
+       after->show();
+       after->set_menu(*after_options);
+
+       spin_tension=manage(new class Gtk::SpinButton(adj_tension,0.1,3));
+       spin_tension->show();
+       spin_continuity=manage(new class Gtk::SpinButton(adj_continuity,0.1,3));
+       spin_continuity->show();
+       spin_bias=manage(new class Gtk::SpinButton(adj_bias,0.1,3));
+       spin_bias->show();
+       spin_temporal_tension=manage(new class Gtk::SpinButton(adj_temporal_tension,0.1,3));
+       spin_temporal_tension->show();
+       
+       
+       Gtk::HBox *hbox(manage(new Gtk::HBox()));
+       hbox->show();
+       hbox->pack_start(*value_widget);
+       hbox->pack_start(*value_node_label);
+       
+       attach(*manage(new Gtk::Label(_("ValueBase:"))), 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       //attach(*value_widget, 1, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       //attach(*value_node_label, 0, 4, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("Time:"))), 0, 1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       attach(*time_widget, 1, 4, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("In:"))), 0, 1, 3, 4, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+       attach(*before, 1, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("Out:"))), 2, 3, 3, 4, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       attach(*after, 3, 4, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       attach(*manage(new Gtk::Label(_("Tension:"))), 0, 1, 4, 5, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       attach(*spin_tension, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("Continuity:"))), 2, 3, 4, 5, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+       attach(*spin_continuity, 3, 4, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("Bias:"))), 0, 1, 5, 6, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       attach(*spin_bias, 1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*manage(new Gtk::Label(_("Temporal Tension:"))), 2, 3, 5, 6, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);        
+       attach(*spin_temporal_tension, 3, 4, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       show_all();
+       hide();
+       attach(*hbox, 1, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       set_canvas(canvas);
+}
+
+void
+Widget_Waypoint::set_canvas(sinfg::Canvas::Handle x)
+{
+       canvas=x;
+       assert(canvas);
+       
+       time_widget->set_fps(canvas->rend_desc().get_frame_rate());
+       value_widget->set_canvas(canvas);
+}
+
+void
+Widget_Waypoint::set_waypoint(sinfg::Waypoint &x)
+{
+       time_widget->set_fps(canvas->rend_desc().get_frame_rate());
+
+       waypoint=x;
+                       
+#warning This really needs to be fixed to support value node waypoints!
+       if(waypoint.is_static())
+       {
+               value_widget->set_value(waypoint.get_value());
+               value_widget->show();
+               value_node_label->hide();
+       }
+       else
+       {
+               value_widget->hide();
+               value_node_label->show();
+       }
+       
+       time_widget->set_value(waypoint.get_time());
+
+       before->set_history((int)waypoint.get_before());
+       after->set_history((int)waypoint.get_after());
+
+       adj_tension.set_value(waypoint.get_tension());
+       adj_continuity.set_value(waypoint.get_continuity());
+       adj_bias.set_value(waypoint.get_bias());
+       adj_temporal_tension.set_value(waypoint.get_temporal_tension());
+       
+}
+const sinfg::Waypoint &
+Widget_Waypoint::get_waypoint()const
+{
+#warning This too!
+       waypoint.set_time(time_widget->get_value());
+       waypoint.set_value(value_widget->get_value());
+       //int i;
+
+       waypoint.set_before((sinfg::Waypoint::Interpolation)before->get_history());
+       waypoint.set_after((sinfg::Waypoint::Interpolation)after->get_history());
+
+       waypoint.set_tension(adj_tension.get_value());
+       waypoint.set_continuity(adj_continuity.get_value());
+       waypoint.set_bias(adj_bias.get_value());
+       waypoint.set_temporal_tension(adj_temporal_tension.get_value());
+       return waypoint;
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_waypoint.h b/synfig-studio/trunk/src/gtkmm/widget_waypoint.h
new file mode 100644 (file)
index 0000000..5a45f3e
--- /dev/null
@@ -0,0 +1,96 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypoint.h
+**     \brief Template Header
+**
+**     $Id: widget_waypoint.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_WIDGET_WAYPOINT_H
+#define __SINFG_GTKMM_WIDGET_WAYPOINT_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include <gtk/gtk.h>
+//#include <gtkmm/arrow.h>
+//#include <gtkmm/image.h>
+//#include <gdkmm/pixbufloader.h>
+//#include <gtkmm/viewport.h>
+#include <gtkmm/adjustment.h>
+//#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+//#include <gtkmm/progressbar.h>
+//#include <atkmm/stateset.h>
+//#include <gtkmm/paned.h>
+#include <gtkmm/box.h>
+//#include <gtkmm/scrollbar.h>
+#include <gtkmm/combo.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/spinbutton.h>
+
+
+#include <sinfgapp/value_desc.h>
+#include <sinfg/waypoint.h>
+//#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_ValueBase;
+class Widget_Time;
+class Widget_Waypoint;
+
+class Widget_Waypoint : public Gtk::Table
+{
+    Widget_ValueBase *value_widget;
+       Gtk::Label *value_node_label;
+       Gtk::Label *label;
+       Widget_Time *time_widget;
+       mutable sinfg::Waypoint waypoint;
+       sinfg::Canvas::Handle canvas;
+       //Gtk::Adjustment time_adjustment;
+
+       Gtk::Combo *in,*out;
+       Gtk::OptionMenu *before, *after;
+       Gtk::Menu *before_options,*after_options;
+
+       Gtk::SpinButton *spin_tension, *spin_continuity, *spin_bias, *spin_temporal_tension;
+       Gtk::Adjustment adj_tension, adj_continuity, adj_bias, adj_temporal_tension;
+//     Gtk::ComboDropDownItem item;
+
+public:
+       Widget_Waypoint(etl::handle<sinfg::Canvas> canvas);
+       void set_canvas(sinfg::Canvas::Handle x);
+       void set_waypoint(sinfg::Waypoint &x);
+       const sinfg::Waypoint &get_waypoint()const;
+}; // END of class Widget_Waypoint
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/widget_waypointmodel.cpp b/synfig-studio/trunk/src/gtkmm/widget_waypointmodel.cpp
new file mode 100644 (file)
index 0000000..20584f1
--- /dev/null
@@ -0,0 +1,187 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypointmodel.cpp
+**     \brief Template Header
+**
+**     $Id: widget_waypointmodel.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <gtkmm/label.h>
+#include <gtkmm/spinbutton.h>
+#include <ETL/stringf>
+#include "widget_value.h"
+#include "app.h"
+#include <gtkmm/menu.h>
+#include <gtkmm/optionmenu.h>
+#include "widget_time.h"
+#include "widget_waypointmodel.h"
+#endif
+
+using namespace sinfg;
+using namespace std;
+using namespace etl;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Widget_WaypointModel::Widget_WaypointModel():
+       Gtk::Table(4,3,false),
+       adj_tension(0.0,-20,20,0.1,1),
+       adj_continuity(0.0,-20,20,0.1,1),
+       adj_bias(0.0,-20,20,0.1,1),
+       adj_temporal_tension(0.0,-20,20,0.1,1),
+       checkbutton_after(_("Out:")),
+       checkbutton_before(_("In:")),
+       checkbutton_tension(_("Tension:")),
+       checkbutton_continuity(_("Continuity:")),
+       checkbutton_bias(_("Bias:")),
+       checkbutton_temporal_tension(_("Temporal Tension:"))
+{
+       before_options=manage(new class Gtk::Menu());
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("TCB Smooth"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Constant"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Linear"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Ease In"));
+       before_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Manual"));
+
+       after_options=manage(new class Gtk::Menu());
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("TCB Smooth"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Constant"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Linear"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Ease Out"));
+       after_options->items().push_back(Gtk::Menu_Helpers::MenuElem("Manual"));
+
+       before=manage(new class Gtk::OptionMenu());
+       before->show();
+       before->set_menu(*before_options);
+
+       after=manage(new class Gtk::OptionMenu());
+       after->show();
+       after->set_menu(*after_options);
+
+       spin_tension=manage(new class Gtk::SpinButton(adj_tension,0.1,3));
+       spin_tension->show();
+       spin_continuity=manage(new class Gtk::SpinButton(adj_continuity,0.1,3));
+       spin_continuity->show();
+       spin_bias=manage(new class Gtk::SpinButton(adj_bias,0.1,3));
+       spin_bias->show();
+       spin_temporal_tension=manage(new class Gtk::SpinButton(adj_temporal_tension,0.1,3));
+       spin_temporal_tension->show();
+
+       checkbutton_before.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       checkbutton_after.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       checkbutton_tension.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       checkbutton_continuity.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       checkbutton_bias.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       checkbutton_temporal_tension.signal_toggled().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       
+       adj_tension.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       adj_continuity.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       adj_bias.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       adj_temporal_tension.signal_value_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+
+       before->signal_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       after->signal_changed().connect(sigc::mem_fun(*this,&Widget_WaypointModel::on_change));
+       
+       attach(checkbutton_before, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);     
+       attach(*before, 1, 2, 0,1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(checkbutton_after, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);      
+       attach(*after, 3, 4, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       attach(checkbutton_tension, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);    
+       attach(*spin_tension, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(checkbutton_continuity, 2, 3, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0); 
+       attach(*spin_continuity, 3, 4, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(checkbutton_bias, 0, 1, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);       
+       attach(*spin_bias, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(checkbutton_temporal_tension, 2, 3, 2, 3, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);   
+       attach(*spin_temporal_tension, 3, 4, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       show_all();
+       hide();
+       updating=false;
+       on_change();
+}
+
+void
+Widget_WaypointModel::on_change()
+{
+       if(updating)
+               return;
+       
+       waypoint_model.set_before((Waypoint::Interpolation)before->get_history());
+       waypoint_model.set_after((Waypoint::Interpolation)after->get_history());
+
+       waypoint_model.set_tension(adj_tension.get_value());
+       waypoint_model.set_continuity(adj_continuity.get_value());
+       waypoint_model.set_bias(adj_bias.get_value());
+       waypoint_model.set_temporal_tension(adj_temporal_tension.get_value());
+
+       waypoint_model.set_before_flag(checkbutton_before.get_active());
+       waypoint_model.set_after_flag(checkbutton_after.get_active());
+       waypoint_model.set_tension_flag(checkbutton_tension.get_active());
+       waypoint_model.set_continuity_flag(checkbutton_continuity.get_active());
+       waypoint_model.set_bias_flag(checkbutton_bias.get_active());
+       waypoint_model.set_temporal_tension_flag(checkbutton_temporal_tension.get_active());
+       
+       before->set_sensitive(checkbutton_before.get_active());
+       after->set_sensitive(checkbutton_after.get_active());
+       spin_tension->set_sensitive(checkbutton_tension.get_active());
+       spin_continuity->set_sensitive(checkbutton_continuity.get_active());
+       spin_bias->set_sensitive(checkbutton_bias.get_active());
+       spin_temporal_tension->set_sensitive(checkbutton_temporal_tension.get_active());
+}
+
+void
+Widget_WaypointModel::set_waypoint_model(sinfg::Waypoint::Model &x)
+{
+       waypoint_model=x;
+       updating=true;
+       
+       before->set_history((int)waypoint_model.get_before());
+       after->set_history((int)waypoint_model.get_after());
+
+       adj_tension.set_value(waypoint_model.get_tension());
+       adj_continuity.set_value(waypoint_model.get_continuity());
+       adj_bias.set_value(waypoint_model.get_bias());
+       adj_temporal_tension.set_value(waypoint_model.get_temporal_tension());
+       
+       checkbutton_before.set_active(waypoint_model.get_before_flag());
+       checkbutton_after.set_active(waypoint_model.get_after_flag());
+       checkbutton_tension.set_active(waypoint_model.get_tension_flag());
+       checkbutton_continuity.set_active(waypoint_model.get_continuity_flag());
+       checkbutton_bias.set_active(waypoint_model.get_bias_flag());
+       checkbutton_temporal_tension.set_active(waypoint_model.get_temporal_tension_flag());
+       
+       updating=false;
+       
+       on_change();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/widget_waypointmodel.h b/synfig-studio/trunk/src/gtkmm/widget_waypointmodel.h
new file mode 100644 (file)
index 0000000..8d5a9b4
--- /dev/null
@@ -0,0 +1,95 @@
+/* === S I N F G =========================================================== */
+/*!    \file dialog_waypointmodel.h
+**     \brief Template Header
+**
+**     $Id: widget_waypointmodel.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_WIDGET_WAYPOINTMODEL_H
+#define __SINFG_GTKMM_WIDGET_WAYPOINTMODEL_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include <gtk/gtk.h>
+//#include <gtkmm/arrow.h>
+//#include <gtkmm/image.h>
+//#include <gdkmm/pixbufloader.h>
+//#include <gtkmm/viewport.h>
+//#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+//#include <gtkmm/progressbar.h>
+//#include <atkmm/stateset.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/combo.h>
+#include <gtkmm/optionmenu.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/checkbutton.h>
+
+
+#include <sinfg/waypoint.h>
+#include <sinfg/string.h>
+#include <sinfg/time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+
+class Widget_Time;
+class Widget_WaypointModel;
+
+class Widget_WaypointModel : public Gtk::Table
+{      
+       sinfg::Waypoint::Model waypoint_model;
+       
+       bool updating;
+       
+       Gtk::Combo *in,*out;
+       Gtk::OptionMenu *before, *after;
+       Gtk::Menu *before_options,*after_options;
+
+       Gtk::SpinButton *spin_tension, *spin_continuity, *spin_bias, *spin_temporal_tension;
+       Gtk::Adjustment adj_tension, adj_continuity, adj_bias, adj_temporal_tension;
+
+       Gtk::CheckButton checkbutton_after;
+       Gtk::CheckButton checkbutton_before;
+       Gtk::CheckButton checkbutton_tension;
+       Gtk::CheckButton checkbutton_continuity;
+       Gtk::CheckButton checkbutton_bias;
+       Gtk::CheckButton checkbutton_temporal_tension;
+
+       void on_change();
+       
+public:
+       Widget_WaypointModel();
+       void set_waypoint_model(sinfg::Waypoint::Model &x);
+       const sinfg::Waypoint::Model &get_waypoint_model()const { return waypoint_model; }
+}; // END of class Widget_WaypointModel
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/workarea.cpp b/synfig-studio/trunk/src/gtkmm/workarea.cpp
new file mode 100644 (file)
index 0000000..740f791
--- /dev/null
@@ -0,0 +1,2521 @@
+/* === S I N F G =========================================================== */
+/*!    \file workarea.cpp
+**     \brief Template Header
+**
+**     $Id: workarea.cpp,v 1.3 2005/01/16 19:55:57 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <sigc++/adaptors/hide.h>
+
+#include "workarea.h"
+#include "canvasview.h"
+#include "app.h"
+#include <gtkmm/window.h>
+#include <gtkmm/image.h>
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/ruler.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/image.h>
+#include <gtkmm/scrollbar.h>
+#include <cmath>
+#include <sigc++/retype_return.h>
+#include <sigc++/retype.h>
+#include <sigc++/hide.h>
+#include <ETL/misc>
+
+#include <sinfg/target_scanline.h>
+#include <sinfg/target_tile.h>
+#include <sinfg/surface.h>
+#include <sinfgapp/canvasinterface.h>
+#include "event_mouse.h"
+#include "event_layerclick.h"
+#include "widget_color.h"
+#include <sinfg/distance.h>
+#include "workarearenderer.h"
+
+#include "renderer_canvas.h"
+#include "renderer_grid.h"
+#include "renderer_guides.h"
+#include "renderer_timecode.h"
+#include "renderer_ducks.h"
+#include "renderer_dragbox.h"
+#include "renderer_bbox.h"
+#include "asyncrenderer.h"
+#include <gtkmm/frame.h>
+
+#include <sinfg/mutex.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+#define RULER_FIX              15
+
+#ifndef stratof
+#define stratof(X) (atof((X).c_str()))
+#define stratoi(X) (atoi((X).c_str()))
+#endif
+
+
+/* === G L O B A L S ======================================================= */
+
+/* === C L A S S E S ======================================================= */
+
+class WorkAreaTarget : public sinfg::Target_Tile
+{
+public:
+       WorkArea *workarea;
+       bool low_res;
+       int w,h;
+       int real_tile_w,real_tile_h;
+       //std::vector<Glib::RefPtr<Gdk::Pixbuf> >::iterator tile_iter;
+
+       int twindow_start, twindow_width, twindow_height, twindow_pad;
+       int refresh_id;
+       
+       bool onionskin;
+       bool onion_first_tile;
+       int onion_layers;
+
+       std::list<sinfg::Time> onion_skin_queue;
+
+       sinfg::Mutex mutex;
+
+       void set_onion_skin(bool x)
+       {
+               onionskin=x;
+               
+               Time time(rend_desc().get_time_start());
+               
+               onion_skin_queue.push_back(time);
+               //onion_skin_queue.push_back(time-1);
+               //onion_skin_queue.push_back(time+1);
+               
+               try
+               {
+                       onion_skin_queue.push_back(
+                               get_canvas()->keyframe_list().find_prev(
+                                       time
+                               )->get_time()
+                       );
+               }
+               catch(...)
+               {  }
+               
+               try
+               {
+                       onion_skin_queue.push_back(
+                               get_canvas()->keyframe_list().find_next(
+                                       time
+                               )->get_time()
+                       );
+               }
+               catch(...)
+               {  }
+               
+               onion_layers=onion_skin_queue.size();
+               
+               onion_first_tile=false;
+       }
+public:
+       
+       WorkAreaTarget(WorkArea *workarea,int w, int h):
+               workarea(workarea),
+               low_res(workarea->get_low_resolution_flag()),
+               w(w),
+               h(h),
+               real_tile_w(workarea->tile_w),
+               real_tile_h(workarea->tile_h),
+               refresh_id(workarea->refreshes),
+               onionskin(false),
+               onion_layers(0)
+       {
+               //set_remove_alpha();
+               //set_avoid_time_sync();
+               set_clipping(true);
+               if(low_res)
+               {
+                       set_tile_w(workarea->tile_w/2);
+                       set_tile_h(workarea->tile_h/2);
+               }
+               else
+               {
+                       set_tile_w(workarea->tile_w);
+                       set_tile_h(workarea->tile_h);
+               }
+               set_canvas(workarea->get_canvas());
+               set_quality(workarea->get_quality());
+       }
+       
+       ~WorkAreaTarget()
+       {
+               workarea->queue_draw();
+       }
+
+       virtual bool set_rend_desc(sinfg::RendDesc *newdesc)
+       {
+               assert(workarea);
+               newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
+               if(low_res)
+                       newdesc->set_wh(w/2,h/2);
+               else
+                       newdesc->set_wh(w,h);
+
+               if(
+                               workarea->get_w()!=w
+                       ||      workarea->get_h()!=h
+               ) workarea->set_wh(w,h,4);
+               
+               workarea->full_frame=false;
+
+               desc=*newdesc;
+               return true;
+       }
+
+       virtual int total_tiles()const
+       {
+               int tw(rend_desc().get_w()/get_tile_w());
+               int th(rend_desc().get_h()/get_tile_h());
+               if(rend_desc().get_w()%get_tile_w()!=0)tw++;
+               if(rend_desc().get_h()%get_tile_h()!=0)th++;
+               return tw*th;
+       }
+
+       virtual int next_frame(Time& time)
+       {
+               sinfg::Mutex::Lock lock(mutex);
+               
+               if(!onionskin)
+                       return sinfg::Target_Tile::next_frame(time);
+               
+               onion_first_tile=(onion_layers==(signed)onion_skin_queue.size());
+               
+               if(!onion_skin_queue.empty())
+               {
+                       time=onion_skin_queue.front();
+                       onion_skin_queue.pop_front();
+               }
+               else
+                       return 0;
+               
+               return onion_skin_queue.size()+1;
+       }
+
+       virtual int next_tile(int& x, int& y)
+       {
+               sinfg::Mutex::Lock lock(mutex);
+               //if(workarea->tile_queue.empty()) return 0;
+                       
+               //int curr_tile(workarea->tile_queue.front());
+               //workarea->tile_queue.pop_front();
+               int curr_tile(workarea->next_unrendered_tile(refresh_id-onion_skin_queue.size()));
+               if(curr_tile<0)
+                       return 0;
+               
+               // Width of the image(in tiles)
+               int tw(rend_desc().get_w()/get_tile_w());
+               if(rend_desc().get_w()%get_tile_w()!=0)tw++;
+                               
+               y=(curr_tile/tw)*get_tile_w();
+               x=(curr_tile%tw)*get_tile_h();
+
+               // Mark this tile as "up-to-date"
+               if(onionskin)
+                       workarea->tile_book[curr_tile].second=refresh_id-onion_skin_queue.size();
+               else
+                       workarea->tile_book[curr_tile].second=refresh_id;
+
+               return total_tiles()-curr_tile+1;
+       }
+
+       
+       virtual bool start_frame(sinfg::ProgressCallback *cb)
+       {
+               sinfg::Mutex::Lock lock(mutex);
+
+               int tw(rend_desc().get_w()/get_tile_w());
+               if(rend_desc().get_w()%get_tile_w()!=0)tw++;
+               int th(rend_desc().get_h()/get_tile_h());
+               if(rend_desc().get_h()%get_tile_h()!=0)th++;
+
+               twindow_start=0;
+               twindow_width=tw;
+               twindow_height=th;
+               twindow_pad=0;
+
+               workarea->tile_book.resize(total_tiles());
+               //tile_iter=workarea->tile_book.begin()+twindow_start;
+               return true;
+       }
+               
+       static void free_buff(const guint8 *x) { free(const_cast<guint8*>(x)); }
+       
+       virtual bool add_tile(const sinfg::Surface &surface, int x, int y)
+       {
+               sinfg::Mutex::Lock lock(mutex);
+               assert(surface);
+               
+               PixelFormat pf(PF_RGB);
+               
+               const int total_bytes(get_tile_w()*get_tile_h()*sinfg::channels(pf));
+
+               unsigned char *buffer((unsigned char*)malloc(total_bytes));
+
+               if(!surface || !buffer)
+                       return false;
+               {
+                       unsigned char *dest(buffer);
+                       const Color *src(surface[0]);
+                       int w(get_tile_w());
+                       int h(get_tile_h());
+                       int x(surface.get_w()*surface.get_h());
+                       //if(low_res) { w/=2,h/=2; }
+                       Color dark(0.6,0.6,0.6);
+                       Color lite(0.8,0.8,0.8);
+                       for(int i=0;i<x;i++)
+                               dest=Color2PixelFormat(
+                                       Color::blend(
+                                               (*(src++)),
+                                               ((i/surface.get_w())*8/h+(i%surface.get_w())*8/w)&1?dark:lite,
+                                               1.0f
+                                       ).clamped(),
+                                       pf,dest,App::gamma
+                               );
+               }
+
+               x/=get_tile_w();
+               y/=get_tile_h();
+               int tw(rend_desc().get_w()/get_tile_w());
+               if(rend_desc().get_w()%get_tile_w()!=0)tw++;
+               unsigned int index=y*tw+x;
+
+               // Sanity check
+               if(index>workarea->tile_book.size())
+                       return false;
+
+               Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+               
+               pixbuf=Gdk::Pixbuf::create_from_data(
+                       buffer, // pointer to the data
+                       Gdk::COLORSPACE_RGB, // the colorspace
+                       ((pf&PF_A)==PF_A), // has alpha?
+                       8, // bits per sample
+                       surface.get_w(),        // width
+                       surface.get_h(),        // height
+                       surface.get_w()*sinfg::channels(pf), // stride (pitch)
+                       sigc::ptr_fun(&WorkAreaTarget::free_buff)
+               );      
+
+               if(low_res)
+               {
+                       // We need to scale up
+                       pixbuf=pixbuf->scale_simple(
+                               surface.get_w()*2,
+                               surface.get_h()*2,
+                               Gdk::INTERP_NEAREST
+                       );
+               }
+               
+               if(!onionskin || onion_first_tile || !workarea->tile_book[index].first)
+               {                                                       
+                       workarea->tile_book[index].first=pixbuf;
+               }
+               else
+               {
+                       pixbuf->composite(
+                               workarea->tile_book[index].first, // Dest
+                               0,//int dest_x
+                               0,//int dest_y
+                               pixbuf->get_width(), // dest width
+                               pixbuf->get_height(), // dest_height,
+                               0, // double offset_x
+                               0, // double offset_y
+                               1, // double scale_x
+                               1, // double scale_y
+                               Gdk::INTERP_NEAREST, // interp
+                               255/(onion_layers-onion_skin_queue.size()+1) //int overall_alpha
+                       );
+               }
+               
+               //if(index%2)
+                       workarea->queue_draw();                 
+               assert(workarea->tile_book[index].first);
+               return true;
+       }
+
+       virtual void end_frame()
+       {
+               //workarea->queue_draw();
+       }
+};
+
+
+class WorkAreaTarget_Full : public sinfg::Target_Scanline
+{
+public:
+       WorkArea *workarea;
+       bool low_res;
+       int w,h;
+       int real_tile_w,real_tile_h;
+       //std::vector<Glib::RefPtr<Gdk::Pixbuf> >::iterator tile_iter;
+
+       int twindow_start, twindow_width, twindow_height, twindow_pad;
+       int refresh_id;
+       
+       bool onionskin;
+       bool onion_first_tile;
+       int onion_layers;
+
+       Surface surface;
+
+       std::list<sinfg::Time> onion_skin_queue;
+
+       void set_onion_skin(bool x)
+       {
+               onionskin=x;
+               
+               Time time(rend_desc().get_time_start());
+               
+               onion_skin_queue.push_back(time);
+               //onion_skin_queue.push_back(time-1);
+               //onion_skin_queue.push_back(time+1);
+               if(!onionskin)
+                       return;
+               
+               try
+               {
+                       onion_skin_queue.push_back(
+                               get_canvas()->keyframe_list().find_prev(
+                                       time
+                               )->get_time()
+                       );
+               }
+               catch(...)
+               {  }
+               
+               try
+               {
+                       onion_skin_queue.push_back(
+                               get_canvas()->keyframe_list().find_next(
+                                       time
+                               )->get_time()
+                       );
+               }
+               catch(...)
+               {  }
+               
+               onion_layers=onion_skin_queue.size();
+               
+               onion_first_tile=false;
+       }
+public:
+       
+       WorkAreaTarget_Full(WorkArea *workarea,int w, int h):
+               workarea(workarea),
+               low_res(workarea->get_low_resolution_flag()),
+               w(w),
+               h(h),
+               refresh_id(workarea->refreshes),
+               onionskin(false),
+               onion_layers(0)
+       {
+               set_canvas(workarea->get_canvas());
+               set_quality(workarea->get_quality());
+       }
+       
+       ~WorkAreaTarget_Full()
+       {
+       }
+
+       virtual bool set_rend_desc(sinfg::RendDesc *newdesc)
+       {
+               assert(workarea);
+               newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
+               if(low_res)
+                       newdesc->set_wh(w/2,h/2);
+               else
+                       newdesc->set_wh(w,h);
+
+               if(
+                               workarea->get_w()!=w
+                       ||      workarea->get_h()!=h
+               ) workarea->set_wh(w,h,4);
+               
+               surface.set_wh(newdesc->get_w(),newdesc->get_h());
+
+               desc=*newdesc;
+               workarea->full_frame=true;
+               workarea->tile_book.resize(1);
+               return true;
+       }
+
+       virtual int next_frame(Time& time)
+       {
+               // Mark this tile as "up-to-date"
+               if(onionskin)
+                       workarea->tile_book[0].second=refresh_id-onion_skin_queue.size();
+               else
+                       workarea->tile_book[0].second=refresh_id;
+
+               if(!onionskin)
+                       return sinfg::Target_Scanline::next_frame(time);
+               
+               onion_first_tile=(onion_layers==(signed)onion_skin_queue.size());
+               
+               if(!onion_skin_queue.empty())
+               {
+                       time=onion_skin_queue.front();
+                       onion_skin_queue.pop_front();
+               }
+               else
+                       return 0;               
+               return onion_skin_queue.size()+1;
+       }
+
+       
+       virtual bool start_frame(sinfg::ProgressCallback *cb)
+       {
+               return true;
+       }
+
+       virtual Color * start_scanline(int scanline)
+       {
+               return surface[scanline];
+       }
+
+       virtual bool end_scanline()
+       {
+               return true;
+       }
+
+       static void free_buff(const guint8 *x) { free(const_cast<guint8*>(x)); }
+       
+       virtual void end_frame()
+       {
+               assert(surface);
+               
+               PixelFormat pf(PF_RGB);
+               
+               const int total_bytes(surface.get_w()*surface.get_h()*sinfg::channels(pf));
+
+               unsigned char *buffer((unsigned char*)malloc(total_bytes));
+
+               if(!surface || !buffer)
+                       return;
+               {
+                       unsigned char *dest(buffer);
+                       const Color *src(surface[0]);
+                       int w(surface.get_w());
+                       //int h(surface.get_h());
+                       int x(surface.get_w()*surface.get_h());
+                       //if(low_res) { w/=2,h/=2; }
+                       Color dark(0.6,0.6,0.6);
+                       Color lite(0.8,0.8,0.8);
+                       int tw=workarea->tile_w;
+                       int th=workarea->tile_h;
+                       if(low_res)
+                       {
+                               tw/=2;
+                               th/=2;
+                       }
+                       for(int i=0;i<x;i++)
+                               dest=Color2PixelFormat(
+                                       Color::blend(
+                                               (*(src++)),
+                                               ((i/w)*8/th+(i%w)*8/tw)&1?dark:lite,
+                                               1.0f
+                                       ).clamped(),
+                                       pf,
+                                       dest,
+                                       App::gamma
+                               );
+               }
+
+               Glib::RefPtr<Gdk::Pixbuf> pixbuf;
+               
+               pixbuf=Gdk::Pixbuf::create_from_data(
+                       buffer, // pointer to the data
+                       Gdk::COLORSPACE_RGB, // the colorspace
+                       ((pf&PF_A)==PF_A), // has alpha?
+                       8, // bits per sample
+                       surface.get_w(),        // width
+                       surface.get_h(),        // height
+                       surface.get_w()*sinfg::channels(pf), // stride (pitch)
+                       sigc::ptr_fun(&WorkAreaTarget::free_buff)
+               );      
+
+               if(low_res)
+               {
+                       // We need to scale up
+                       pixbuf=pixbuf->scale_simple(
+                               surface.get_w()*2,
+                               surface.get_h()*2,
+                               Gdk::INTERP_NEAREST
+                       );
+               }
+               
+               int index=0;
+               
+               if(!onionskin || onion_first_tile || !workarea->tile_book[index].first)
+               {                                                       
+                       workarea->tile_book[index].first=pixbuf;
+               }
+               else
+               {
+                       pixbuf->composite(
+                               workarea->tile_book[index].first, // Dest
+                               0,//int dest_x
+                               0,//int dest_y
+                               pixbuf->get_width(), // dest width
+                               pixbuf->get_height(), // dest_height,
+                               0, // double offset_x
+                               0, // double offset_y
+                               1, // double scale_x
+                               1, // double scale_y
+                               Gdk::INTERP_NEAREST, // interp
+                               255/(onion_layers-onion_skin_queue.size()+1) //int overall_alpha
+                       );
+               }
+               
+               workarea->queue_draw();                 
+               assert(workarea->tile_book[index].first);
+       }
+};
+
+
+
+
+/* === M E T H O D S ======================================================= */
+
+
+WorkArea::WorkArea(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface):
+       Gtk::Table(4+RULER_FIX, 3, false),
+       canvas_interface(canvas_interface),
+       canvas(canvas_interface->get_canvas()),
+       scrollx_adjustment(0,-4,4,0.01,0.1),
+       scrolly_adjustment(0,-4,4,0.01,0.1),
+       progresscallback(0),
+       dragging(DRAG_NONE),
+       show_grid(false),
+       tile_w(128),
+       tile_h(128)
+{      
+       show_guides=true;
+       curr_input_device=0;
+       full_frame=false;
+       allow_duck_clicks=true;
+       allow_layer_clicks=true;
+       render_idle_func_id=0;
+       zoom=prev_zoom=1.0;
+       quality=10;
+       rendering=false;        
+       canceled_=false;
+       low_resolution=true;
+       pw=0.001;
+       ph=0.001;
+       last_focus_point=Point(0,0);
+       onion_skin=false;
+       queued=false;
+       dirty_trap_enabled=false;
+       solid_lines=true;
+       
+       dirty_trap_queued=0;
+
+       meta_data_lock=false;
+
+       insert_renderer(new Renderer_Canvas,    000);
+       insert_renderer(new Renderer_Grid,              100);
+       insert_renderer(new Renderer_Guides,    200);
+       insert_renderer(new Renderer_Ducks,             300);
+       insert_renderer(new Renderer_BBox,              399);
+       insert_renderer(new Renderer_Dragbox,   400);
+       insert_renderer(new Renderer_Timecode,  500);
+
+       signal_duck_selection_changed().connect(sigc::mem_fun(*this,&studio::WorkArea::queue_draw));
+       signal_strokes_changed().connect(sigc::mem_fun(*this,&studio::WorkArea::queue_draw));
+       signal_grid_changed().connect(sigc::mem_fun(*this,&studio::WorkArea::queue_draw));
+       signal_grid_changed().connect(sigc::mem_fun(*this,&studio::WorkArea::save_meta_data));
+       signal_sketch_saved().connect(sigc::mem_fun(*this,&studio::WorkArea::save_meta_data));
+
+       // Not that it really makes a difference... (setting this to zero, that is)
+       refreshes=0;
+       
+       drawing_area=manage(new class Gtk::DrawingArea());
+       drawing_area->show();
+       drawing_area->set_extension_events(Gdk::EXTENSION_EVENTS_ALL);
+
+       drawing_frame=manage(new Gtk::Frame);
+       drawing_frame->add(*drawing_area);
+       //drawing_frame->set_shadow_type(Gtk::SHADOW_NONE);
+       //drawing_frame->property_border_width()=5;
+       //drawing_frame->modify_fg(Gtk::STATE_NORMAL,Gdk::Color("#00ffff"));
+       //drawing_frame->modify_base(Gtk::STATE_NORMAL,Gdk::Color("#ff00ff"));
+       /*drawing_frame->modify_fg(Gtk::STATE_ACTIVE,Gdk::Color("#00ffff"));
+       drawing_frame->modify_base(Gtk::STATE_ACTIVE,Gdk::Color("#ff00ff"));
+       drawing_frame->modify_bg(Gtk::STATE_ACTIVE,Gdk::Color("#00ff00"));
+       drawing_frame->modify_fg(Gtk::STATE_INSENSITIVE,Gdk::Color("#00ffff"));
+       drawing_frame->modify_base(Gtk::STATE_INSENSITIVE,Gdk::Color("#ff00ff"));
+       drawing_frame->modify_bg(Gtk::STATE_INSENSITIVE,Gdk::Color("#00ff00"));
+       drawing_frame->modify_fg(Gtk::STATE_SELECTED,Gdk::Color("#00ffff"));
+       drawing_frame->modify_base(Gtk::STATE_SELECTED,Gdk::Color("#ff00ff"));
+       drawing_frame->modify_bg(Gtk::STATE_SELECTED,Gdk::Color("#00ff00"));
+       */
+       //drawing_frame->set_state(Gtk::STATE_NORMAL);
+       
+       drawing_frame->show();
+       
+       attach(*drawing_frame, 1, 3+RULER_FIX, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+
+       Gtk::IconSize iconsize=Gtk::IconSize::from_name("sinfg-small_icon");
+
+
+       // Create the vertical and horizontal rulers
+       vruler = manage(new class Gtk::VRuler());
+       hruler = manage(new class Gtk::HRuler());
+       vruler->set_metric(Gtk::PIXELS);
+       hruler->set_metric(Gtk::PIXELS);
+       vruler->show();
+       hruler->show();
+       attach(*vruler, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*hruler, 1, 3+RULER_FIX, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
+       hruler->signal_event().connect(sigc::mem_fun(*this, &WorkArea::on_hruler_event));
+       vruler->signal_event().connect(sigc::mem_fun(*this, &WorkArea::on_vruler_event));
+       hruler->add_events(Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK |Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
+       vruler->add_events(Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK |Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
+
+       // Create the menu button
+       menubutton=manage(new class Gtk::Button());
+       Gtk::Arrow *arrow1 = manage(new class Gtk::Arrow(Gtk::ARROW_RIGHT, Gtk::SHADOW_OUT));
+       menubutton->add(*arrow1);
+       menubutton->show_all();
+       menubutton->signal_pressed().connect(sigc::mem_fun(*this, &WorkArea::popup_menu));
+       attach(*menubutton, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       
+
+       Gtk::VScrollbar *vscrollbar1 = manage(new class Gtk::VScrollbar(*get_scrolly_adjustment()));
+       Gtk::HScrollbar *hscrollbar1 = manage(new class Gtk::HScrollbar(*get_scrollx_adjustment()));
+       vscrollbar1->show();
+       hscrollbar1->show();
+       attach(*vscrollbar1, 3+RULER_FIX, 4+RULER_FIX, 1, 2, Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
+       attach(*hscrollbar1, 2+RULER_FIX, 3+RULER_FIX, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::FILL, 0, 0);
+
+       ZoomDial *zoomdial=manage(new class ZoomDial(iconsize));
+       zoomdial->signal_zoom_in().connect(sigc::mem_fun(*this, &studio::WorkArea::zoom_in));
+       zoomdial->signal_zoom_out().connect(sigc::mem_fun(*this, &studio::WorkArea::zoom_out));
+       zoomdial->signal_zoom_fit().connect(sigc::mem_fun(*this, &studio::WorkArea::zoom_fit));
+       zoomdial->signal_zoom_norm().connect(sigc::mem_fun(*this, &studio::WorkArea::zoom_norm));
+       zoomdial->show();
+       attach(*zoomdial, 0, 2+RULER_FIX, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+
+       drawing_area->add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);
+       add_events(Gdk::KEY_PRESS_MASK);
+       drawing_area->add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
+       drawing_area->add_events(Gdk::BUTTON1_MOTION_MASK | Gdk::BUTTON2_MOTION_MASK |Gdk::POINTER_MOTION_MASK);
+       
+       // ----------------- Attach signals
+       
+       drawing_area->signal_expose_event().connect(sigc::mem_fun(*this, &WorkArea::refresh));
+       drawing_area->signal_event().connect(sigc::mem_fun(*this, &WorkArea::on_drawing_area_event));
+       drawing_area->signal_size_allocate().connect(sigc::hide(sigc::mem_fun(*this, &WorkArea::refresh_dimension_info)));
+
+
+       
+       canvas_interface->signal_rend_desc_changed().connect(sigc::mem_fun(*this, &WorkArea::refresh_dimension_info));
+       // When either of the scrolling adjustments change, then redraw.
+       get_scrollx_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &WorkArea::queue_scroll));
+       get_scrolly_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &WorkArea::queue_scroll));
+       get_scrollx_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &WorkArea::refresh_dimension_info));
+       get_scrolly_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &WorkArea::refresh_dimension_info));
+
+       get_canvas()->signal_meta_data_changed("grid_size").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("grid_snap").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("grid_show").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("guide_show").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("guide_x").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("guide_y").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("onion_skin").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("guide_snap").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("sketch").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+       get_canvas()->signal_meta_data_changed("solid_lines").connect(sigc::mem_fun(*this,&WorkArea::load_meta_data));
+
+       queued=false;
+       meta_data_lock=false;
+       set_focus_point(Point(0,0));
+
+
+       load_meta_data();       
+       // Load sketch
+       {
+               String data(canvas->get_meta_data("sketch"));
+               if(!data.empty())
+               {
+                       if(!load_sketch(data))
+                               load_sketch(dirname(canvas->get_file_name())+ETL_DIRECTORY_SEPERATOR+basename(data));
+               }
+       }
+
+       hruler->property_max_size()=double(10.0);
+       vruler->property_max_size()=double(10.0);
+
+       drawing_area->set_flags(drawing_area->get_flags()|Gtk::CAN_FOCUS);
+}
+
+WorkArea::~WorkArea()
+{
+//     delete [] buffer;
+}
+
+void
+WorkArea::save_meta_data()
+{
+       if(meta_data_lock)
+               return;
+       meta_data_lock=true;
+
+       Vector s(get_grid_size());
+       canvas_interface->set_meta_data("grid_size",strprintf("%f %f",s[0],s[1]));
+       canvas_interface->set_meta_data("grid_snap",get_grid_snap()?"1":"0");
+       canvas_interface->set_meta_data("guide_snap",get_guide_snap()?"1":"0");
+       canvas_interface->set_meta_data("guide_show",get_show_guides()?"1":"0");
+       canvas_interface->set_meta_data("grid_show",show_grid?"1":"0");
+       canvas_interface->set_meta_data("onion_skin",onion_skin?"1":"0");
+       {
+               String data;
+               GuideList::const_iterator iter;
+               for(iter=get_guide_list_x().begin();iter!=get_guide_list_x().end();++iter)
+               {
+                       if(!data.empty())
+                               data+=' ';
+                       data+=strprintf("%f",*iter);
+               }
+               if(!data.empty())
+                       canvas_interface->set_meta_data("guide_x",data);
+               
+               data.clear();
+               for(iter=get_guide_list_y().begin();iter!=get_guide_list_y().end();++iter)
+               {
+                       if(!data.empty())
+                               data+=' ';
+                       data+=strprintf("%f",*iter);
+               }
+               if(!data.empty())
+                       canvas_interface->set_meta_data("guide_y",data);
+       }
+       
+       if(get_sketch_filename().size())
+       {
+               if(dirname(canvas->get_file_name())==dirname(get_sketch_filename()))
+                       canvas_interface->set_meta_data("sketch",basename(get_sketch_filename()));
+               else
+                       canvas_interface->set_meta_data("sketch",get_sketch_filename());
+       }
+
+       meta_data_lock=false;
+}
+
+void
+WorkArea::load_meta_data()
+{
+       if(meta_data_lock)
+               return;
+       meta_data_lock=true;
+       
+       String data;
+
+       data=canvas->get_meta_data("grid_size");
+       if(!data.empty())
+       {
+               float gx(get_grid_size()[0]),gy(get_grid_size()[1]);
+
+               String::iterator iter(find(data.begin(),data.end(),' '));
+               String tmp(data.begin(),iter);                                          
+               
+               if(!tmp.empty())
+                       gx=stratof(tmp);
+               
+               if(iter==data.end())
+                       tmp.clear();
+               else
+                       tmp=String(iter+1,data.end());
+
+               if(!tmp.empty())
+                       gy=stratof(tmp);
+               
+               set_grid_size(Vector(gx,gy));
+       }
+       else
+               sinfg::error("WorkArea::load_meta_data(): Unable to parse data for \"grid_size\", which was \"%s\"",data.c_str());
+
+       data=canvas->get_meta_data("grid_show");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               show_grid=true;
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               show_grid=false;
+
+       data=canvas->get_meta_data("solid_lines");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               solid_lines=true;
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               solid_lines=false;
+
+       data=canvas->get_meta_data("guide_show");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               show_guides=true;
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               show_guides=false;
+
+       data=canvas->get_meta_data("grid_snap");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               set_grid_snap(true);
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               set_grid_snap(false);
+
+       data=canvas->get_meta_data("guide_snap");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               set_guide_snap(true);
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               set_guide_snap(false);
+
+       data=canvas->get_meta_data("onion_skin");
+       if(data.size() && (data=="1" || data[0]=='t' || data[0]=='T'))
+               set_onion_skin(true);
+       if(data.size() && (data=="0" || data[0]=='f' || data[0]=='F'))
+               set_onion_skin(false);
+       
+       data=canvas->get_meta_data("guide_x");
+       get_guide_list_x().clear();
+       while(!data.empty())
+       {
+               String::iterator iter(find(data.begin(),data.end(),' '));
+               String guide(data.begin(),iter);                                                
+
+               if(!guide.empty())
+                       get_guide_list_x().push_back(stratof(guide));
+               
+               if(iter==data.end())
+                       data.clear();
+               else
+                       data=String(iter+1,data.end());
+       }
+       //sort(get_guide_list_x());
+       
+       data=canvas->get_meta_data("guide_y");
+       get_guide_list_y().clear();
+       while(!data.empty())
+       {
+               String::iterator iter(find(data.begin(),data.end(),' '));
+               String guide(data.begin(),iter);                                                
+
+               if(!guide.empty())
+                       get_guide_list_y().push_back(stratof(guide));
+               
+               if(iter==data.end())
+                       data.clear();
+               else
+                       data=String(iter+1,data.end());
+       }
+       //sort(get_guide_list_y());
+
+       meta_data_lock=false;
+       queue_draw();
+}
+
+void
+WorkArea::set_onion_skin(bool x)
+{
+       if(onion_skin==x)
+               return;
+       onion_skin=x;
+       save_meta_data();
+       queue_render_preview();
+       signal_onion_skin_changed()();
+}
+
+bool
+WorkArea::get_onion_skin()const
+{
+       return onion_skin;
+}
+
+void
+WorkArea::enable_grid()
+{
+       show_grid=true;
+       save_meta_data();
+       queue_draw();
+}
+
+void 
+WorkArea::disable_grid()
+{
+       show_grid=false;
+       save_meta_data();
+       queue_draw();
+}
+
+void
+WorkArea::set_show_guides(bool x)
+{
+       show_guides=x;
+       save_meta_data();
+       queue_draw();
+}
+
+void
+WorkArea::toggle_grid()
+{
+       show_grid=!show_grid;
+       save_meta_data();
+       queue_draw();
+}
+
+void
+WorkArea::set_low_resolution_flag(bool x)
+{
+       if(x!=low_resolution)
+       {
+               low_resolution=x;
+               queue_render_preview();
+       }
+}
+
+void
+WorkArea::toggle_low_resolution_flag()
+{
+       set_low_resolution_flag(!get_low_resolution_flag());
+}
+
+void
+WorkArea::popup_menu()
+{
+       signal_popup_menu()();
+}
+
+void
+WorkArea::set_grid_size(const sinfg::Vector &s)
+{
+       Duckmatic::set_grid_size(s);
+       save_meta_data();
+       queue_draw();
+}
+
+void
+WorkArea::set_focus_point(const sinfg::Point &point)
+{
+       // These next three lines try to ensure that we place the
+       // focus on a pixel boundry
+       /*Point adjusted(point[0]/abs(get_pw()),point[1]/abs(get_ph()));
+       adjusted[0]=(abs(adjusted[0]-floor(adjusted[0]))<0.5)?floor(adjusted[0])*abs(get_pw()):ceil(adjusted[0])*abs(get_ph());
+       adjusted[1]=(abs(adjusted[1]-floor(adjusted[1]))<0.5)?floor(adjusted[1])*abs(get_ph()):ceil(adjusted[1])*abs(get_ph());
+       */
+       const sinfg::Point& adjusted(point);
+       
+       sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       Real x_factor=(rend_desc.get_br()[0]-rend_desc.get_tl()[0]>0)?-1:1;
+       Real y_factor=(rend_desc.get_br()[1]-rend_desc.get_tl()[1]>0)?-1:1;
+
+       get_scrollx_adjustment()->set_value(adjusted[0]*x_factor);
+       get_scrolly_adjustment()->set_value(adjusted[1]*y_factor);      
+}
+
+sinfg::Point
+WorkArea::get_focus_point()const
+{
+       sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       Real x_factor=(rend_desc.get_br()[0]-rend_desc.get_tl()[0]>0)?-1:1;
+       Real y_factor=(rend_desc.get_br()[1]-rend_desc.get_tl()[1]>0)?-1:1;
+       
+       return sinfg::Point(get_scrollx_adjustment()->get_value()*x_factor, get_scrolly_adjustment()->get_value()*y_factor);
+}
+
+bool
+WorkArea::set_wh(int W, int H,int CHAN)
+{
+       // If our size is already set, don't set it again
+       if(W==w && H==h && CHAN==bpp)
+       {
+               return true;
+       }
+       if(W<=0 || H<=0 || CHAN<=0)
+               return false;
+       
+       assert(W>0);
+       assert(H>0);
+       assert(CHAN>0);
+       
+       // Set all of the parameters
+       w=W;
+       h=H;
+       bpp=CHAN;
+
+       refresh_dimension_info();
+
+       tile_book.clear();
+               
+       return true;
+}
+
+bool
+WorkArea::on_key_press_event(GdkEventKey* event)
+{
+       if(get_selected_ducks().empty())
+               return false;
+
+       Real multiplier(1.0);
+       
+       if(Gdk::ModifierType(event->state)&GDK_SHIFT_MASK)
+               multiplier=10.0;
+       
+       Vector nudge;
+       switch(event->keyval)
+       {
+               case GDK_Left:
+                       nudge=Vector(-pw,0);
+                       break;
+               case GDK_Right:
+                       nudge=Vector(pw,0);
+                       break;
+               case GDK_Up:
+                       nudge=Vector(0,-ph);
+                       break;
+               case GDK_Down:
+                       nudge=Vector(0,ph);
+                       break;
+               default:
+                       return false;
+                       break;
+       }
+       
+       sinfgapp::Action::PassiveGrouper grouper(instance.get(),"Nudge");
+       
+       // Grid snap does not apply to nudging
+       bool grid_snap_holder(get_grid_snap());
+       bool guide_snap_holder(get_guide_snap());
+       set_grid_snap(false);
+
+       try {   
+               start_duck_drag(get_selected_duck()->get_trans_point());
+               translate_selected_ducks(get_selected_duck()->get_trans_point()+nudge*multiplier);
+               end_duck_drag();
+       }
+       catch(String)
+       {
+               canvas_view->duck_refresh_flag=true;
+               canvas_view->queue_rebuild_ducks();
+       }
+
+       set_grid_snap(grid_snap_holder);
+       set_guide_snap(guide_snap_holder);
+       
+       return true;
+}
+
+bool
+WorkArea::on_drawing_area_event(GdkEvent *event)
+{
+       sinfg::Point mouse_pos;
+    float bezier_click_pos;
+       const float radius((abs(pw)+abs(ph))*4);
+       int button_pressed(0);
+       float pressure(0);
+       bool is_mouse(false);
+       Gdk::ModifierType modifier(Gdk::ModifierType(0));
+       
+       drawing_area->grab_focus();
+       
+       // Handle input stuff
+       if(
+               event->any.type==GDK_MOTION_NOTIFY ||
+               event->any.type==GDK_BUTTON_PRESS ||
+               event->any.type==GDK_2BUTTON_PRESS ||
+               event->any.type==GDK_3BUTTON_PRESS ||
+               event->any.type==GDK_BUTTON_RELEASE
+       )
+       {
+               GdkDevice *device;
+               if(event->any.type==GDK_MOTION_NOTIFY)
+               {
+                       device=event->motion.device;
+                       modifier=Gdk::ModifierType(event->motion.state);
+               }
+               else
+               {
+                       device=event->button.device;
+                       modifier=Gdk::ModifierType(event->button.state);
+               }
+                       
+               // Make sure we recognise the device
+               if(curr_input_device)
+               {
+                       if(curr_input_device!=device)
+                       {
+                               assert(device);
+                               curr_input_device=device;
+                               signal_input_device_changed()(curr_input_device);
+                       }
+               }               
+               else if(device)
+               {
+                       curr_input_device=device;
+                       signal_input_device_changed()(curr_input_device);
+               }                       
+
+               assert(curr_input_device);
+               
+               // Calculate the position of the
+               // input device in canvas coordinates
+               // and the buttons
+               if(!event->button.axes)
+               {
+                       mouse_pos=sinfg::Point(screen_to_comp_coords(sinfg::Point(event->button.x,event->button.y)));
+                       button_pressed=event->button.button;
+                       pressure=1.0f;
+                       is_mouse=true;
+                       if(isnan(event->button.x) || isnan(event->button.y))
+                               return false;
+               }
+               else
+               {
+                       double x(event->button.axes[0]);
+                       double y(event->button.axes[1]);
+                       if(isnan(x) || isnan(y))
+                               return false;
+
+                       pressure=event->button.axes[2];
+                       //sinfg::info("pressure=%f",pressure);
+                       pressure-=0.04f;
+                       pressure/=1.0f-0.04f;
+                       
+                       
+                       assert(!isnan(pressure));
+                       
+                       mouse_pos=sinfg::Point(screen_to_comp_coords(sinfg::Point(x,y)));
+                       
+                       button_pressed=event->button.button;
+                       
+                       if(button_pressed==1 && pressure<0 && (event->any.type!=GDK_BUTTON_RELEASE && event->any.type!=GDK_BUTTON_PRESS))
+                               button_pressed=0;
+                       if(pressure<0)
+                               pressure=0;
+
+                       //if(event->any.type==GDK_BUTTON_PRESS && button_pressed)
+                       //      sinfg::info("Button pressed on input device = %d",event->button.button);
+                       
+                       //if(event->button.axes[2]>0.1)
+                       //      button_pressed=1;
+                       //else
+                       //      button_pressed=0;                               
+               }
+       }
+
+
+       // Handle the renderables
+       {
+               std::set<etl::handle<WorkAreaRenderer> >::iterator iter;
+               for(iter=renderer_set_.begin();iter!=renderer_set_.end();++iter)
+               {
+                       if((*iter)->get_enabled())
+                               if((*iter)->event_vfunc(event))
+                               {
+                                       // Event handled. Return true.
+                                       return true;
+                               }
+               }
+       }
+
+       // Event hasn't been handled, pass it down
+       switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               {
+               switch(button_pressed)
+               {
+               case 1: // Attempt to click on a duck
+               {       
+                       etl::handle<Duck> duck;
+                       dragging=DRAG_NONE;
+                       
+                       if(allow_duck_clicks)
+                       {
+                               duck=find_duck(mouse_pos,radius);
+                               
+                               if(duck)
+                               {
+                                       clicked_duck=0;
+                                       if(duck_is_selected(duck))
+                                       {
+                                               clicked_duck=duck;
+                                       }
+                                       else
+                                       {
+                                               if(modifier&GDK_SHIFT_MASK)
+                                               {
+                                                       select_duck(duck);
+                                               }
+                                               else if(modifier&GDK_CONTROL_MASK)
+                                               {
+                                                       select_duck(duck);
+                                               }
+                                               else
+                                               {
+                                                       clear_selected_ducks();
+                                                       select_duck(duck);
+                                               }
+                                       }
+                               }
+                       }
+                       //else
+                       //      clear_selected_ducks();
+                               
+               
+               
+                       selected_bezier=find_bezier(mouse_pos,radius,&bezier_click_pos);
+                       if(duck && duck->get_editable())
+                       {
+                               //get_selected_duck()->signal_user_click(0)();
+                               //if(clicked_duck)clicked_duck->signal_user_click(0)();
+                               dragging=DRAG_DUCK;
+                               drag_point=mouse_pos;
+                               //drawing_area->queue_draw();
+                               start_duck_drag(mouse_pos);
+                               get_canvas_view()->reset_cancel_status();
+                               return true;
+                       }
+// I commented out this section because
+// it was causing issues when rotoscoping.
+// At the moment, we don't need it, so 
+// this was the easiest way to fix the problem.
+/*
+                       else
+                       if(selected_bezier)
+                       {
+                               selected_duck=0;
+                               selected_bezier->signal_user_click(0)(bezier_click_pos);
+                       }
+*/
+                       else
+                       {
+                               //clear_selected_ducks();
+                               selected_bezier=0;
+                               if(canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,BUTTON_LEFT,mouse_pos,pressure,modifier))==Smach::RESULT_OK)
+                               {
+                                       // Check for a guide click
+                                       GuideList::iterator iter;
+                                       
+                                       iter=find_guide_x(mouse_pos,radius);
+                                       if(iter==get_guide_list_x().end())
+                                       {
+                                               curr_guide_is_x=false;
+                                               iter=find_guide_y(mouse_pos,radius);
+                                       }
+                                       else
+                                               curr_guide_is_x=true;
+                                       if(iter!=get_guide_list_x().end() && iter!=get_guide_list_y().end())
+                                       {
+                                               dragging=DRAG_GUIDE;
+                                               curr_guide=iter;
+                                               return true;
+                                       }
+
+
+                                       // All else fails, try making a selection box
+                                       dragging=DRAG_BOX;
+                                       curr_point=drag_point=mouse_pos;
+                                       return true;
+                               }
+                       }
+                       break;
+               }
+               case 2: // Attempt to drag and move the window
+               {
+                       etl::handle<Duck> duck=find_duck(mouse_pos,radius);
+                       etl::handle<Bezier> bezier=find_bezier(mouse_pos,radius,&bezier_click_pos);
+                       if(duck)
+                               duck->signal_user_click(1)();
+                       else
+                       if(bezier)
+                               bezier->signal_user_click(1)(bezier_click_pos);
+
+                       if(canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,BUTTON_MIDDLE,mouse_pos,pressure,modifier))==Smach::RESULT_OK)
+                       if(is_mouse)
+                       {
+                               dragging=DRAG_WINDOW;
+                               drag_point=mouse_pos;
+                               signal_user_click(1)(mouse_pos);
+                       }
+                       break;
+               }
+               case 3: // Attempt to either get info on a duck, or open the menu
+               {
+                       etl::handle<Duck> duck=find_duck(mouse_pos,radius);
+                       etl::handle<Bezier> bezier=find_bezier(mouse_pos,radius,&bezier_click_pos);
+                       
+                       Layer::Handle layer(get_canvas()->find_layer(mouse_pos));
+                       if(duck)
+                       {
+                               if(get_selected_ducks().size()<=1)
+                                       duck->signal_user_click(2)();
+                               else
+                               {
+                                       canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,BUTTON_RIGHT,mouse_pos,pressure,modifier));
+                               }
+                               return true;
+                       }
+                       else
+                       if(bezier)
+                       {
+                               bezier->signal_user_click(2)(bezier_click_pos);
+                               return true;
+                       }
+                       else 
+                       if(layer)
+                       {
+                               if(canvas_view->get_smach().process_event(EventLayerClick(layer,BUTTON_RIGHT,mouse_pos))==Smach::RESULT_OK)                                             
+                                       return false;
+                               return true;
+                       }
+                       else
+                               canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,BUTTON_RIGHT,mouse_pos,pressure,modifier));                  
+                       /*
+                       if(canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,BUTTON_RIGHT,mouse_pos,pressure,modifier))==Smach::RESULT_OK)
+                       {
+                               //popup_menu();
+                               return true;
+                       }
+                       */
+                       break;
+               }
+               case 4:
+                       signal_user_click(3)(mouse_pos);
+                       break;
+               case 5:
+                       signal_user_click(4)(mouse_pos);
+                       break;
+               default:
+                       break;
+               }
+               }
+               break;
+       case GDK_MOTION_NOTIFY:
+               curr_point=mouse_pos;
+
+               if(event->motion.time-last_event_time<25)
+                       return true;
+               else
+                       last_event_time=event->motion.time;
+
+               signal_cursor_moved_();
+       
+               // Guide/Duck hilights on hover
+               if(dragging==DRAG_NONE)
+               {
+                       GuideList::iterator iter;
+                       
+                       iter=find_guide_x(mouse_pos,radius);
+                       if(iter==get_guide_list_x().end())
+                               iter=find_guide_y(mouse_pos,radius);
+                       
+                       if(iter!=curr_guide)
+                       {
+                               curr_guide=iter;
+                               drawing_area->queue_draw();
+                       }
+
+                       etl::handle<Duck> duck;
+                       duck=find_duck(mouse_pos,radius);
+                       if(duck!=hover_duck)
+                       {
+                               hover_duck=duck;
+                               drawing_area->queue_draw();
+                       }
+               }
+
+       
+               if(dragging==DRAG_DUCK)
+               {
+                       if(canvas_view->get_cancel_status())
+                       {
+                               dragging=DRAG_NONE;
+                               canvas_view->queue_rebuild_ducks();
+                               return true;
+                       }
+                       /*
+                       Point point((mouse_pos-selected_duck->get_origin())/selected_duck->get_scalar());
+                       if(get_grid_snap())
+                       {
+                               point[0]=floor(point[0]/grid_size[0]+0.5)*grid_size[0];
+                               point[1]=floor(point[1]/grid_size[1]+0.5)*grid_size[1];
+                       }
+                       selected_duck->set_point(point);
+                       */
+                       
+                       //Point p(mouse_pos);
+                       
+                       set_axis_lock(event->motion.state&GDK_SHIFT_MASK);
+                       
+                       translate_selected_ducks(mouse_pos);
+                       
+                       drawing_area->queue_draw();
+               }
+               if(dragging==DRAG_BOX)
+               {
+                       curr_point=mouse_pos;
+                       drawing_area->queue_draw();
+               }
+               if(dragging==DRAG_GUIDE)
+               {
+                       if(curr_guide_is_x)
+                               *curr_guide=mouse_pos[0];
+                       else
+                               *curr_guide=mouse_pos[1];
+                       drawing_area->queue_draw();
+               }
+               if(dragging!=DRAG_WINDOW)
+               {       // Update those triangle things on the rulers
+                       const sinfg::Point point(mouse_pos);
+                       hruler->property_position()=Distance(point[0],Distance::SYSTEM_UNITS).get(App::distance_system,get_canvas()->rend_desc());
+                       vruler->property_position()=Distance(point[1],Distance::SYSTEM_UNITS).get(App::distance_system,get_canvas()->rend_desc());
+               }
+               if(dragging==DRAG_WINDOW)
+               {
+                       set_focus_point(get_focus_point()+mouse_pos-drag_point);
+               }
+               else
+               if(event->motion.state&GDK_BUTTON1_MASK && canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,BUTTON_LEFT,mouse_pos,pressure,modifier))==Smach::RESULT_ACCEPT)
+                       return true;
+               else
+               if(event->motion.state&GDK_BUTTON2_MASK && canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,BUTTON_MIDDLE,mouse_pos,pressure,modifier))==Smach::RESULT_ACCEPT)
+                       return true;
+               else
+               if(event->motion.state&GDK_BUTTON3_MASK && canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,BUTTON_RIGHT,mouse_pos,pressure,modifier))==Smach::RESULT_ACCEPT)
+                       return true;
+               else
+               if(canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_MOTION,BUTTON_NONE,mouse_pos,pressure,modifier))==Smach::RESULT_ACCEPT)
+                       return true;
+
+               break;
+       case GDK_BUTTON_RELEASE:
+       {
+               bool ret(false);
+
+               if(dragging==DRAG_GUIDE)
+               {
+                       dragging=DRAG_NONE;
+                       save_meta_data();
+                       return true;
+               }
+               else
+               if(dragging==DRAG_DUCK)
+               {                       
+                       sinfgapp::Action::PassiveGrouper grouper(instance.get(),"Move");
+                       dragging=DRAG_NONE;
+                       //translate_selected_ducks(mouse_pos);
+                       set_axis_lock(false);
+                       
+                       try{
+                       get_canvas_view()->duck_refresh_flag=false;
+                       get_canvas_view()->duck_refresh_needed=false;
+                       const bool drag_did_anything(end_duck_drag());
+                       get_canvas_view()->duck_refresh_flag=true;
+                       if(!drag_did_anything)
+                       {
+                               //etl::handle<Duck> duck=find_duck(mouse_pos,radius);
+                               
+                               if(modifier&GDK_SHIFT_MASK)
+                               {
+                                       //sinfg::info("DUCK_DRAG_RELEASE: SHIFT-MASK ON!");
+                                       if(clicked_duck)
+                                       {
+                                               //sinfg::info("DUCK_DRAG_RELEASE: CLICKED DUCK!");
+                                               unselect_duck(clicked_duck);
+                                       }
+                               }
+                               else if(modifier&GDK_CONTROL_MASK)
+                               {
+                                       //sinfg::info("DUCK_DRAG_RELEASE: CONTROL-MASK ON!");
+                                       if(clicked_duck)
+                                       {
+                                               //sinfg::info("DUCK_DRAG_RELEASE: CLICKED DUCK!");
+                                               unselect_duck(clicked_duck);
+                                       }
+                               }
+                               else
+                               {
+                                       //sinfg::info("DUCK_DRAG_RELEASE: NO MASK!");
+                                       if(clicked_duck)
+                                       {
+                                               //sinfg::info("DUCK_DRAG_RELEASE: CLICKED DUCK!");
+                                               clear_selected_ducks();
+                                               select_duck(clicked_duck);
+                                       }
+                               }               
+                               if(clicked_duck)clicked_duck->signal_user_click(0)();
+                       }
+                       else
+                       {
+                               if(canvas_view->duck_refresh_needed)
+                                       canvas_view->queue_rebuild_ducks();
+                               return true;
+                       }
+                       }catch(String)
+                       {
+                               canvas_view->duck_refresh_flag=true;
+                               canvas_view->queue_rebuild_ducks();
+                               return true;
+                       }
+                       //queue_draw();
+                       clicked_duck=0;
+
+                       ret=true;
+               }
+               
+               if(dragging==DRAG_BOX)
+               {                       
+                       dragging=DRAG_NONE;
+                       if((drag_point-mouse_pos).mag()>radius/2.0f)
+                       {
+                               if(canvas_view->get_smach().process_event(EventBox(drag_point,mouse_pos,MouseButton(event->button.button),modifier))==Smach::RESULT_ACCEPT)
+                                       return true;
+
+                               if(!(modifier&GDK_CONTROL_MASK) && !(modifier&GDK_SHIFT_MASK))
+                                       clear_selected_ducks();
+                               select_ducks_in_box(drag_point,mouse_pos);
+                               ret=true;
+                       }
+                       else
+                       {       
+                               if(allow_layer_clicks)
+                               {
+                                       Layer::Handle layer(get_canvas()->find_layer(drag_point));
+                                       //if(layer)
+                                       {
+                                               if(canvas_view->get_smach().process_event(EventLayerClick(layer,BUTTON_LEFT,mouse_pos,modifier))==Smach::RESULT_OK)                                             
+                                                       signal_layer_selected_(layer);
+                                               ret=true;
+                                       }
+                               }
+                               else
+                               {
+                                       signal_user_click(0)(mouse_pos);
+                               }
+                       }
+               }
+               
+               dragging=DRAG_NONE;
+
+               if(canvas_view->get_smach().process_event(EventMouse(EVENT_WORKAREA_MOUSE_BUTTON_UP,MouseButton(event->button.button),mouse_pos,pressure,modifier))==Smach::RESULT_ACCEPT)
+                       ret=true;
+               
+               return ret;
+       }
+               break;
+       default:
+               break;
+       }
+               return false;
+}
+
+bool
+WorkArea::on_hruler_event(GdkEvent *event)
+{
+/*
+       switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               if(dragging==DRAG_NONE)
+               {
+                       dragging=DRAG_GUIDE;
+                       curr_guide=get_guide_list_y().insert(get_guide_list_y().begin());
+                       curr_guide_is_x=false;
+               }
+               return true;
+               break;
+
+       case GDK_MOTION_NOTIFY:
+               // Guide movement
+               if(dragging==DRAG_GUIDE && curr_guide_is_x==false)
+               {
+                       double y,x;
+                       if(event->button.axes)
+                       {
+                               x=(event->button.axes[0]);
+                               y=(event->button.axes[1]);
+                       }
+                       else
+                       {
+                               x=event->button.x;
+                               y=event->button.y;
+                       }
+                       
+                       if(isnan(y) || isnan(x))
+                               return false;                   
+                       
+                       *curr_guide=sinfg::Point(screen_to_comp_coords(sinfg::Point(x,y)))[1];
+
+                       queue_draw();
+               }
+               return true;
+               break;
+               
+       case GDK_BUTTON_RELEASE:
+               if(dragging==DRAG_GUIDE && curr_guide_is_x==false)
+               {
+                       dragging=DRAG_NONE;
+                       get_guide_list_y().erase(curr_guide);
+               }
+               break;
+               return true;
+       default:
+               break;
+       }
+*/
+       return false;
+}
+
+bool
+WorkArea::on_vruler_event(GdkEvent *event)
+{
+/*
+       switch(event->type)
+    {
+       case GDK_BUTTON_PRESS:
+               DEBUGPOINT();
+               if(dragging==DRAG_NONE)
+               {
+                       DEBUGPOINT();
+                       dragging=DRAG_GUIDE;
+                       curr_guide=get_guide_list_x().insert(get_guide_list_x().begin());
+                       curr_guide_is_x=true;
+               }
+               return true;
+               break;
+       case GDK_BUTTON_RELEASE:
+               DEBUGPOINT();
+               if(dragging==DRAG_GUIDE && curr_guide_is_x==true)
+               {
+                       DEBUGPOINT();
+                       dragging=DRAG_NONE;
+                       get_guide_list_x().erase(curr_guide);
+               }
+               break;
+               return true;
+       default:
+               break;
+       }
+*/
+       return false;
+}
+
+
+void
+WorkArea::refresh_dimension_info()
+{
+       sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+
+       canvaswidth=rend_desc.get_br()[0]-rend_desc.get_tl()[0];
+       canvasheight=rend_desc.get_br()[1]-rend_desc.get_tl()[1];
+
+       pw=canvaswidth/w;
+       ph=canvasheight/h;      
+
+       scrollx_adjustment.set_page_increment(abs(get_grid_size()[0]));
+       scrollx_adjustment.set_step_increment(abs(pw));
+       scrollx_adjustment.set_lower(-abs(canvaswidth));
+       scrollx_adjustment.set_upper(abs(canvaswidth));
+       scrolly_adjustment.set_lower(-abs(canvasheight));
+       scrolly_adjustment.set_upper(abs(canvasheight));
+       scrolly_adjustment.set_step_increment(abs(ph));
+       scrolly_adjustment.set_page_increment(abs(get_grid_size()[1]));
+
+
+       
+       if(drawing_area->get_width()<=0 || drawing_area->get_height()<=0 || w==0 || h==0)
+               return;
+       
+       const sinfg::Point focus_point(get_focus_point());
+       const sinfg::Real x(focus_point[0]/pw+drawing_area->get_width()/2-w/2);
+       const sinfg::Real y(focus_point[1]/ph+drawing_area->get_height()/2-h/2);
+       
+       window_tl[0]=rend_desc.get_tl()[0]-pw*x;
+       window_br[0]=rend_desc.get_br()[0]+pw*(drawing_area->get_width()-x-w);
+
+       window_tl[1]=rend_desc.get_tl()[1]-ph*y;
+       window_br[1]=rend_desc.get_br()[1]+ph*(drawing_area->get_height()-y-h);
+       
+       hruler->property_lower()=Distance(window_tl[0],Distance::SYSTEM_UNITS).get(App::distance_system,rend_desc);
+       hruler->property_upper()=Distance(window_br[0],Distance::SYSTEM_UNITS).get(App::distance_system,rend_desc);
+       vruler->property_lower()=Distance(window_tl[1],Distance::SYSTEM_UNITS).get(App::distance_system,rend_desc);
+       vruler->property_upper()=Distance(window_br[1],Distance::SYSTEM_UNITS).get(App::distance_system,rend_desc);
+
+       view_window_changed();
+}
+
+
+sinfg::Point
+WorkArea::screen_to_comp_coords(sinfg::Point pos)const
+{
+       sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       //sinfg::Vector::value_type canvaswidth=rend_desc.get_br()[0]-rend_desc.get_tl()[0];
+       //sinfg::Vector::value_type canvasheight=rend_desc.get_br()[1]-rend_desc.get_tl()[1];
+       //sinfg::Vector::value_type pw=canvaswidth/w;
+       //sinfg::Vector::value_type ph=canvasheight/h;
+       Vector focus_point=get_focus_point();
+       sinfg::Vector::value_type x=focus_point[0]/pw+drawing_area->get_width()/2-w/2;
+       sinfg::Vector::value_type y=focus_point[1]/ph+drawing_area->get_height()/2-h/2;
+
+       return rend_desc.get_tl()-sinfg::Point(pw*x,ph*y)+sinfg::Point(pw*pos[0],ph*pos[1]);
+}
+
+sinfg::Point
+WorkArea::comp_to_screen_coords(sinfg::Point pos)const
+{
+       sinfg::warning("WorkArea::comp_to_screen_coords: Not yet implemented");
+       return sinfg::Point();
+}
+
+int
+WorkArea::next_unrendered_tile(int refreshes)const
+{
+       //assert(!tile_book.empty());
+       if(tile_book.empty())
+               return -1;
+
+       //const sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_focus_point());
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+       const sinfg::Vector::value_type
+               x(focus_point[0]/pw+drawing_area->get_width()/2-w/2),
+               y(focus_point[1]/ph+drawing_area->get_height()/2-h/2);
+       
+       const int width_in_tiles(w/tile_w+(w%tile_w?1:0));
+       const int height_in_tiles(h/tile_h+(h%tile_h?1:0));
+                       
+       int
+               u(0),v(0),
+               u1(int(-x/tile_w)),
+               v1(int(-y/tile_h)),
+               u2(int((-x+drawing_area->get_width())/tile_w+1)),
+               v2(int((-y+drawing_area->get_height())/tile_h+1));
+       
+       if(u2>width_in_tiles)u2=width_in_tiles;
+       if(v2>height_in_tiles)v2=height_in_tiles;
+       if(u1<0)u1=0;
+       if(v1<0)v1=0;
+               
+       int last_good_tile(-1);
+       
+       for(v=v1;v<v2;v++)
+               for(u=u1;u<u2;u++)
+               {
+                       int index(v*width_in_tiles+u);
+                       if(tile_book[index].second<refreshes)
+                       {
+                               last_good_tile=index;
+                               if(rand()%8==0)
+                                       return index;
+                       }
+               }
+       return last_good_tile;
+}
+
+/*
+template <typename F, typename T=WorkAreaRenderer, typename R=typename F::result_type>
+class handle2ptr_t : public std::unary_function<typename etl::handle<T>,R>
+{
+private:
+       F func;
+public:
+       handle2ptr_t(const F &func):func(func) { };
+       
+       R operator()(typename etl::handle<T> x) { return func(*x); }
+};
+
+template <typename F>
+handle2ptr_t<F>
+handle2ptr(F func)
+{
+       return handle2ptr_t<F>(func);
+}
+       for_each(
+               renderer_set_.begin(),
+               renderer_set_.end(),
+               handle2ptr(
+                       sigc::bind(
+                               sigc::bind(
+                                       sigc::mem_fun(
+                                               &WorkAreaRenderer::render_vfunc
+                                       ),
+                                       Gdk::Rectangle(event->area)
+                               ),
+                               drawing_area->get_window()
+                       )
+               )
+       );
+*/
+
+bool
+WorkArea::refresh(GdkEventExpose*event)
+{
+       assert(get_canvas());
+
+       drawing_area->get_window()->clear();
+       
+       //const sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       
+       const sinfg::Vector focus_point(get_focus_point());
+       
+       // Update the old focus point
+       last_focus_point=focus_point;
+       
+       // Draw out the renderables
+       {
+               std::set<etl::handle<WorkAreaRenderer> >::iterator iter;
+               for(iter=renderer_set_.begin();iter!=renderer_set_.end();++iter)
+               {
+                       if((*iter)->get_enabled())
+                               (*iter)->render_vfunc(
+                                       drawing_area->get_window(),
+                                       Gdk::Rectangle(&event->area)
+                               );
+               }
+       }
+       
+       
+       // Calculate the window coordinates of the top-left
+       // corner of the canvas.
+       //const sinfg::Vector::value_type
+       //      x(focus_point[0]/pw+drawing_area->get_width()/2-w/2),
+       //      y(focus_point[1]/ph+drawing_area->get_height()/2-h/2);
+
+       //const sinfg::Vector::value_type window_startx(window_tl[0]);
+       //const sinfg::Vector::value_type window_endx(window_br[0]);
+       //const sinfg::Vector::value_type window_starty(window_tl[1]);
+       //const sinfg::Vector::value_type window_endy(window_br[1]);
+       
+       Glib::RefPtr<Gdk::GC> gc=Gdk::GC::create(drawing_area->get_window());
+
+
+
+       // If we are in animate mode, draw a red border around the screen
+       if(canvas_interface->get_mode()&sinfgapp::MODE_ANIMATE)
+       {
+               /*gc->set_rgb_fg_color(Gdk::Color("#FF0000"));
+               gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);       
+               drawing_area->get_window()->draw_rectangle(
+                       gc,
+                       false,  // Fill?
+                       0,0,    // x,y
+                       drawing_area->get_width()-1,drawing_area->get_height()-1        //w,h
+               );
+               */
+               drawing_frame->modify_bg(Gtk::STATE_NORMAL,Gdk::Color("#FF0000"));
+               //get_window()->set_background(Gdk::Color("#FF0000"));
+       }
+       else
+               drawing_frame->unset_bg(Gtk::STATE_NORMAL);
+
+
+
+       previous_focus=get_focus_point();       
+
+       return true;
+}
+
+void
+WorkArea::done_rendering()
+{
+/*
+       assert(buffer);
+       assert(w>0);
+       assert(h>0);
+       pix_buf=Gdk::Pixbuf::create_from_data(
+               buffer, // pointer to the data
+               Gdk::COLORSPACE_RGB, // the colorspace
+               true, // has alpha?
+               8, // bits per sample
+               w,      // width
+               h,      // height
+               w*bpp); // stride (pitch)
+       assert(pix_buf);
+*/
+}
+
+
+void
+WorkArea::set_quality(int x)
+{
+       if(x==quality)
+               return;
+       quality=x;
+       queue_render_preview();
+}
+
+
+class WorkAreaProgress : public sinfg::ProgressCallback
+{
+       WorkArea *work_area;
+       ProgressCallback *cb;
+
+public:
+
+       WorkAreaProgress(WorkArea *work_area,ProgressCallback *cb):
+               work_area(work_area),cb(cb)
+       {
+               assert(cb);
+       }
+
+       virtual bool
+       task(const std::string &str)
+       {
+               if(work_area->dirty)
+                       return false;
+               return cb->task(str);
+       }
+
+       virtual bool
+       error(const std::string &err)
+       {
+               if(work_area->dirty)
+                       return false;
+               return cb->error(err);
+       }
+
+       virtual bool
+       amount_complete(int current, int total)
+       {
+               if(work_area->dirty)
+                       return false;
+               return cb->amount_complete(current,total);
+       }
+};
+
+bool
+studio::WorkArea::async_update_preview()
+{
+       async_renderer=0;
+
+       queued=false;
+       canceled_=false;
+       get_canvas_view()->reset_cancel_status();
+
+       // This object will mark us as busy until
+       // we are done.
+       //studio::App::Busy busy;
+       
+       //WorkAreaProgress callback(this,get_canvas_view()->get_ui_interface().get());
+       //sinfg::ProgressCallback *cb=&callback;
+
+       if(!is_visible())return false;
+       
+       /*
+       // If we are queued to render the scene at the next idle
+       // go ahead and de-queue it. 
+       if(render_idle_func_id)
+       {
+               g_source_remove(render_idle_func_id);           
+               //queued=false;
+               render_idle_func_id=0;
+       }
+       */
+       
+       dirty=false;
+       get_canvas_view()->reset_cancel_status();
+       
+       //bool ret=false;
+       RendDesc desc=get_canvas()->rend_desc();
+       
+       int w=(int)(desc.get_w()*zoom);
+       int h=(int)(desc.get_h()*zoom);
+               
+       // Setup the description parameters
+       desc.set_antialias(1);  
+       desc.set_time(cur_time);
+       
+       set_rend_desc(desc);
+
+       // Create the render target
+       handle<Target> target;
+       
+       if(w*h>(low_resolution?480*270:480*270/2))
+       {
+               handle<WorkAreaTarget> trgt(new class WorkAreaTarget(this,w,h));
+
+               trgt->set_rend_desc(&desc);
+               trgt->set_onion_skin(get_onion_skin());
+               target=trgt;
+       }
+       else
+       {
+               handle<WorkAreaTarget_Full> trgt(new class WorkAreaTarget_Full(this,w,h));
+
+               trgt->set_rend_desc(&desc);
+               trgt->set_onion_skin(get_onion_skin());
+               target=trgt;
+       }
+       
+       // We can rest assured that our time has already
+       // been set, so there is no need to have to
+       // recalculate that over again.
+       // UPDATE: This is kind of needless with
+       // the way that time is handled now in SINFG.
+       //target->set_avoid_time_sync(true);
+       async_renderer=new AsyncRenderer(target);
+       async_renderer->signal_finished().connect(
+               sigc::mem_fun(this,&WorkArea::async_update_finished)
+       );
+
+       rendering=true;
+       async_renderer->start();
+
+       sinfg::ProgressCallback *cb=get_canvas_view()->get_ui_interface().get();
+
+       rendering=true;
+       cb->task("Rendering...");
+       rendering=true;
+       
+       return true;
+}
+
+void 
+studio::WorkArea::async_update_finished()
+{
+       sinfg::ProgressCallback *cb=get_canvas_view()->get_ui_interface().get();
+
+       rendering=false;
+
+       if(!async_renderer)
+               return;
+       
+       // If we completed successfuly, then
+       // we aren't dirty anymore
+       if(async_renderer->has_success())
+       {
+               dirty=false;
+               //queued=false;
+               cb->task("Idle");
+       }
+       else
+       {
+               dirty=true;
+               cb->task("Render Failed");
+       }
+       //get_canvas_view()->reset_cancel_status();
+       done_rendering();
+}
+
+bool
+studio::WorkArea::sync_update_preview()
+{
+       //      const Time &time(cur_time);
+
+       canceled_=false;
+       get_canvas_view()->reset_cancel_status();
+
+       async_renderer=0;
+
+again:
+       // This object will mark us as busy until
+       // we are done.
+       studio::App::Busy busy;
+       
+       WorkAreaProgress callback(this,get_canvas_view()->get_ui_interface().get());
+       sinfg::ProgressCallback *cb=&callback;
+       
+       // We don't want to render if we are already rendering
+       if(rendering)
+       {
+               dirty=true;
+               return false;
+       }
+
+       if(!is_visible())return false;
+       get_canvas()->set_time(get_time());     
+       get_canvas_view()->get_smach().process_event(EVENT_REFRESH_DUCKS);
+       signal_rendering()();
+       
+       // If we are queued to render the scene at the next idle
+       // go ahead and de-queue it. 
+       if(render_idle_func_id)
+       {
+               g_source_remove(render_idle_func_id);           
+               //queued=false;
+               render_idle_func_id=0;
+       }
+       // Start rendering
+       rendering=true;
+       
+       dirty=false;
+       get_canvas_view()->reset_cancel_status();
+       
+       bool ret=false;
+       RendDesc desc=get_canvas()->rend_desc();
+       //newdesc->set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
+       
+       int w=(int)(desc.get_w()*zoom);
+       int h=(int)(desc.get_h()*zoom);
+               
+       // Setup the description parameters
+       desc.set_antialias(1);  
+       desc.set_time(cur_time);
+       //desc.set_wh(w,h);
+       
+       set_rend_desc(desc);
+
+       // Create the render target
+       handle<WorkAreaTarget> target(new class WorkAreaTarget(this,w,h));
+
+       target->set_rend_desc(&desc);
+
+       // We can rest assured that our time has already
+       // been set, so there is no need to have to
+       // recalculate that over again.
+       target->set_avoid_time_sync(true);
+       
+       if(cb)
+               cb->task(strprintf("Rendering canvas %s...",get_canvas()->get_name().c_str()));
+
+       target->render(cb);
+       
+       if(!ret && !get_canvas_view()->get_cancel_status() && dirty)
+       {
+               rendering=false;
+               //canceled_=true;
+               goto again;
+       }
+       if(get_canvas_view()->get_cancel_status())
+               canceled_=true;
+       
+       if(cb)
+       {
+               if(ret)
+                       cb->task("Idle");
+               else
+                       cb->task("Render Failed");
+               cb->amount_complete(0,1);                       
+       }
+
+       // Refresh the work area to make sure that
+       // it is being displayed correctly
+       drawing_area->queue_draw();
+               
+       // If we completed successfuly, then
+       // we aren't dirty anymore
+       if(ret)
+       {
+               dirty=false;
+               //queued=false;
+       }
+       else dirty=true;
+       rendering=false;
+       //get_canvas_view()->reset_cancel_status();
+       done_rendering();
+       return ret;
+}
+
+void
+studio::WorkArea::async_render_preview(Time time)
+{
+       cur_time=time;
+       //tile_book.clear();
+
+       refreshes+=5;
+       if(!is_visible())return;
+
+       get_canvas()->set_time(get_time());     
+       get_canvas_view()->get_smach().process_event(EVENT_REFRESH_DUCKS);
+       signal_rendering()();
+
+       async_update_preview();
+}
+void
+WorkArea::async_render_preview()
+{
+       return async_render_preview(get_canvas_view()->get_time());
+}
+
+bool
+studio::WorkArea::sync_render_preview(Time time)
+{
+       cur_time=time;
+       //tile_book.clear();
+       refreshes+=5;
+       if(!is_visible())return false;
+       return sync_update_preview();
+}
+
+bool
+WorkArea::sync_render_preview()
+{
+       return sync_render_preview(get_canvas_view()->get_time());
+}
+
+void
+WorkArea::sync_render_preview_hook()
+{
+       sync_render_preview(get_canvas_view()->get_time());
+}
+
+void
+WorkArea::queue_scroll()
+{
+//     const sinfg::RendDesc &rend_desc(get_canvas()->rend_desc());
+       
+       const sinfg::Point focus_point(get_focus_point());
+       
+       const sinfg::Real
+               new_x(focus_point[0]/pw+drawing_area->get_width()/2-w/2),
+               new_y(focus_point[1]/ph+drawing_area->get_height()/2-h/2);
+
+       const sinfg::Real
+               old_x(last_focus_point[0]/pw+drawing_area->get_width()/2-w/2),
+               old_y(last_focus_point[1]/ph+drawing_area->get_height()/2-h/2);
+
+       // If the coordinates didn't change, we shouldn't queue a draw
+       if(old_x==new_x && old_y==new_y)
+               return;
+
+       const int
+               dx(round_to_int(old_x)-round_to_int(new_x)),    
+               dy(round_to_int(old_y)-round_to_int(new_y));
+       
+       drawing_area->get_window()->scroll(-dx,-dy);
+
+       /*drawing_area->queue_draw_area(
+               0,
+               0,
+               128,
+               64
+       );
+       */
+       last_focus_point=focus_point;
+}
+
+void
+studio::WorkArea::zoom_in()
+{
+       set_zoom(zoom*1.25);
+}
+
+void
+studio::WorkArea::zoom_out()
+{
+       set_zoom(zoom/1.25);
+}
+
+void
+studio::WorkArea::zoom_fit()
+{
+       // This really doesn't zoom to fit. Bug.
+       zoom_norm();
+}
+
+void
+studio::WorkArea::zoom_norm()
+{
+       if(zoom==1.0)
+               set_zoom(prev_zoom);
+       else
+       {
+               prev_zoom=zoom;
+               set_zoom(1.0f);
+       }
+}
+
+gboolean
+studio::WorkArea::__render_preview(gpointer data)
+{
+
+       WorkArea *work_area(static_cast<WorkArea*>(data));
+
+       work_area->queued=false;
+       work_area->async_render_preview(work_area->get_canvas_view()->get_time());
+
+       return 0;
+}
+
+void
+studio::WorkArea::queue_render_preview()
+{
+       //sinfg::info("queue_render_preview(): called for %s", get_canvas_view()->get_time().get_string().c_str());
+
+       if(queued==true)
+       {
+               return;
+               //sinfg::info("queue_render_preview(): already queued, unqueuing");
+/*             if(render_idle_func_id)
+                       g_source_remove(render_idle_func_id);
+               render_idle_func_id=0;
+               queued=false;
+*/
+               //async_renderer=0;
+       }
+       
+       if(dirty_trap_enabled)
+       {
+               dirty_trap_queued++;
+               return;
+       }
+       
+       int queue_time=50;
+       
+       if(rendering)
+               queue_time+=250;
+       
+
+       if(queued==false)
+       {
+               //sinfg::info("queue_render_preview(): (re)queuing...");
+               //render_idle_func_id=g_idle_add_full(G_PRIORITY_DEFAULT,__render_preview,this,NULL);
+               render_idle_func_id=g_timeout_add_full(G_PRIORITY_DEFAULT,queue_time,__render_preview,this,NULL);
+               queued=true;
+       }
+/*     else if(rendering)
+       {
+               refreshes+=5;
+               dirty=true;
+               queue_draw();
+       }
+*/
+}
+
+DirtyTrap::DirtyTrap(WorkArea *work_area):work_area(work_area)
+{
+       work_area->dirty_trap_enabled=true;
+       
+       work_area->dirty_trap_queued=0;
+}
+
+DirtyTrap::~DirtyTrap()
+{
+       work_area->dirty_trap_enabled=false;
+       if(work_area->dirty_trap_queued)
+               work_area->queue_render_preview();
+}
+
+void
+studio::WorkArea::queue_draw_preview()
+{
+       drawing_area->queue_draw();
+}
+
+void
+studio::WorkArea::set_cursor(const Gdk::Cursor& x)
+{
+       drawing_area->get_window()->set_cursor(x);
+}
+void
+studio::WorkArea::set_cursor(Gdk::CursorType x)
+{
+       drawing_area->get_window()->set_cursor(Gdk::Cursor(x));
+}
+
+#include "iconcontroler.h"
+
+void
+studio::WorkArea::refresh_cursor()
+{
+//     set_cursor(IconControler::get_tool_cursor(canvas_view->get_smach().get_state_name(),drawing_area->get_window()));
+}
+
+void
+studio::WorkArea::reset_cursor()
+{
+       drawing_area->get_window()->set_cursor(Gdk::Cursor(Gdk::TOP_LEFT_ARROW));
+//     set_cursor(Gdk::TOP_LEFT_ARROW);
+}
+
+void
+studio::WorkArea::set_zoom(float z)
+{
+       z=max(1.0f/128.0f,min(128.0f,z));
+       if(z==zoom)
+               return;
+       zoom = z;
+       refresh_dimension_info();
+       /*if(async_renderer)
+       {
+               async_renderer->stop();
+               async_renderer=0;
+       }*/
+       refreshes+=5;
+       async_update_preview();
+       //queue_render_preview();
+}
+
+void
+WorkArea::set_selected_value_node(etl::loose_handle<sinfg::ValueNode> x)
+{
+       if(x!=selected_value_node_)
+       {
+               selected_value_node_=x;
+               queue_draw();
+       }
+}
+
+void
+WorkArea::insert_renderer(const etl::handle<WorkAreaRenderer> &x)
+{
+       renderer_set_.insert(x);
+       x->set_work_area(this);
+       queue_draw();
+}
+
+void
+WorkArea::insert_renderer(const etl::handle<WorkAreaRenderer> &x, int priority)
+{
+       x->set_priority(priority);
+       insert_renderer(x);
+}
+
+void
+WorkArea::erase_renderer(const etl::handle<WorkAreaRenderer> &x)
+{
+       x->set_work_area(0);
+       renderer_set_.erase(x);
+       queue_draw();
+}
+
+void
+WorkArea::resort_render_set()
+{
+       std::set<etl::handle<WorkAreaRenderer> > tmp(
+               renderer_set_.begin(),
+               renderer_set_.end()
+       );
+       renderer_set_.swap(tmp);
+       queue_draw();
+}
diff --git a/synfig-studio/trunk/src/gtkmm/workarea.h b/synfig-studio/trunk/src/gtkmm/workarea.h
new file mode 100644 (file)
index 0000000..8e1da79
--- /dev/null
@@ -0,0 +1,490 @@
+/* === S I N F G =========================================================== */
+/*!    \file workarea.h
+**     \brief Template Header
+**
+**     $Id: workarea.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_GTKMM_WORKAREA_H
+#define __SINFG_GTKMM_WORKAREA_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+#include <map>
+#include <set>
+
+#include <ETL/smart_ptr>
+#include <ETL/handle>
+
+#include <gtkmm/drawingarea.h>
+#include <gtkmm/table.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/ruler.h>
+#include <gtkmm/image.h>
+#include <gdkmm/pixbuf.h>
+#include <gdkmm/cursor.h>
+#include <gdkmm/device.h>
+
+#include <sinfg/time.h>
+#include <sinfg/vector.h>
+#include <sinfg/general.h>
+#include <sinfg/renddesc.h>
+#include <sinfg/canvas.h>
+
+#include "zoomdial.h"
+#include "duckmatic.h"
+#include "instance.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+/*
+namespace etl {
+
+template <typename T_, typename C_=std::less<T_,T_> >
+class dereferenced_compare
+{
+public:
+       typedef etl::loose_handle<T_> first_argument_type;
+       typedef etl::loose_handle<T_> second_argument_type;
+       typedef bool result_type;
+       
+}
+};
+*/
+
+class WorkAreaTarget;
+class WorkAreaTarget_Full;
+namespace sinfgapp { class CanvasInterface; };
+
+namespace sinfg { class Layer; };
+namespace Gtk { class Frame; };
+
+namespace studio
+{
+class Instance;
+class CanvasView;
+class WorkArea;
+class WorkAreaRenderer;
+class AsyncRenderer;
+class DirtyTrap
+{
+       friend class WorkArea;
+       WorkArea *work_area;
+public:
+       DirtyTrap(WorkArea *work_area);
+       ~DirtyTrap();
+};
+
+
+class WorkArea : public Gtk::Table, public Duckmatic
+{
+       friend class WorkAreaTarget;
+       friend class WorkAreaTarget_Full;
+       friend class DirtyTrap;
+       friend class WorkAreaRenderer;
+               
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+       
+public:
+
+       void insert_renderer(const etl::handle<WorkAreaRenderer> &x);
+       void insert_renderer(const etl::handle<WorkAreaRenderer> &x,int priority);
+       void erase_renderer(const etl::handle<WorkAreaRenderer> &x);
+       void resort_render_set();
+
+       enum DragMode
+       {
+               DRAG_NONE=0,
+               DRAG_WINDOW,
+               DRAG_DUCK,
+               DRAG_GUIDE,
+               DRAG_BOX
+       };
+
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       std::set<etl::handle<WorkAreaRenderer> > renderer_set_;
+
+       etl::handle<studio::AsyncRenderer> async_renderer;
+
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface;
+       etl::handle<sinfg::Canvas> canvas;
+       etl::loose_handle<studio::Instance> instance;
+       etl::loose_handle<studio::CanvasView> canvas_view;
+
+       // Widgets
+       Gtk::DrawingArea *drawing_area;
+       Gtk::Adjustment scrollx_adjustment;
+       Gtk::Adjustment scrolly_adjustment;
+       Gtk::VRuler *vruler;
+       Gtk::HRuler *hruler;
+       Gtk::Button *menubutton;
+       Gtk::Frame *drawing_frame;
+
+       GdkDevice* curr_input_device;
+       
+       // Bleh!
+       int     w;                                              //!< Width of the image (in pixels)
+       int     h;                                              //!< Height of the image (in pixels)
+       sinfg::Real     canvaswidth;    //!< Width of the canvas
+       sinfg::Real     canvasheight;   //!< Height of the canvas
+       sinfg::Real     pw;                             //!< The width of a pixel
+       sinfg::Real     ph;                             //!< The height of a pixel
+       float zoom;                                     //!< Zoom factor
+       float prev_zoom;                        //!< Previous Zoom factor
+       sinfg::Point window_tl;         //!< The (theoretical) top-left corner of the view window
+       sinfg::Point window_br;         //!< The (theoretical) bottom-right corner of the view window
+
+       guint32 last_event_time;
+
+       int bpp;
+       //unsigned char *buffer;
+       
+       //! ???
+       sinfg::ProgressCallback *progresscallback;
+
+       //! ???
+       sinfg::RendDesc desc;
+       
+       //! This flag is set if the user is dragging the video window
+       /*! \see drag_point */
+       DragMode dragging;
+               
+       etl::handle<Duckmatic::Duck> clicked_duck;
+       etl::handle<Duckmatic::Duck> hover_duck;
+
+       //! When dragging the viewport, this is set to the origin of the drag
+       sinfg::Point drag_point;
+
+       sinfg::Point curr_point;
+
+       //! ???
+       sinfg::Point previous_focus;
+
+       //! This flag is set if the grid should be drawn
+       bool show_grid;
+
+       //! This flag is set if the guides should be drawn
+       bool show_guides;
+
+       bool low_resolution;
+       
+       bool meta_data_lock;
+
+       //! This flag is set if the entire frame is rendered rather than using tiles    
+       bool full_frame;
+       
+       //Glib::RefPtr<Gdk::Pixbuf> pix_buf;
+       
+       //! This vector holds all of the tiles for this image
+       std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> > tile_book;
+
+       //! This integer describes the total times that the work are has been refreshed
+       int refreshes;
+       
+       //! This list holds the queue of tiles that need to be rendered
+       //std::list<int> tile_queue;
+       
+       int tile_w, tile_h;
+
+       gint render_idle_func_id;
+
+       //! The coordinates of the focus the last time a part of the screen was refreshed
+       sinfg::Point last_focus_point;
+
+       bool canceled_;
+       
+       int quality;
+
+       bool dirty_trap_enabled;
+       
+       int dirty_trap_queued;
+       
+       
+       bool onion_skin;
+               
+       etl::loose_handle<sinfg::ValueNode> selected_value_node_;
+
+
+       /*
+ -- ** -- P U B L I C   D A T A -----------------------------------------------
+       */
+
+public:
+
+       const etl::loose_handle<sinfg::ValueNode>& get_selected_value_node() { return  selected_value_node_; }
+       const sinfg::Point& get_drag_point()const { return drag_point; }
+       std::vector< std::pair<Glib::RefPtr<Gdk::Pixbuf>,int> >& get_tile_book(){ return tile_book; }
+       int get_refreshes()const { return refreshes; }
+       bool get_canceled()const { return canceled_; }
+       bool get_queued()const { return queued; }
+       bool get_rendering()const { return rendering; }
+       bool get_full_frame()const { return full_frame; }
+       //int get_w()const { return w; }
+       //int get_h()const { return h; }
+
+       int get_tile_w()const { return tile_w; }
+       int get_tile_h()const { return tile_h; }
+       
+       bool solid_lines;
+       bool rendering;
+       bool dirty;
+       bool queued;
+       bool cancel;
+       bool allow_layer_clicks;
+       bool allow_duck_clicks;
+
+       GuideList::iterator curr_guide;
+       bool curr_guide_is_x;
+
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       //unsigned char *get_buffer() { return buffer; }
+       bool set_wh(int w, int h,int chan=3);
+
+       int next_unrendered_tile(int refreshes)const;
+       int next_unrendered_tile()const { return next_unrendered_tile(refreshes); }
+
+       /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+       */
+
+private:
+
+       sigc::signal<void,GdkDevice* > signal_input_device_changed_;
+
+       //! One signal per button
+       sigc::signal<void,sinfg::Point> signal_user_click_[5];
+
+       sigc::signal<void> signal_popup_menu_;
+
+       sigc::signal<void> signal_cursor_moved_;
+       sigc::signal<void> signal_rendering_;
+
+       sigc::signal<void> signal_onion_skin_changed_;
+
+       //! Signal for when the user clicks on a layer
+       sigc::signal<void, etl::handle<sinfg::Layer> > signal_layer_selected_;
+
+       sigc::signal<void> signal_view_window_changed_;
+
+public:
+
+       sigc::signal<void>& signal_onion_skin_changed() { return signal_onion_skin_changed_; }
+
+       sigc::signal<void>& signal_rendering() { return signal_rendering_; }
+
+       sigc::signal<void>& signal_cursor_moved() { return signal_cursor_moved_; }
+
+       sigc::signal<void>& signal_view_window_changed() { return signal_view_window_changed_; }
+       void view_window_changed() { signal_view_window_changed()(); }
+
+       sigc::signal<void,GdkDevice* >& signal_input_device_changed() { return signal_input_device_changed_; }
+
+       sigc::signal<void> &signal_popup_menu() { return signal_popup_menu_; }
+
+       //! One signal per button (5 buttons)
+       sigc::signal<void,sinfg::Point> &signal_user_click(int button=0){ return signal_user_click_[button]; }
+
+       sigc::signal<void, etl::handle<sinfg::Layer> >& signal_layer_selected() { return signal_layer_selected_; }
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+       void set_onion_skin(bool x);
+       bool get_onion_skin()const;
+       void toggle_onion_skin() { set_onion_skin(!get_onion_skin()); }
+
+       void set_selected_value_node(etl::loose_handle<sinfg::ValueNode> x);
+
+       bool is_dragging() { return dragging!=DRAG_NONE; }
+
+       DragMode get_dragging_mode() { return dragging; }
+
+       WorkArea(etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface);
+       virtual ~WorkArea();
+
+       void set_cursor(const Gdk::Cursor& x);
+       void set_cursor(Gdk::CursorType x);
+
+       const sinfg::Point& get_cursor_pos()const { return curr_point; }
+
+       Gtk::Adjustment *get_scrollx_adjustment() { return &scrollx_adjustment; }
+       Gtk::Adjustment *get_scrolly_adjustment() { return &scrolly_adjustment; }
+       const Gtk::Adjustment *get_scrollx_adjustment()const { return &scrollx_adjustment; }
+       const Gtk::Adjustment *get_scrolly_adjustment()const { return &scrolly_adjustment; }
+
+       void set_instance(etl::loose_handle<studio::Instance> x) { instance=x; }
+       void set_canvas(etl::handle<sinfg::Canvas> x) { canvas=x; }
+       void set_canvas_view(etl::loose_handle<studio::CanvasView> x) { canvas_view=x; }
+       etl::handle<sinfg::Canvas> get_canvas()const { return canvas; }
+       etl::handle<studio::Instance> get_instance()const { return instance; }
+       etl::loose_handle<studio::CanvasView> get_canvas_view()const { return canvas_view; }
+
+       void refresh_dimension_info();
+       
+       //! Enables showing of the grid
+       void enable_grid();
+       
+       //! Disables showing of the grid
+       void disable_grid();
+       
+       //! Toggles the showing of the grid
+       void toggle_grid();
+       
+       //! Returns the state of the show_grid flag
+       bool grid_status()const { return show_grid; }
+
+       void toggle_grid_snap() { Duckmatic::toggle_grid_snap(); }
+
+       bool get_show_guides()const { return show_guides; }
+       void set_show_guides(bool x);
+       void toggle_show_guides() { set_show_guides(!get_show_guides()); }
+               
+       bool get_low_resolution_flag()const { return low_resolution; }
+       void set_low_resolution_flag(bool x);
+       void toggle_low_resolution_flag();
+       
+       //! ???
+       void queue_scroll();
+       
+       //! Sets the size of the grid
+       void set_grid_size(const sinfg::Vector &s);
+               
+       //! ??
+       void popup_menu();
+       
+       int get_quality()const { return quality; }
+
+       void set_quality(int x);
+       
+
+       int get_w()const { return w; }
+       int get_h()const { return h; }
+       int get_bpp()const { return bpp; }
+
+       //! ??
+       const sinfg::RendDesc &get_rend_desc()const { return desc; }
+       
+       //! ??
+       void set_rend_desc(const sinfg::RendDesc &x) { desc=x; }
+       
+       //! Converts screen coords (ie: pixels) to composition coordinates
+       sinfg::Point screen_to_comp_coords(sinfg::Point pos)const;
+
+       //! Converts composition coordinates to screen coords (ie: pixels)
+       sinfg::Point comp_to_screen_coords(sinfg::Point pos)const;
+
+       float get_pw()const { return pw; }
+       float get_ph()const { return ph; }
+       
+       const sinfg::Point &get_window_tl()const { return window_tl; }
+       const sinfg::Point &get_window_br()const { return window_br; }
+
+
+       bool async_update_preview();
+       void async_update_finished();
+       void async_render_preview(sinfg::Time time);
+       void async_render_preview();
+       
+       bool sync_update_preview();
+       bool sync_render_preview(sinfg::Time time);
+       bool sync_render_preview();
+       void sync_render_preview_hook();
+
+       void queue_render_preview();
+       
+       
+       void queue_draw_preview();
+       
+       void zoom_in();
+       void zoom_out();
+       void zoom_fit();
+       void zoom_norm();
+       float get_zoom()const { return zoom; }
+       
+       void set_zoom(float z);
+
+
+       void set_progress_callback(sinfg::ProgressCallback *x)  { progresscallback=x; }
+       sinfg::ProgressCallback *get_progress_callback() { return progresscallback; }
+
+       void set_focus_point(const sinfg::Point &x);
+
+       sinfg::Point get_focus_point()const;
+
+       void done_rendering();
+       
+       bool refresh(GdkEventExpose*bleh=NULL);
+       
+       void reset_cursor();
+       void refresh_cursor();
+
+       void save_meta_data();
+       void load_meta_data();
+       
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+       bool on_key_press_event(GdkEventKey* event);
+       bool on_drawing_area_event(GdkEvent* event);
+       bool on_hruler_event(GdkEvent* event);
+       bool on_vruler_event(GdkEvent* event);
+
+       /*
+ -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
+       */
+
+public:
+
+       /*
+ -- ** -- S T A T I C   P R I V A T E   M E T H O D S -------------------------
+       */
+
+private:
+
+       static gboolean __render_preview(gpointer data);
+
+}; // END of class WorkArea
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/workarearenderer.cpp b/synfig-studio/trunk/src/gtkmm/workarearenderer.cpp
new file mode 100644 (file)
index 0000000..47e2a18
--- /dev/null
@@ -0,0 +1,131 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: workarearenderer.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "workarearenderer.h"
+#include "workarea.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace studio;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+WorkAreaRenderer::WorkAreaRenderer():
+       enabled_(true),
+       priority_(0)
+{
+}
+
+WorkAreaRenderer::~WorkAreaRenderer()
+{
+}
+
+bool
+WorkAreaRenderer::get_enabled_vfunc()const
+{
+       return enabled_;
+}
+
+void
+WorkAreaRenderer::set_enabled(bool x)
+{
+       if(x==enabled_)
+               return;
+       enabled_=x;
+       signal_changed()();
+}
+
+void
+WorkAreaRenderer::set_priority(int x)
+{
+       if(x==priority_)
+               return;
+       priority_=x;
+       signal_changed()();
+}
+
+void
+WorkAreaRenderer::set_work_area(WorkArea* x)
+{
+       work_area_=x;
+}
+       
+void
+WorkAreaRenderer::render_vfunc(
+       const Glib::RefPtr<Gdk::Drawable>& window,
+       const Gdk::Rectangle& expose_area
+)
+{
+}
+
+bool
+WorkAreaRenderer::event_vfunc(
+       GdkEvent* event
+)
+{
+       return false;
+}
+
+int
+WorkAreaRenderer::get_w()const
+{ return get_work_area()->get_w(); }
+int
+WorkAreaRenderer::get_h()const
+{ return get_work_area()->get_h(); }
+       
+float
+WorkAreaRenderer::get_pw()const
+{ return get_work_area()->get_pw(); }
+float
+WorkAreaRenderer::get_ph()const
+{ return get_work_area()->get_ph(); }
+
+sinfg::Point
+WorkAreaRenderer::screen_to_comp_coords(sinfg::Point pos)const
+{
+       return get_work_area()->screen_to_comp_coords(pos);
+}
+
+sinfg::Point
+WorkAreaRenderer::comp_to_screen_coords(sinfg::Point pos)const
+{
+       return get_work_area()->comp_to_screen_coords(pos);
+}
diff --git a/synfig-studio/trunk/src/gtkmm/workarearenderer.h b/synfig-studio/trunk/src/gtkmm/workarearenderer.h
new file mode 100644 (file)
index 0000000..d9c41b8
--- /dev/null
@@ -0,0 +1,115 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: workarearenderer.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_WORKAREARENDERER_H
+#define __SINFG_WORKAREARENDERER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <sinfg/vector.h>
+#include <gdkmm/drawable.h>
+#include <gdkmm/rectangle.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+class WorkArea;
+       
+class WorkAreaRenderer : public etl::shared_object, public sigc::trackable
+{
+public:
+       typedef etl::handle<WorkAreaRenderer> Handle;
+       typedef etl::loose_handle<WorkAreaRenderer> LooseHandle;
+
+private:
+       bool enabled_;
+       int priority_;
+       
+       sigc::signal<void> signal_changed_;
+       
+       WorkArea* work_area_;
+       
+public:
+
+       sigc::signal<void>& signal_changed() { return signal_changed_; }
+               
+public:
+       int get_w()const;
+       int get_h()const;
+       
+       float get_pw()const;
+       float get_ph()const;
+
+       //! Converts screen coords (ie: pixels) to composition coordinates
+       sinfg::Point screen_to_comp_coords(sinfg::Point pos)const;
+
+       //! Converts composition coordinates to screen coords (ie: pixels)
+       sinfg::Point comp_to_screen_coords(sinfg::Point pos)const;
+
+       WorkAreaRenderer();
+       virtual ~WorkAreaRenderer();
+
+       bool get_enabled()const { return get_enabled_vfunc(); }
+       int get_priority()const { return priority_; }
+       WorkArea* get_work_area()const { return work_area_; }
+       
+       void set_enabled(bool x);
+       void set_priority(int x);
+       void set_work_area(WorkArea* work_area_);
+       
+       virtual void render_vfunc(
+               const Glib::RefPtr<Gdk::Drawable>& window,
+               const Gdk::Rectangle& expose_area
+       );
+
+       virtual bool event_vfunc(
+               GdkEvent* event
+       );
+
+protected:
+
+       virtual bool get_enabled_vfunc()const;
+
+public:
+       bool operator<(const WorkAreaRenderer &rhs)
+               { return priority_<rhs.priority_; }
+};
+
+inline bool operator<(const WorkAreaRenderer::Handle &lhs,const WorkAreaRenderer::Handle &rhs)
+       { return lhs->get_priority() < rhs->get_priority(); }
+
+inline bool operator<(const WorkAreaRenderer::LooseHandle &lhs,const WorkAreaRenderer::LooseHandle &rhs)
+       { return lhs->get_priority() < rhs->get_priority(); }
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/gtkmm/zoomdial.cpp b/synfig-studio/trunk/src/gtkmm/zoomdial.cpp
new file mode 100644 (file)
index 0000000..8557f44
--- /dev/null
@@ -0,0 +1,47 @@
+/* === S I N F G =========================================================== */
+/*!    \file zoomdial.cpp
+**     \brief Template File
+**
+**     $Id: zoomdial.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+//#include "zoomdial.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
diff --git a/synfig-studio/trunk/src/gtkmm/zoomdial.h b/synfig-studio/trunk/src/gtkmm/zoomdial.h
new file mode 100644 (file)
index 0000000..42c902e
--- /dev/null
@@ -0,0 +1,93 @@
+/* === S I N F G =========================================================== */
+/*!    \file zoomdial.h
+**     \brief Template Header
+**
+**     $Id: zoomdial.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_STUDIO_ZOOMDIAL_H
+#define __SINFG_STUDIO_ZOOMDIAL_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <gtkmm/tooltips.h>
+#include <gtkmm/button.h>
+
+/* === M A C R O S ========================================================= */
+
+#define SMALL_BUTTON(button,stockid,tooltip)   \
+       button = manage(new class Gtk::Button());       \
+       icon=manage(new Gtk::Image(Gtk::StockID(stockid),iconsize));    \
+       button->add(*icon);     \
+       tooltips.set_tip(*button,tooltip);      \
+       icon->set_padding(0,0);\
+       icon->show();   \
+       button->set_relief(Gtk::RELIEF_NONE); \
+       button->show()
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio
+{
+
+class ZoomDial : public Gtk::Table
+{
+
+       Gtk::Tooltips tooltips;
+       Gtk::IconSize iconsize;
+
+       
+public:
+       Gtk::Button *zoom_in;
+       Gtk::Button *zoom_out;
+       Gtk::Button *zoom_fit;
+       Gtk::Button *zoom_norm;
+
+       ZoomDial(Gtk::IconSize &size):Table(3, 1, false),iconsize(size)
+       {
+               Gtk::Image *icon;
+
+               SMALL_BUTTON(zoom_in,"gtk-add","Zoom In");
+               SMALL_BUTTON(zoom_out,"gtk-remove","Zoom Out");
+               SMALL_BUTTON(zoom_fit,"gtk-zoom-fit","Zoom Fit");
+               SMALL_BUTTON(zoom_norm,"gtk-zoom-100","Zoom to 100%");
+
+               attach(*zoom_out, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+               attach(*zoom_norm, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+               attach(*zoom_in, 2, 3, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
+       }
+
+       Glib::SignalProxy0<void> signal_zoom_in()
+       { return zoom_in->signal_clicked(); }
+       Glib::SignalProxy0<void> signal_zoom_out()
+       { return zoom_out->signal_clicked(); }
+       Glib::SignalProxy0<void> signal_zoom_fit()
+       { return zoom_fit->signal_clicked(); }
+       Glib::SignalProxy0<void> signal_zoom_norm()
+       { return zoom_norm->signal_clicked(); }
+
+}; // END of class ZoomDial
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/Makefile.am b/synfig-studio/trunk/src/sinfgapp/Makefile.am
new file mode 100644 (file)
index 0000000..9c46228
--- /dev/null
@@ -0,0 +1,50 @@
+# $Header: /opt/voria/cvs/studio/src/sinfgapp/Makefile.am,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+
+MAINTAINERCLEANFILES=Makefile.in
+INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/libltdl
+
+LAYER_ACTION_HH=actions/layerremove.h actions/layermove.h actions/layerraise.h actions/layerlower.h actions/layeradd.h actions/layeractivate.h actions/layerparamset.h actions/layerparamconnect.h actions/layerparamdisconnect.h actions/layerencapsulate.h actions/layerduplicate.h actions/layersetdesc.h
+LAYER_ACTION_CC=actions/layerremove.cpp actions/layermove.cpp actions/layerraise.cpp actions/layerlower.cpp actions/layeradd.cpp actions/layeractivate.cpp actions/layerparamset.cpp actions/layerparamconnect.cpp actions/layerparamdisconnect.cpp actions/layerencapsulate.cpp actions/layerduplicate.cpp actions/layersetdesc.cpp
+
+VALUEDESC_ACTION_HH=actions/valuedescset.h actions/valuedescexport.h actions/valuedescconvert.h actions/valuedescconnect.h actions/valuedescdisconnect.h actions/valuedesclink.h
+VALUEDESC_ACTION_CC=actions/valuedescset.cpp actions/valuedescexport.cpp actions/valuedescconvert.cpp actions/valuedescconnect.cpp actions/valuedescdisconnect.cpp actions/valuedesclink.cpp
+
+VALUENODE_ACTION_HH=actions/valuenodeconstset.h actions/valuenodeadd.h actions/valuenodereplace.h actions/valuenodelinkconnect.h actions/valuenodelinkdisconnect.h actions/valuenodedynamiclistinsert.h actions/valuenodedynamiclistremove.h actions/valuenoderename.h actions/valuenoderemove.h actions/valuenodedynamiclistinsertsmart.h actions/valuenodedynamiclistremovesmart.h actions/valuenodedynamiclistloop.h actions/valuenodedynamiclistunloop.h actions/valuenodedynamiclistrotateorder.h
+VALUENODE_ACTION_CC=actions/valuenodeconstset.cpp actions/valuenodeadd.cpp actions/valuenodereplace.cpp actions/valuenodelinkconnect.cpp actions/valuenodelinkdisconnect.cpp actions/valuenodedynamiclistinsert.cpp actions/valuenodedynamiclistremove.cpp actions/valuenoderename.cpp actions/valuenoderemove.cpp actions/valuenodedynamiclistinsertsmart.cpp actions/valuenodedynamiclistremovesmart.cpp actions/valuenodedynamiclistloop.cpp actions/valuenodedynamiclistunloop.cpp actions/valuenodedynamiclistrotateorder.cpp
+
+WAYPOINT_ACTION_HH=actions/waypointadd.h actions/waypointset.h actions/waypointsetsmart.h actions/waypointremove.h actions/waypointsimpleadd.h
+WAYPOINT_ACTION_CC=actions/waypointadd.cpp actions/waypointset.cpp actions/waypointsetsmart.cpp actions/waypointremove.cpp actions/waypointsimpleadd.cpp
+
+TIMEPOINT_ACTION_HH=actions/timepointsmove.h actions/timepointscopy.h actions/timepointsdelete.h timegather.h
+TIMEPOINT_ACTION_CC=actions/timepointsmove.cpp actions/timepointscopy.cpp actions/timepointsdelete.cpp timegather.cpp
+
+ACTIVEPOINT_ACTION_HH=actions/activepointadd.h actions/activepointset.h actions/activepointsetsmart.h actions/activepointsetoff.h actions/activepointseton.h actions/activepointremove.h actions/activepointsimpleadd.h
+ACTIVEPOINT_ACTION_CC=actions/activepointadd.cpp actions/activepointset.cpp actions/activepointsetsmart.cpp actions/activepointsetoff.cpp actions/activepointseton.cpp actions/activepointremove.cpp actions/activepointsimpleadd.cpp
+
+KEYFRAME_ACTION_HH=actions/keyframesetdelta.h actions/keyframeadd.h actions/keyframeset.h actions/keyframeremove.h actions/keyframeduplicate.h actions/keyframewaypointset.h
+KEYFRAME_ACTION_CC=actions/keyframesetdelta.cpp actions/keyframeadd.cpp actions/keyframeset.cpp actions/keyframeremove.cpp actions/keyframeduplicate.cpp actions/keyframewaypointset.cpp
+
+CANVAS_ACTION_HH=actions/canvasrenddescset.h actions/canvasadd.h actions/canvasremove.h
+CANVAS_ACTION_CC=actions/canvasrenddescset.cpp actions/canvasadd.cpp actions/canvasremove.cpp
+
+GROUP_ACTION_HH=actions/groupaddlayers.h actions/groupremovelayers.h actions/groupremove.h actions/grouprename.h
+GROUP_ACTION_CC=actions/groupaddlayers.cpp actions/groupremovelayers.cpp actions/groupremove.cpp actions/grouprename.cpp
+
+OTHER_ACTION_HH=actions/colorset.h actions/editmodeset.h actions/blinepointtangentmerge.h actions/blinepointtangentsplit.h actions/gradientset.h
+OTHER_ACTION_CC=actions/colorset.cpp actions/editmodeset.cpp actions/blinepointtangentmerge.cpp actions/blinepointtangentsplit.cpp actions/gradientset.cpp
+
+ACTIONHH=$(GROUP_ACTION_HH) $(LAYER_ACTION_HH) $(VALUEDSEC_ACTION_HH) $(VALUENODE_ACTION_HH) $(WAYPOINT_ACTION_HH) $(KEYFRAME_ACTION_HH) $(OTHER_ACTION_HH) $(CANVAS_ACTION_HH) $(ACTIVEPOINT_ACTION_HH) $(TIMEPOINT_ACTION_HH)
+ACTIONCC=$(GROUP_ACTION_CC) $(LAYER_ACTION_CC) $(VALUEDESC_ACTION_CC) $(VALUENODE_ACTION_CC) $(WAYPOINT_ACTION_CC) $(KEYFRAME_ACTION_CC) $(OTHER_ACTION_CC) $(CANVAS_ACTION_CC) $(ACTIVEPOINT_ACTION_CC) $(TIMEPOINT_ACTION_CC)
+
+SINFGAPPHH=$(ACTIONHH) blineconvert.h cvs.h editmode.h action.h action_param.h action_system.h canvasinterface.h instance.h selectionmanager.h uimanager.h value_desc.h main.h inputdevice.h settings.h
+
+sinfglibdir=@sinfglibdir@
+
+lib_LTLIBRARIES = libsinfgapp.la
+libsinfgapp_la_SOURCES =  $(SINFGAPPHH) $(ACTIONCC) blineconvert.cpp cvs.cpp main.cpp action_param.cpp action.cpp action_system.cpp canvasinterface.cpp instance.cpp uimanager.cpp inputdevice.cpp settings.cpp
+libsinfgapp_la_LIBADD = @SINFG_LIBS@
+libsinfgapp_la_CXXFLAGS = @SINFG_CFLAGS@
+libsinfgapp_la_LDFLAGS = -export-dynamic -no-undefined
+
+include_sinfgappdir=$(prefix)/include/sinfgapp-0.0/sinfgapp
+include_sinfgapp_HEADERS = $(SINFGAPPHH)
diff --git a/synfig-studio/trunk/src/sinfgapp/action.cpp b/synfig-studio/trunk/src/sinfgapp/action.cpp
new file mode 100644 (file)
index 0000000..1c1dd7e
--- /dev/null
@@ -0,0 +1,449 @@
+/* === S I N F G =========================================================== */
+/*!    \file action.cpp
+**     \brief Template File
+**
+**     $Id: action.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "action.h"
+#include "instance.h"
+
+
+#include "actions/layerremove.h"
+#include "actions/layermove.h"
+#include "actions/layerraise.h"
+#include "actions/layerlower.h"
+#include "actions/layeradd.h"
+#include "actions/layeractivate.h"
+#include "actions/layerparamset.h"
+#include "actions/layerparamconnect.h"
+#include "actions/layerparamdisconnect.h"
+#include "actions/layerencapsulate.h"
+#include "actions/layerduplicate.h"
+#include "actions/layersetdesc.h"
+
+#include "actions/valuenodeconstset.h"
+#include "actions/valuenodeadd.h"
+#include "actions/valuenodereplace.h"
+#include "actions/valuenodelinkconnect.h"
+#include "actions/valuenodelinkdisconnect.h"
+#include "actions/valuenodedynamiclistinsert.h"
+#include "actions/valuenodedynamiclistremove.h"
+#include "actions/valuenodedynamiclistinsertsmart.h"
+#include "actions/valuenodedynamiclistremovesmart.h"
+#include "actions/valuenodedynamiclistloop.h"
+#include "actions/valuenodedynamiclistunloop.h"
+#include "actions/valuenodedynamiclistrotateorder.h"
+#include "actions/valuenoderename.h"
+#include "actions/valuenoderemove.h"
+
+#include "actions/valuedescset.h"
+#include "actions/valuedescexport.h"
+#include "actions/valuedescconvert.h"
+#include "actions/valuedescconnect.h"
+#include "actions/valuedescdisconnect.h"
+#include "actions/valuedesclink.h"
+
+#include "actions/waypointadd.h"
+#include "actions/waypointset.h"
+#include "actions/waypointsetsmart.h"
+#include "actions/waypointremove.h"
+
+#include "actions/activepointadd.h"
+#include "actions/activepointset.h"
+#include "actions/activepointsetsmart.h"
+#include "actions/activepointsetoff.h"
+#include "actions/activepointseton.h"
+#include "actions/activepointremove.h"
+
+#include "actions/keyframeadd.h"
+#include "actions/keyframeset.h"
+#include "actions/keyframeremove.h"
+#include "actions/keyframeduplicate.h"
+#include "actions/keyframewaypointset.h"
+#include "actions/keyframesetdelta.h"
+
+#include "actions/timepointsmove.h"
+#include "actions/timepointscopy.h"
+#include "actions/timepointsdelete.h"
+
+#include "actions/canvasrenddescset.h"
+#include "actions/canvasadd.h"
+#include "actions/canvasremove.h"
+
+#include "actions/editmodeset.h"
+
+#include "actions/blinepointtangentmerge.h"
+#include "actions/blinepointtangentsplit.h"
+
+#include "actions/gradientset.h"
+#include "actions/colorset.h"
+
+#include "actions/groupaddlayers.h"
+#include "actions/groupremovelayers.h"
+#include "actions/groupremove.h"
+#include "actions/grouprename.h"
+
+#include "canvasinterface.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === S T A T I C S ======================================================= */
+
+sinfgapp::Action::Book *book_;
+
+/* === M E T H O D S ======================================================= */
+
+#define ADD_ACTION(x) { BookEntry &be(book()[x::name__]); \
+       be.name=x::name__; \
+       be.local_name=x::local_name__; \
+       be.version=x::version__; \
+       be.task=x::task__; \
+       be.priority=x::priority__; \
+       be.category=x::category__; \
+       be.factory=x::create; \
+       be.get_param_vocab=x::get_param_vocab; \
+       be.is_canidate=x::is_canidate; \
+       }
+       
+
+Action::Main::Main()
+{
+       book_=new sinfgapp::Action::Book();
+       
+       ADD_ACTION(Action::LayerRemove);
+       ADD_ACTION(Action::LayerMove);
+       ADD_ACTION(Action::LayerRaise);
+       ADD_ACTION(Action::LayerLower);
+       ADD_ACTION(Action::LayerAdd);
+       ADD_ACTION(Action::LayerActivate);
+       ADD_ACTION(Action::LayerParamSet);
+       ADD_ACTION(Action::LayerParamConnect);
+       ADD_ACTION(Action::LayerParamDisconnect);
+       ADD_ACTION(Action::LayerEncapsulate);
+       ADD_ACTION(Action::LayerDuplicate);
+       ADD_ACTION(Action::LayerSetDesc);
+       
+       ADD_ACTION(Action::ValueNodeConstSet);  
+       ADD_ACTION(Action::ValueNodeAdd);       
+       ADD_ACTION(Action::ValueNodeReplace);   
+       ADD_ACTION(Action::ValueNodeLinkConnect);
+       ADD_ACTION(Action::ValueNodeLinkDisconnect);
+       ADD_ACTION(Action::ValueNodeDynamicListInsert);
+       ADD_ACTION(Action::ValueNodeDynamicListRemove);
+       ADD_ACTION(Action::ValueNodeDynamicListInsertSmart);
+       ADD_ACTION(Action::ValueNodeDynamicListRemoveSmart);
+       ADD_ACTION(Action::ValueNodeDynamicListLoop);
+       ADD_ACTION(Action::ValueNodeDynamicListUnLoop);
+       ADD_ACTION(Action::ValueNodeDynamicListRotateOrder);
+       ADD_ACTION(Action::ValueNodeRename);
+       ADD_ACTION(Action::ValueNodeRemove);
+       
+       ADD_ACTION(Action::ValueDescSet);
+       ADD_ACTION(Action::ValueDescExport);
+       ADD_ACTION(Action::ValueDescConvert);
+       ADD_ACTION(Action::ValueDescConnect);
+       ADD_ACTION(Action::ValueDescDisconnect);
+       ADD_ACTION(Action::ValueDescLink);
+
+       ADD_ACTION(Action::WaypointAdd);
+       ADD_ACTION(Action::WaypointSet);
+       ADD_ACTION(Action::WaypointSetSmart);
+       ADD_ACTION(Action::WaypointRemove);
+
+       ADD_ACTION(Action::ActivepointAdd);
+       ADD_ACTION(Action::ActivepointSet);
+       ADD_ACTION(Action::ActivepointSetSmart);
+       ADD_ACTION(Action::ActivepointSetOn);
+       ADD_ACTION(Action::ActivepointSetOff);
+       ADD_ACTION(Action::ActivepointRemove);
+
+       ADD_ACTION(Action::KeyframeAdd);
+       ADD_ACTION(Action::KeyframeSet);
+       ADD_ACTION(Action::KeyframeRemove);
+       ADD_ACTION(Action::KeyframeDuplicate);
+       ADD_ACTION(Action::KeyframeWaypointSet);
+       ADD_ACTION(Action::KeyframeSetDelta);
+
+       ADD_ACTION(Action::CanvasRendDescSet);
+       ADD_ACTION(Action::CanvasAdd);
+       ADD_ACTION(Action::CanvasRemove);
+
+       ADD_ACTION(Action::EditModeSet);
+
+       ADD_ACTION(Action::BLinePointTangentMerge);
+       ADD_ACTION(Action::BLinePointTangentSplit);
+
+       ADD_ACTION(Action::GradientSet);
+       ADD_ACTION(Action::ColorSet);
+       
+       ADD_ACTION(Action::TimepointsMove);
+       ADD_ACTION(Action::TimepointsCopy);
+       ADD_ACTION(Action::TimepointsDelete);
+
+       ADD_ACTION(Action::GroupAddLayers);
+       ADD_ACTION(Action::GroupRemoveLayers);
+       ADD_ACTION(Action::GroupRemove);
+       ADD_ACTION(Action::GroupRename);
+}
+
+Action::Main::~Main()
+{
+       delete book_;
+       
+}
+
+
+Action::Book& Action::book() { return *book_; }
+
+
+Action::Handle
+Action::create(const String &name)
+{
+       if(!book().count(name))
+               return 0; //! \todo perhaps we should throw something instead?
+       return book()[name].factory();  
+}
+
+
+Action::CanidateList
+Action::compile_canidate_list(const ParamList& param_list, Category category)
+{
+       Action::CanidateList ret;
+       
+       Book::const_iterator iter;
+
+       //sinfg::info("param_list.size()=%d",param_list.size());
+
+       for(iter=book().begin();iter!=book().end();++iter)
+       {
+               if((iter->second.category&category))
+               {
+                       if(iter->second.is_canidate(param_list))
+                               ret.push_back(iter->second);
+                       else
+                       {
+                               //sinfg::info("Action \"%s\" is not a canidate",iter->second.name.c_str());
+                       }
+               }
+       }
+       
+       return ret;
+}
+
+Action::CanidateList::iterator
+Action::CanidateList::find(const String& x)
+{
+       iterator iter;
+       for(iter=begin();iter!=end();++iter)
+               if(iter->name==x)
+                       break;
+       return iter;
+}
+
+void
+Action::Base::set_param_list(const ParamList &param_list)
+{
+       ParamList::const_iterator iter;
+       
+       for(iter=param_list.begin();iter!=param_list.end();++iter)
+               set_param(iter->first,iter->second);
+}
+
+void
+Super::perform()
+{
+       set_dirty(false);
+       
+       prepare();
+
+       ActionList::const_iterator iter;
+       for(iter=action_list_.begin();iter!=action_list_.end();++iter)
+       {
+               try
+               {
+                       try
+                       {
+                               (*iter)->perform();
+                               CanvasSpecific* canvas_specific(dynamic_cast<CanvasSpecific*>(iter->get()));
+                               if(canvas_specific && canvas_specific->is_dirty())
+                                       set_dirty(true);
+                       }
+                       catch(...)
+                       {
+                               if(iter!=action_list_.begin())
+                               {
+                                       for(--iter;iter!=action_list_.begin();--iter)
+                                               (*iter)->undo();
+                                       (*iter)->undo();
+                               }
+                               throw;
+                       }
+               }
+               catch(Error x)
+               {
+                       throw Error(x.get_type(),((*iter)->get_name()+": "+x.get_desc()).c_str());
+               }
+       }
+}
+
+void
+Super::undo()
+{
+       set_dirty(false);
+
+       ActionList::const_reverse_iterator iter;
+       for(iter=const_cast<const ActionList &>(action_list_).rbegin();iter!=const_cast<const ActionList &>(action_list_).rend();++iter)
+       {
+               try {
+                       (*iter)->undo();
+                       CanvasSpecific* canvas_specific(dynamic_cast<CanvasSpecific*>(iter->get()));
+                       if(canvas_specific && canvas_specific->is_dirty())
+                               set_dirty(true);
+               }
+               catch(...)
+               {
+                       if(iter!=const_cast<const ActionList &>(action_list_).rbegin())
+                       {
+                               for(--iter;iter!=const_cast<const ActionList &>(action_list_).rbegin();--iter)
+                                       (*iter)->perform();
+                               (*iter)->perform();
+                       }
+                       throw;
+               }
+       }
+}
+
+void
+Super::add_action(etl::handle<Undoable> action)
+{
+       action_list_.push_back(action);
+       CanvasSpecific *specific_action=dynamic_cast<CanvasSpecific *>(action.get());
+       if(specific_action && !get_canvas())
+               set_canvas(specific_action->get_canvas());
+}
+
+void
+Super::add_action_front(etl::handle<Undoable> action)
+{
+       action_list_.push_front(action);
+       CanvasSpecific *specific_action=dynamic_cast<CanvasSpecific *>(action.get());
+       if(specific_action && !get_canvas())
+               set_canvas(specific_action->get_canvas());
+}
+
+
+Group::Group(const std::string &str):
+       name_(str),
+       ready_(true)
+{
+}
+
+Group::~Group()
+{
+}
+
+
+
+
+Action::ParamVocab
+Action::CanvasSpecific::get_param_vocab()
+{
+       ParamVocab ret;
+       
+       ret.push_back(ParamDesc("canvas",Param::TYPE_CANVAS)
+               .set_local_name(_("Canvas"))
+               .set_desc(_("Selected Canvas"))
+       );
+
+       ret.push_back(ParamDesc("canvas_interface",Param::TYPE_CANVASINTERFACE)
+               .set_local_name(_("Canvas Interface"))
+               .set_desc(_("Canvas Interface"))
+               .set_optional(true)
+       );
+       
+
+       return ret;
+}
+
+bool
+CanvasSpecific::set_param(const sinfg::String& name, const Param &param)
+{
+       if(name=="canvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               if(!param.get_canvas())
+                       return false;
+               set_canvas(param.get_canvas());
+               
+               return true;
+       }
+       if(name=="canvas_interface" && param.get_type()==Param::TYPE_CANVASINTERFACE)
+       {
+               if(!param.get_canvas_interface())
+                       return false;
+               set_canvas_interface(param.get_canvas_interface());
+               if(!get_canvas())
+                       set_canvas(get_canvas_interface()->get_canvas());
+               
+               return true;
+       }
+       if(name=="edit_mode" && param.get_type()==Param::TYPE_EDITMODE)
+       {
+               set_edit_mode(param.get_edit_mode());
+               
+               return true;
+       }
+
+       return false;
+}
+
+bool
+CanvasSpecific::is_ready()const
+{
+       if(!get_canvas())
+               return false;
+       return true;
+}
+
+EditMode
+CanvasSpecific::get_edit_mode()const
+{
+       if(mode_!=MODE_UNDEFINED)
+               return mode_;
+       
+       if(get_canvas_interface())
+               return get_canvas_interface()->get_mode();
+       
+       return MODE_NORMAL;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/action.h b/synfig-studio/trunk/src/sinfgapp/action.h
new file mode 100644 (file)
index 0000000..372c8c7
--- /dev/null
@@ -0,0 +1,387 @@
+/* === S I N F G =========================================================== */
+/*!    \file action.h
+**     \brief Template File
+**
+**     $Id: action.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_H
+#define __SINFG_APP_ACTION_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/string.h>
+#include <sinfg/canvas.h>
+#include <ETL/handle>
+#include <ETL/stringf>
+#include <ETL/trivial>
+
+#include <map>
+#include <list>
+
+#include <sinfg/layer.h>
+#include <sinfg/canvas.h>
+#include <sinfg/valuenode.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/value.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/string.h>
+#include <sinfg/keyframe.h>
+
+#include "action_param.h"
+#include "editmode.h"
+
+/* === M A C R O S ========================================================= */
+
+#define ACTION_MODULE_EXT public: \
+       static const char name__[], local_name__[], version__[], cvs_id__[], task__[]; \
+       static const Category category__; \
+       static const int priority__; \
+       static Action::Base *create(); \
+       virtual sinfg::String get_name()const;  \
+       virtual sinfg::String get_local_name()const;
+
+
+#define ACTION_SET_NAME(class,x) const char class::name__[]=x
+
+#define ACTION_SET_CATEGORY(class,x) const Category class::category__(x)
+
+#define ACTION_SET_TASK(class,x) const char class::task__[]=x
+
+#define ACTION_SET_PRIORITY(class,x) const int class::priority__=x
+
+#define ACTION_SET_LOCAL_NAME(class,x) const char class::local_name__[]=x
+
+#define ACTION_SET_VERSION(class,x) const char class::version__[]=x
+
+#define ACTION_SET_CVS_ID(class,x) const char class::cvs_id__[]=x
+
+#define ACTION_INIT(class) \
+       Action::Base* class::create() { return new class(); }   \
+       sinfg::String class::get_name()const { return name__; } \
+       sinfg::String class::get_local_name()const { return local_name__; }     \
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg {
+class ProgressCallback;
+class Canvas;
+}; // END of namespace sinfg
+
+namespace sinfgapp {
+
+class Instance;
+class Main;
+       
+namespace Action {     
+
+class System;
+       
+
+//! Exception class, thrown when redoing or undoing an action
+class Error
+{
+public:
+       enum Type
+       {
+               TYPE_UNKNOWN,
+               TYPE_UNABLE,
+               TYPE_BADPARAM,
+               TYPE_CRITICAL,
+               TYPE_NOTREADY,
+               TYPE_BUG,
+
+               TYPE_END
+       };
+private:
+
+       Type type_;
+       sinfg::String desc_;
+
+public:
+       
+       Error(Type type, const char *format, ...):
+               type_(type)
+       {
+               va_list args;
+               va_start(args,format);
+               desc_=etl::vstrprintf(format,args);
+       }
+
+       Error(const char *format, ...):
+               type_(TYPE_UNKNOWN)
+       {
+               va_list args;
+               va_start(args,format);
+               desc_=etl::vstrprintf(format,args);
+       }
+
+       Error(Type type=TYPE_UNABLE):
+               type_(type)
+       {
+       }
+       
+       Type get_type()const { return type_; }
+       sinfg::String get_desc()const { return desc_; }
+       
+}; // END of class Action::Error
+
+class Param;
+class ParamList;
+class ParamDesc;
+class ParamVocab;
+
+// Action Category
+enum Category
+{
+       CATEGORY_NONE                   =0,
+       CATEGORY_LAYER                  =(1<<0),
+       CATEGORY_CANVAS                 =(1<<1),
+       CATEGORY_WAYPOINT               =(1<<2),
+       CATEGORY_ACTIVEPOINT    =(1<<3),
+       CATEGORY_VALUEDESC              =(1<<4),
+       CATEGORY_VALUENODE              =(1<<5),
+       CATEGORY_KEYFRAME               =(1<<6),
+       CATEGORY_GROUP                  =(1<<7),
+
+       CATEGORY_OTHER                  =(1<<12),
+
+       CATEGORY_DRAG                   =(1<<24),
+       
+       CATEGORY_HIDDEN                 =(1<<31),
+       CATEGORY_ALL                    =(~0)-(1<<31)           //!< All categories (EXCEPT HIDDEN)
+}; // END of enum Category
+
+inline Category operator|(Category lhs, Category rhs)
+{ return static_cast<Category>(int(lhs)|int(rhs)); }
+
+
+
+//! Action Base Class
+/*!    An action should implement the following functions:
+**     static bool is_canidate(const ParamList &x);
+**             -       Checks the ParamList to see if this action could be performed.
+**     static ParamVocab get_param_vocab();
+**             -       Yields the ParamVocab object which describes what
+**                     this action needs before it can perform the act.
+**     static Action::Base* create();
+**             -       Factory for creating this action from a ParamList
+**
+*/
+class Base : public etl::shared_object 
+{
+protected:
+       Base() { }
+       
+public:
+       virtual ~Base() { };
+
+       //! This function will throw an Action::Error() on failure
+       virtual void perform()=0;
+       
+       virtual bool set_param(const sinfg::String& name, const Param &) { return false; }
+       virtual bool is_ready()const=0;
+       
+       virtual sinfg::String get_name()const =0;
+       virtual sinfg::String get_local_name()const { return get_name(); }
+
+       void set_param_list(const ParamList &);
+       
+}; // END of class Action::Base
+
+typedef Action::Base* (*Factory)();
+typedef bool (*CanidateChecker)(const ParamList &x);
+typedef ParamVocab (*GetParamVocab)();
+
+typedef etl::handle<Base> Handle;
+
+//! Undoable Action Base Class
+class Undoable : public Base
+{
+       friend class System;
+       bool active_;
+
+protected:
+       Undoable():active_(true) { }
+
+private:
+       void set_active(bool x) { active_=x; }
+
+public:
+
+       //! This function will throw an Action::Error() on failure
+       virtual void undo()=0;
+
+       bool is_active()const { return active_; }
+
+}; // END of class Action::Undoable
+
+//! Action base class for canvas-specific actions
+class CanvasSpecific 
+{
+private:
+       bool is_dirty_;
+       EditMode        mode_;
+
+       etl::loose_handle<sinfgapp::CanvasInterface> canvas_interface_;
+       sinfg::Canvas::Handle canvas_;
+
+protected:
+       CanvasSpecific(const sinfg::Canvas::Handle &canvas):is_dirty_(true),mode_(MODE_UNDEFINED),canvas_(canvas) { }
+       CanvasSpecific():mode_(MODE_UNDEFINED) { }
+
+       virtual ~CanvasSpecific() { };
+       
+       
+public:
+
+       void set_canvas(sinfg::Canvas::Handle x) { canvas_=x; }
+       void set_canvas_interface(etl::loose_handle<sinfgapp::CanvasInterface> x) { canvas_interface_=x; }
+
+       sinfg::Canvas::Handle get_canvas()const { return canvas_; }
+       etl::loose_handle<sinfgapp::CanvasInterface> get_canvas_interface()const { return canvas_interface_; }
+
+       static ParamVocab get_param_vocab();
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       EditMode get_edit_mode()const;
+
+       void set_edit_mode(EditMode x) { mode_=x; }
+       
+       bool is_dirty()const { return is_dirty_; }
+       void set_dirty(bool x=true) { is_dirty_=x; }
+       
+}; // END of class Action::Undoable
+
+typedef std::list< etl::handle<Action::Undoable> > ActionList;
+
+/*!    \class sinfgapp::Action::Super
+**     \brief Super-Action base class for actions composed of several other actions.
+**
+**     Actions deriving from this class should only implement prepare(), and
+**     NOT implement perform() or undo().
+*/
+class Super : public Undoable, public CanvasSpecific
+{
+       ActionList action_list_;
+
+public:
+
+       ActionList &action_list() { return action_list_; }
+       const ActionList &action_list()const { return action_list_; }
+
+       virtual void prepare()=0;
+
+       void clear() { action_list().clear(); }
+       
+       bool first_time()const { return action_list_.empty(); }
+       
+       void add_action(etl::handle<Undoable> action);
+
+       void add_action_front(etl::handle<Undoable> action);
+
+       virtual void perform();
+       virtual void undo();
+
+}; // END of class Action::Super
+
+
+class Group : public Super
+{
+       sinfg::String name_;
+
+       ActionList action_list_;
+protected:
+       bool ready_;
+public:
+       Group(const sinfg::String &str="Group");
+       virtual ~Group();
+
+       virtual sinfg::String get_name()const { return name_; }
+
+       virtual void prepare() { };
+
+       virtual bool set_param(const sinfg::String& name, const Param &)const { return false; }
+       virtual bool is_ready()const { return ready_; }
+
+       void set_name(std::string&x) { name_=x; }
+}; // END of class Action::Group
+
+
+
+
+
+struct BookEntry
+{
+       sinfg::String   name;
+       sinfg::String   local_name;
+       sinfg::String   version;
+       sinfg::String   task;
+       int                     priority;
+       Category                category;
+       Factory                 factory;
+       CanidateChecker is_canidate;
+       GetParamVocab   get_param_vocab;        
+       
+       bool operator<(const BookEntry &rhs)const { return priority<rhs.priority; }
+}; // END of struct BookEntry
+
+typedef std::map<sinfg::String,BookEntry> Book;
+
+class CanidateList : public std::list<BookEntry>
+{
+public:
+       iterator find(const sinfg::String& x);
+       const_iterator find(const sinfg::String& x)const { return const_cast<CanidateList*>(this)->find(x); }
+};
+
+Book& book();
+
+Handle create(const sinfg::String &name);
+
+//! Compiles a list of potential canidate actions with the given \a param_list and \a category
+CanidateList compile_canidate_list(const ParamList& param_list, Category category=CATEGORY_ALL);
+
+/*!    \class sinfgapp::Action::Main
+**     \brief \writeme
+**
+**     \writeme
+*/
+class Main
+{
+       friend class sinfgapp::Main;
+
+       Main();
+
+public:
+       ~Main();
+
+}; // END of class Action::Main
+
+}; // END of namespace Action
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/action_param.cpp b/synfig-studio/trunk/src/sinfgapp/action_param.cpp
new file mode 100644 (file)
index 0000000..ef873b9
--- /dev/null
@@ -0,0 +1,515 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_param.cpp
+**     \brief Template File
+**
+**     $Id: action_param.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "action_param.h"
+#include "action.h"
+#include "canvasinterface.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === P R O C E D U R E S ================================================= */
+
+bool
+Action::canidate_check(const ParamVocab& param_vocab, const ParamList& param_list)
+{
+       ParamVocab::const_iterator iter;
+       
+       for(iter=param_vocab.begin();iter!=param_vocab.end();++iter)
+       {
+               int n(param_list.count(iter->get_name()));
+
+//             if(n && !iter->get_mutual_exclusion().empty() && param_list.count(iter->get_mutual_exclusion()))
+//                     return false;
+
+               if(!n && !iter->get_mutual_exclusion().empty() && param_list.count(iter->get_mutual_exclusion()))
+                       continue;
+
+               if(iter->get_user_supplied() || iter->get_optional())
+                       continue;
+                                                       
+               if(n==0)
+                       return false;
+               if(n==1 && iter->get_requires_multiple())
+                       return false;
+               if(n>1 && !iter->get_supports_multiple())
+                       return false;
+               
+               if(iter->get_type()!=param_list.find(iter->get_name())->second.get_type())
+                       return false;
+       }
+       return true;
+}
+
+/* === S T A T I C S ======================================================= */
+
+struct _ParamCounter
+{
+       static int counter;
+       ~_ParamCounter()
+       {
+               if(counter)
+                       sinfg::error("%d action params not yet deleted!",counter);
+       }
+} _param_counter;
+
+int _ParamCounter::counter(0);
+
+/* === M E T H O D S ======================================================= */
+
+Param::Param(const Param &rhs):
+       type_(rhs.type_)
+{
+       _ParamCounter::counter++;
+       switch(type_)
+       {
+       case TYPE_ACTIVEPOINT:
+               data.activepoint.construct();
+               data.activepoint.get()=rhs.data.activepoint.get();
+               break;
+       case TYPE_WAYPOINT:
+               data.waypoint.construct();
+               data.waypoint.get()=rhs.data.waypoint.get();
+               break;
+       case TYPE_WAYPOINTMODEL:
+               data.waypoint_model.construct();
+               data.waypoint_model.get()=rhs.data.waypoint_model.get();
+               break;
+       case TYPE_KEYFRAME:
+               data.keyframe.construct();
+               data.keyframe.get()=rhs.data.keyframe.get();
+               break;
+       case TYPE_CANVAS:
+               data.canvas.construct();
+               data.canvas.get()=rhs.data.canvas.get();
+               break;
+       case TYPE_CANVASINTERFACE:
+               data.canvas_interface.construct();
+               data.canvas_interface.get()=rhs.data.canvas_interface.get();
+               break;
+       case TYPE_LAYER:
+               data.layer.construct();
+               data.layer.get()=rhs.data.layer.get();
+               break;
+       case TYPE_VALUENODE:
+               data.value_node.construct();
+               data.value_node.get()=rhs.data.value_node.get();
+               break;
+       case TYPE_VALUEDESC:
+               data.value_desc.construct();
+               data.value_desc.get()=rhs.data.value_desc.get();
+               break;
+       case TYPE_VALUE:
+               data.value.construct();
+               data.value.get()=rhs.data.value.get();
+               break;
+       case TYPE_STRING:
+               data.string.construct();
+               data.string.get()=rhs.data.string.get();
+               break;
+       case TYPE_RENDDESC:
+               data.rend_desc.construct();
+               data.rend_desc.get()=rhs.data.rend_desc.get();
+               break;
+       case TYPE_TIME:
+               data.time.construct();
+               data.time.get()=rhs.data.time.get();
+               break;
+
+       case TYPE_INTEGER:
+               data.integer=rhs.data.integer;
+               break;
+       case TYPE_EDITMODE:
+               data.edit_mode=rhs.data.edit_mode;
+               break;
+       case TYPE_REAL:
+               data.real=rhs.data.real;
+               break;
+       case TYPE_BOOL:
+               data.b=rhs.data.b;
+               break;
+
+       case TYPE_NIL:
+               break;
+
+       default:
+               assert(0);
+               break;
+       }
+}
+
+Param::Param(const etl::handle<sinfgapp::CanvasInterface>& x):
+       
+       type_(TYPE_CANVASINTERFACE)
+{
+       _ParamCounter::counter++;
+       data.canvas_interface.construct();
+       data.canvas_interface.get()=x;
+}
+
+/*
+Param::Param(sinfgapp::CanvasInterface* x):
+       
+       type_(TYPE_CANVASINTERFACE)
+{
+       _ParamCounter::counter++;
+       data.canvas_interface.construct();
+       data.canvas_interface=x;
+}
+*/
+
+Param::Param(const etl::loose_handle<sinfgapp::CanvasInterface>& x):
+       
+       type_(TYPE_CANVASINTERFACE)
+{
+       _ParamCounter::counter++;
+       data.canvas_interface.construct();
+       data.canvas_interface.get()=x;
+}
+
+Param::Param(const sinfg::Canvas::Handle& x):  
+       type_(TYPE_CANVAS)
+{
+       _ParamCounter::counter++;
+       data.canvas.construct();
+       data.canvas.get()=x;
+}
+
+Param::Param(const sinfg::Canvas::LooseHandle& x):     
+       type_(TYPE_CANVAS)
+{
+       _ParamCounter::counter++;
+       data.canvas.construct();
+       data.canvas.get()=x;
+}
+
+Param::Param(const sinfg::Layer::Handle& x):
+       
+       type_(TYPE_LAYER)
+{
+       _ParamCounter::counter++;
+       data.layer.construct();
+       data.layer.get()=x;
+}
+
+Param::Param(const sinfg::Layer::LooseHandle& x):
+       
+       type_(TYPE_LAYER)
+{
+       _ParamCounter::counter++;
+       data.layer.construct();
+       data.layer.get()=x;
+}
+
+Param::Param(const sinfg::ValueNode::Handle& x):
+       
+       type_(TYPE_VALUENODE)
+{
+       _ParamCounter::counter++;
+       data.value_node.construct();
+       data.value_node.get()=x;
+}
+
+Param::Param(const sinfg::ValueNode::LooseHandle& x):
+       
+       type_(TYPE_VALUENODE)
+{
+       _ParamCounter::counter++;
+       data.value_node.construct();
+       data.value_node.get()=x;
+}
+
+Param::Param(const sinfg::ValueBase& x):
+       
+       type_(TYPE_VALUE)
+{
+       _ParamCounter::counter++;
+       data.value.construct();
+       data.value.get()=x;
+}
+
+Param::Param(const sinfg::RendDesc& x):        
+       type_(TYPE_RENDDESC)
+{
+       _ParamCounter::counter++;
+       data.rend_desc.construct();
+       data.rend_desc.get()=x;
+}
+
+Param::Param(const sinfg::Time& x):
+       type_(TYPE_TIME)
+{
+       _ParamCounter::counter++;
+       data.time.construct();
+       data.time.get()=x;
+}
+
+Param::Param(const sinfg::Activepoint& x):
+       
+       type_(TYPE_ACTIVEPOINT)
+{
+       _ParamCounter::counter++;
+       data.activepoint.construct();
+       data.activepoint.get()=x;
+}
+
+Param::Param(const sinfg::Waypoint& x):        
+       type_(TYPE_WAYPOINT)
+{
+       _ParamCounter::counter++;
+       data.waypoint.construct();
+       data.waypoint.get()=x;
+}
+
+Param::Param(const sinfg::Waypoint::Model& x): 
+       type_(TYPE_WAYPOINTMODEL)
+{
+       _ParamCounter::counter++;
+       data.waypoint_model.construct();
+       data.waypoint_model.get()=x;
+}
+
+Param::Param(const sinfg::String& x):
+       type_(TYPE_STRING)
+{
+       _ParamCounter::counter++;
+       data.string.construct();
+       data.string.get()=x;
+}
+
+Param::Param(const char * x):
+       type_(TYPE_STRING)
+{
+       _ParamCounter::counter++;
+       data.string.construct();
+       data.string.get()=x;
+}
+
+Param::Param(const sinfg::Keyframe& x):
+       
+       type_(TYPE_KEYFRAME)
+{
+       _ParamCounter::counter++;
+       data.keyframe.construct();
+       data.keyframe.get()=x;
+}
+
+Param::Param(const sinfgapp::ValueDesc& x):
+       
+       type_(TYPE_VALUEDESC)
+{
+       _ParamCounter::counter++;
+       data.value_desc.construct();
+       data.value_desc.get()=x;
+}
+
+Param::Param(const int& x):
+       type_(TYPE_INTEGER)
+{
+       _ParamCounter::counter++;
+       data.integer=x;
+}
+
+Param::Param(const EditMode& x):
+       type_(TYPE_EDITMODE)
+{
+       _ParamCounter::counter++;
+       data.edit_mode=x;
+}
+
+Param::Param(const sinfg::Real& x):
+       
+       type_(TYPE_REAL)
+{
+       _ParamCounter::counter++;
+       data.real=x;
+}
+
+Param::Param(const bool& x):
+       
+       type_(TYPE_BOOL)
+{
+       _ParamCounter::counter++;
+       data.b=x;
+}
+
+Param::~Param()
+{
+       clear();
+       _ParamCounter::counter--;
+}
+
+Param&
+Param::operator=(const Param& rhs)
+{
+       clear();
+       type_=rhs.type_;
+       
+       switch(type_)
+       {
+       case TYPE_ACTIVEPOINT:
+               data.activepoint.construct();
+               data.activepoint.get()=rhs.data.activepoint.get();
+               break;
+       case TYPE_WAYPOINT:
+               data.waypoint.construct();
+               data.waypoint.get()=rhs.data.waypoint.get();
+               break;
+       case TYPE_WAYPOINTMODEL:
+               data.waypoint_model.construct();
+               data.waypoint_model.get()=rhs.data.waypoint_model.get();
+               break;
+       case TYPE_KEYFRAME:
+               data.keyframe.construct();
+               data.keyframe.get()=rhs.data.keyframe.get();
+               break;
+       case TYPE_CANVAS:
+               data.canvas.construct();
+               data.canvas.get()=rhs.data.canvas.get();
+               break;
+       case TYPE_CANVASINTERFACE:
+               data.canvas_interface.construct();
+               data.canvas_interface.get()=rhs.data.canvas_interface.get();
+               break;
+       case TYPE_TIME:
+               data.time.construct();
+               data.time.get()=rhs.data.time.get();
+               break;
+       case TYPE_LAYER:
+               data.layer.construct();
+               data.layer.get()=rhs.data.layer.get();
+               break;
+       case TYPE_VALUENODE:
+               data.value_node.construct();
+               data.value_node.get()=rhs.data.value_node.get();
+               break;
+       case TYPE_VALUEDESC:
+               data.value_desc.construct();
+               data.value_desc.get()=rhs.data.value_desc.get();
+               break;
+       case TYPE_VALUE:
+               data.value.construct();
+               data.value.get()=rhs.data.value.get();
+               break;
+       case TYPE_RENDDESC:
+               data.rend_desc.construct();
+               data.rend_desc.get()=rhs.data.rend_desc.get();
+               break;
+       case TYPE_STRING:
+               data.string.construct();
+               data.string.get()=rhs.data.string.get();
+               break;
+
+       case TYPE_INTEGER:
+               data.integer=rhs.data.integer;
+               break;
+       case TYPE_EDITMODE:
+               data.integer=rhs.data.integer;
+               break;
+       case TYPE_REAL:
+               data.real=rhs.data.real;
+               break;
+       case TYPE_BOOL:
+               data.b=rhs.data.b;
+               break;
+
+       case TYPE_NIL:
+               break;
+
+       default:
+               assert(0);
+               break;
+       }
+       return *this;
+}
+
+void
+Param::clear()
+{
+       switch(type_)
+       {
+       case TYPE_ACTIVEPOINT:
+               data.activepoint.destruct();
+               break;
+       case TYPE_WAYPOINT:
+               data.waypoint.destruct();
+               break;
+       case TYPE_WAYPOINTMODEL:
+               data.waypoint_model.destruct();
+               break;
+       case TYPE_KEYFRAME:
+               data.keyframe.destruct();
+               break;
+       case TYPE_CANVAS:
+               data.canvas.destruct();
+               break;
+       case TYPE_CANVASINTERFACE:
+               data.canvas_interface.destruct();
+               break;
+       case TYPE_LAYER:
+               data.layer.destruct();
+               break;
+       case TYPE_TIME:
+               data.time.destruct();
+               break;
+       case TYPE_VALUENODE:
+               data.value_node.destruct();
+               break;
+       case TYPE_VALUEDESC:
+               data.value_desc.destruct();
+               break;
+       case TYPE_VALUE:
+               data.value.destruct();
+               break;
+       case TYPE_RENDDESC:
+               data.rend_desc.destruct();
+               break;
+       case TYPE_STRING:
+               data.string.destruct();
+               break;
+
+       case TYPE_NIL:
+       case TYPE_EDITMODE:
+       case TYPE_INTEGER:
+       case TYPE_REAL:
+       case TYPE_BOOL:
+               break;
+
+       default:
+               assert(0);
+               break;
+       }
+       type_=TYPE_NIL;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/action_param.h b/synfig-studio/trunk/src/sinfgapp/action_param.h
new file mode 100644 (file)
index 0000000..8771204
--- /dev/null
@@ -0,0 +1,236 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_param.h
+**     \brief Template File
+**
+**     $Id: action_param.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_PARAM_H
+#define __SINFG_APP_ACTION_PARAM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/string.h>
+#include <sinfg/canvas.h>
+#include <ETL/handle>
+#include <ETL/stringf>
+#include <ETL/trivial>
+
+#include <map>
+#include <list>
+
+#include <sinfg/layer.h>
+#include <sinfg/canvas.h>
+#include <sinfg/valuenode.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/value.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/string.h>
+#include <sinfg/keyframe.h>
+#include <sinfg/waypoint.h>
+
+#include "editmode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg {
+class ProgressCallback;
+class Canvas;
+class RendDesc;
+}; // END of namespace sinfg
+
+namespace sinfgapp {
+
+class CanvasInterface;
+       
+namespace Action {     
+
+//! Action Parameter
+class Param
+{
+public:
+       enum Type
+       {
+               TYPE_NIL,
+               TYPE_INTEGER,
+               TYPE_REAL,
+               TYPE_BOOL,
+               TYPE_ACTIVEPOINT,
+               TYPE_WAYPOINT,
+               TYPE_WAYPOINTMODEL,
+               TYPE_KEYFRAME,
+               TYPE_CANVAS,
+               TYPE_LAYER,
+               TYPE_VALUENODE,
+               TYPE_VALUEDESC,
+               TYPE_VALUE,
+               TYPE_STRING,
+               TYPE_TIME,
+               TYPE_CANVASINTERFACE,
+               TYPE_EDITMODE,
+               TYPE_RENDDESC,
+               
+               TYPE_END
+       };
+private:
+       Type type_;
+
+       union
+       {
+               etl::trivial<sinfg::Canvas::LooseHandle> canvas;
+               etl::trivial<sinfg::Layer::LooseHandle> layer;
+               etl::trivial<sinfg::ValueNode::LooseHandle> value_node;
+               etl::trivial<sinfg::ValueBase> value;
+               etl::trivial<sinfg::Activepoint> activepoint;
+               etl::trivial<sinfg::ValueNode_Animated::Waypoint> waypoint;
+               etl::trivial<sinfg::ValueNode_Animated::Waypoint::Model> waypoint_model;
+               etl::trivial<sinfg::String> string;
+               etl::trivial<sinfg::Keyframe> keyframe;
+               etl::trivial<sinfg::Time> time;
+               etl::trivial<sinfgapp::ValueDesc> value_desc;
+               etl::trivial<etl::loose_handle<sinfgapp::CanvasInterface> > canvas_interface;
+               etl::trivial<sinfg::RendDesc> rend_desc;
+               int integer;
+               sinfg::Real real;
+               bool b;
+               EditMode edit_mode;
+               
+       } data;
+public:
+
+       Param():type_(TYPE_NIL) { }
+       Param(const Param &x);
+       Param(const etl::handle<sinfgapp::CanvasInterface>& x);
+       Param(const etl::loose_handle<sinfgapp::CanvasInterface>& x);
+//     Param(sinfgapp::CanvasInterface* x);
+       Param(const sinfg::Canvas::Handle& x);
+       Param(const sinfg::Canvas::LooseHandle& x);
+       Param(const sinfg::Layer::Handle& x);
+       Param(const sinfg::Layer::LooseHandle& x);
+       Param(const sinfg::ValueNode::Handle& x);
+       Param(const sinfg::ValueNode::LooseHandle& x);
+       Param(const sinfg::Activepoint& x);
+       Param(const sinfg::Waypoint& x);
+       Param(const sinfg::Waypoint::Model& x);
+       Param(const sinfg::String& x);
+       Param(const sinfg::RendDesc& x);
+       Param(const char * x);
+       Param(const sinfg::Keyframe& x);
+       Param(const sinfgapp::ValueDesc& x);
+       Param(const int& x);
+       Param(const EditMode& x);
+       Param(const sinfg::Real& x);
+       Param(const sinfg::Time& x);
+       Param(const bool& x);
+       Param(const sinfg::ValueBase& x);
+
+       ~Param();
+       
+       Param& operator=(const Param& rhs);
+       
+       void clear();
+       
+       const sinfg::Canvas::LooseHandle& get_canvas()const { assert(type_==TYPE_CANVAS); return data.canvas.get(); }
+       const etl::loose_handle<sinfgapp::CanvasInterface>& get_canvas_interface()const { assert(type_==TYPE_CANVASINTERFACE); return data.canvas_interface.get(); }
+       const sinfg::Layer::LooseHandle& get_layer()const { assert(type_==TYPE_LAYER); return data.layer.get(); }
+       const sinfg::ValueNode::LooseHandle& get_value_node()const { assert(type_==TYPE_VALUENODE); return data.value_node.get(); }
+       const sinfg::ValueBase& get_value()const { assert(type_==TYPE_VALUE); return data.value.get(); }
+       const sinfg::Activepoint& get_activepoint()const { assert(type_==TYPE_ACTIVEPOINT); return data.activepoint.get(); }
+       const sinfg::Waypoint& get_waypoint()const { assert(type_==TYPE_WAYPOINT); return data.waypoint.get(); }
+       const sinfg::Waypoint::Model& get_waypoint_model()const { assert(type_==TYPE_WAYPOINTMODEL); return data.waypoint_model.get(); }
+       const sinfg::String& get_string()const { assert(type_==TYPE_STRING); return data.string.get(); }
+       const sinfg::Keyframe& get_keyframe()const { assert(type_==TYPE_KEYFRAME); return data.keyframe.get(); }
+       const sinfgapp::ValueDesc& get_value_desc()const { assert(type_==TYPE_VALUEDESC); return data.value_desc.get(); }
+       const sinfg::Real& get_real()const { assert(type_==TYPE_REAL); return data.real; }
+       const sinfg::Time& get_time()const { assert(type_==TYPE_TIME); return data.time.get(); }
+       const sinfg::RendDesc& get_rend_desc()const { assert(type_==TYPE_RENDDESC); return data.rend_desc.get(); }
+       int get_integer()const { assert(type_==TYPE_INTEGER); return data.integer; }
+       EditMode get_edit_mode()const { assert(type_==TYPE_EDITMODE); return data.edit_mode; }
+       bool get_bool()const { assert(type_==TYPE_BOOL); return data.b; }
+
+
+       const Type& get_type()const { return type_; }
+}; // END of class Param
+
+class ParamList : public std::multimap<sinfg::String,Param>
+{
+public:
+       ParamList& add(const sinfg::String& name, const Param &x) { insert(std::pair<sinfg::String,Param>(name,x)); return *this; }
+       ParamList& add(const ParamList& x) { insert(x.begin(),x.end()); return *this; }
+}; // END of class ParamList
+
+class ParamDesc
+{
+private:
+       sinfg::String   name_;
+       sinfg::String   local_name_;
+       sinfg::String   desc_;
+       sinfg::String   mutual_exclusion_;
+       Param::Type     type_;
+       bool    user_supplied_;
+       bool    supports_multiple_;
+       bool    requires_multiple_;
+       bool    optional_;
+
+public:
+       ParamDesc(const sinfg::String &name, Param::Type type):
+               name_(name),
+               local_name_(name),
+               type_(type),
+               user_supplied_(false),
+               supports_multiple_(false),
+               requires_multiple_(false),
+               optional_(false)
+       { }
+       
+       const sinfg::String& get_name()const { return name_; }
+       const sinfg::String& get_desc()const { return desc_; }
+       const sinfg::String& get_mutual_exclusion()const { return mutual_exclusion_; }
+       const sinfg::String& get_local_name()const { return local_name_; }
+       const Param::Type& get_type()const { return type_; }
+       bool get_user_supplied()const { return user_supplied_; }
+       bool get_supports_multiple()const { return supports_multiple_||requires_multiple_; }
+       bool get_requires_multiple()const { return requires_multiple_; }
+       bool get_optional()const { return optional_; }
+
+       ParamDesc& set_local_name(const sinfg::String& x) { local_name_=x; return *this; }
+       ParamDesc& set_desc(const sinfg::String& x) { desc_=x; return *this; }
+       ParamDesc& set_mutual_exclusion(const sinfg::String& x) { mutual_exclusion_=x; return *this; }
+       ParamDesc& set_user_supplied(bool x=true) { user_supplied_=x; return *this; }
+       ParamDesc& set_supports_multiple(bool x=true) { supports_multiple_=x; return *this; }
+       ParamDesc& set_requires_multiple(bool x=true) { requires_multiple_=x; if(x)supports_multiple_=true; return *this; }
+       ParamDesc& set_optional(bool x=true) { optional_=x; return *this; }
+}; // END of class ParamDesc
+
+class ParamVocab : public std::list< ParamDesc > { };
+
+bool canidate_check(const ParamVocab& param_vocab, const ParamList& param_list);
+
+}; // END of namespace Action
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/action_system.cpp b/synfig-studio/trunk/src/sinfgapp/action_system.cpp
new file mode 100644 (file)
index 0000000..4a5e4d1
--- /dev/null
@@ -0,0 +1,711 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_system.cpp
+**     \brief Template File
+**
+**     $Id: action_system.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "action_system.h"
+#include "instance.h"
+#include "canvasinterface.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfgapp;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+
+Action::System::System():
+       action_count_(0)
+{
+       unset_ui_interface();
+       clear_redo_stack_on_new_action_=false;
+}
+
+Action::System::~System()
+{
+}
+
+bool
+Action::System::perform_action(handle<Action::Base> action)
+{
+       handle<UIInterface> uim(get_ui_interface());
+       
+       assert(action);
+       
+       if(!action->is_ready())
+       {
+               uim->error(action->get_name()+": "+_("Action is not ready."));
+               return false;
+       }       
+       
+       most_recent_action_=action;
+       
+       static bool inuse=false;
+
+       if(inuse) return false;
+
+       inuse=true;
+       try {
+               
+       assert(action);
+       
+       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+       
+       if(canvas_specific && canvas_specific->get_canvas())
+       {
+               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas_specific->get_canvas());
+               assert(canvas_interface);
+               uim=canvas_interface->get_ui_interface();
+       }
+
+       handle<Action::Undoable> undoable_action=handle<Action::Undoable>::cast_dynamic(action);
+       
+       // If we cannot undo this action, make sure
+       // that the user knows this.
+       if(!undoable_action)
+       {
+               if(uim->yes_no(
+                       action->get_name(),
+                       _("This action cannot be undone! Are you sure you want to continue?"),
+                       UIInterface::RESPONSE_NO
+                       ) == UIInterface::RESPONSE_NO
+               )
+                       return false;
+               else
+               {
+                       // Because this action cannot be undone,
+                       // we need to clear the undo stack
+                       clear_undo_stack();
+               }
+       }
+       else
+               assert(undoable_action->is_active());
+
+       // Perform the action
+       try { action->perform(); }
+       catch(Action::Error err)
+       {
+               uim->task(action->get_name()+' '+_("Failed"));
+               inuse=false;
+
+               if(err.get_type()!=Action::Error::TYPE_UNABLE)
+               {
+                       if(err.get_desc().empty())
+                               uim->error(action->get_name()+": "+strprintf("%d",err.get_type()));             
+                       else
+                               uim->error(action->get_name()+": "+err.get_desc());             
+               }
+
+               // If action failed for whatever reason, just return false and do
+               // not add the action onto the list
+               return false;
+       }
+       catch(std::exception err)
+       {
+               uim->task(action->get_name()+' '+_("Failed"));
+               inuse=false;
+
+               uim->error(action->get_name()+": "+err.what());         
+
+               // If action failed for whatever reason, just return false and do
+               // not add the action onto the list
+               return false;
+       }
+       catch(...)
+       {
+               uim->task(action->get_name()+' '+_("Failed"));
+               inuse=false;
+
+               // If action failed for whatever reason, just return false and do
+               // not add the action onto the list
+               return false;
+       }
+
+       // Clear the redo stack
+       if(clear_redo_stack_on_new_action_)
+               clear_redo_stack();     
+
+       if(!group_stack_.empty())
+               group_stack_.front()->inc_depth();
+       else
+               inc_action_count();
+       
+       // Push this action onto the action list if we can undo it
+       if(undoable_action)
+       {
+               // If necessary, signal the change in status of undo
+               if(undo_action_stack_.empty()) signal_undo_status_(true);
+               
+               // Add it to the list
+               undo_action_stack_.push_front(undoable_action);
+
+               // Signal that a new action has been added
+               if(group_stack_.empty())
+                       signal_new_action()(undoable_action);
+       }
+               
+       inuse=false;
+
+       uim->task(action->get_name()+' '+_("Successful"));
+
+       // If the action has "dirtied" the preview, signal it.
+       if(0)if(canvas_specific && canvas_specific->is_dirty())
+       {
+               Canvas::Handle canvas=canvas_specific->get_canvas();
+               if(!group_stack_.empty())
+                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
+               else
+               {
+                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+                       assert(canvas_interface);
+                       DEBUGPOINT();
+                       //canvas_interface->signal_dirty_preview()();
+               }
+       }
+
+       }catch(...) { inuse=false; throw; }
+
+       return true;
+}
+
+bool
+sinfgapp::Action::System::undo_(handle<UIInterface> uim)
+{
+       handle<Action::Undoable> action(undo_action_stack().front());
+       most_recent_action_=action;
+       
+       try { if(action->is_active()) action->undo(); }
+       catch(Action::Error err)
+       {
+               if(err.get_type()!=Action::Error::TYPE_UNABLE)
+               {
+                       if(err.get_desc().empty())
+                               uim->error(action->get_name()+_(" (Undo): ")+strprintf("%d",err.get_type()));           
+                       else
+                               uim->error(action->get_name()+_(" (Undo): ")+err.get_desc());           
+               }
+
+               return false;
+       }
+       catch(std::runtime_error x)
+       {
+               uim->error(x.what());
+               return false;
+       }
+       catch(...)
+       {
+               return false;
+       }
+
+       dec_action_count();
+
+       if(redo_action_stack_.empty())  signal_redo_status()(true);
+
+       redo_action_stack_.push_front(undo_action_stack_.front());
+       undo_action_stack_.pop_front();
+
+       if(undo_action_stack_.empty())  signal_undo_status()(false);
+
+       if(!group_stack_.empty())
+               group_stack_.front()->dec_depth();
+
+       signal_undo_();
+
+       return true;
+}
+
+bool
+sinfgapp::Action::System::undo()
+{
+       //! \todo This function is not exception safe!
+       static bool inuse=false;
+
+       // If there is nothing on the action list, there is nothing to undo
+       if(undo_action_stack().empty() || inuse)
+               return false;
+
+       handle<Action::Undoable> action=undo_action_stack().front();
+       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+
+       handle<UIInterface> uim;
+       if(canvas_specific && canvas_specific->get_canvas())
+       {
+               Canvas::Handle canvas=canvas_specific->get_canvas();
+               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+               assert(canvas_interface);
+               uim=canvas_interface->get_ui_interface();
+       }
+       else
+               uim=get_ui_interface();
+
+       inuse=true;
+
+       if(!undo_(uim))
+       {
+               uim->error(undo_action_stack_.front()->get_name()+": "+_("Failed to undo."));
+               inuse=false;
+               return false;
+       }
+
+       inuse=false;
+       
+       // If the action has "dirtied" the preview, signal it.
+       if(0)if(action->is_active() && canvas_specific && canvas_specific->is_dirty())
+       {
+               Canvas::Handle canvas=canvas_specific->get_canvas();
+               if(!group_stack_.empty())
+                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
+               else
+               {
+                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+                       assert(canvas_interface);
+                       //DEBUGPOINT();
+                       //canvas_interface->signal_dirty_preview()();
+               }
+       }
+
+       return true;
+}
+
+bool
+Action::System::redo_(handle<UIInterface> uim)
+{
+       handle<Action::Undoable> action(redo_action_stack().front());
+       most_recent_action_=action;
+
+       try { if(action->is_active()) action->perform(); }
+       catch(Action::Error err)
+       {
+               if(err.get_type()!=Action::Error::TYPE_UNABLE)
+               {
+                       if(err.get_desc().empty())
+                               uim->error(action->get_name()+_(" (Redo): ")+strprintf("%d",err.get_type()));           
+                       else
+                               uim->error(action->get_name()+_(" (Redo): ")+err.get_desc());           
+               }
+
+               return false;
+       }
+       catch(std::runtime_error x)
+       {
+               uim->error(x.what());
+               return false;
+       }
+       catch(...)
+       {
+               return false;
+       }
+
+       inc_action_count();
+
+       if(undo_action_stack_.empty())  signal_undo_status()(true);
+
+       undo_action_stack_.push_front(redo_action_stack_.front());
+       redo_action_stack_.pop_front();
+
+       if(redo_action_stack_.empty())  signal_redo_status()(false);
+
+       if(!group_stack_.empty())
+               group_stack_.front()->inc_depth();
+
+       signal_redo_();
+
+       return true;
+}
+
+bool
+Action::System::redo()
+{
+       //! \todo This function is not exception safe!
+       static bool inuse=false;
+
+       // If there is nothing on the action list, there is nothing to undo
+       if(redo_action_stack_.empty() || inuse)
+               return false;
+
+       inuse=true;
+
+       handle<Action::Undoable> action=redo_action_stack().front();
+       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+
+       handle<UIInterface> uim;
+       if(canvas_specific && canvas_specific->get_canvas())
+       {
+               Canvas::Handle canvas=canvas_specific->get_canvas();
+               handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+               assert(canvas_interface);
+               uim=canvas_interface->get_ui_interface();
+       }
+       else
+               uim=get_ui_interface();
+
+       if(!redo_(uim))
+       {
+               uim->error(redo_action_stack_.front()->get_name()+": "+_("Failed to redo."));
+               inuse=false;
+               return false;
+       }
+
+       inuse=false;
+
+       // If the action has "dirtied" the preview, signal it.
+       if(0)if(action->is_active() && canvas_specific && canvas_specific->is_dirty())
+       {
+               Canvas::Handle canvas=canvas_specific->get_canvas();
+               if(!group_stack_.empty())
+                       group_stack_.front()->request_redraw(canvas_specific->get_canvas_interface());
+               else
+               {
+                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+                       assert(canvas_interface);
+                       //DEBUGPOINT();
+                       //canvas_interface->signal_dirty_preview()();
+               }
+       }
+
+       return true;
+}
+
+void
+Action::System::inc_action_count()const
+{
+       action_count_++;
+       if(action_count_==1)
+               signal_unsaved_status_changed_(true);
+       if(!action_count_)
+               signal_unsaved_status_changed_(false);
+}
+
+void
+Action::System::dec_action_count()const
+{
+       action_count_--;
+       if(action_count_==-1)
+               signal_unsaved_status_changed_(true);
+       if(!action_count_)
+               signal_unsaved_status_changed_(false);
+}
+
+void
+Action::System::reset_action_count()const
+{
+       if(!action_count_)
+               return;
+
+       action_count_=0;
+       signal_unsaved_status_changed_(false);
+}
+
+void
+Action::System::clear_undo_stack()
+{
+       if(undo_action_stack_.empty()) return;
+       undo_action_stack_.clear();
+       signal_undo_status_(false);
+       signal_undo_stack_cleared_();
+}
+       
+void
+Action::System::clear_redo_stack()
+{
+       if(redo_action_stack_.empty()) return;
+       redo_action_stack_.clear();
+       signal_redo_status_(false);
+       signal_redo_stack_cleared_();
+}
+
+bool
+Action::System::set_action_status(etl::handle<Action::Undoable> action, bool x)
+{
+       Stack::iterator iter;
+       int failed=false;
+       
+       if(action->is_active()==x)
+               return true;
+
+       handle<Action::Undoable> cur_pos=undo_action_stack_.front();
+
+       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+
+       handle<UIInterface> uim=new ConfidentUIInterface();
+       
+       iter=find(undo_action_stack_.begin(),undo_action_stack_.end(),action);
+       if(iter!=undo_action_stack_.end())
+       {
+               while(undo_action_stack_.front()!=action)
+               {
+                       if(!undo_(uim))
+                       {
+                               return false;
+                       }
+               } 
+               if(!undo_(uim))
+               {
+                       return false;
+               }
+               
+               action->set_active(x);
+
+               if(redo_(get_ui_interface()))
+               {
+                       signal_action_status_changed_(action);
+               }
+               else
+               {
+                       action->set_active(!x);
+                       failed=true;
+               }
+               
+               
+               while(undo_action_stack_.front()!=cur_pos)
+               {
+                       if(!redo_(uim))
+                       {
+                               redo_action_stack_.front()->set_active(false);
+                               signal_action_status_changed_(redo_action_stack_.front());
+                       }
+               }
+
+               if(!failed && canvas_specific && canvas_specific->is_dirty())
+               {
+                       Canvas::Handle canvas=canvas_specific->get_canvas();
+                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+                       assert(canvas_interface);
+                       //DEBUGPOINT();
+                       //canvas_interface->signal_dirty_preview()();
+               }
+
+               return true;
+       }
+
+       iter=find(redo_action_stack_.begin(),redo_action_stack_.end(),action);
+       if(iter!=redo_action_stack_.end())
+       {
+               action->set_active(x);
+               signal_action_status_changed_(action);
+
+
+
+
+               if(canvas_specific && canvas_specific->is_dirty())
+               {
+                       Canvas::Handle canvas=canvas_specific->get_canvas();
+                       handle<CanvasInterface> canvas_interface=static_cast<Instance*>(this)->find_canvas_interface(canvas);
+                       assert(canvas_interface);
+                       DEBUGPOINT();
+                       //canvas_interface->signal_dirty_preview()();
+               }
+
+               return true;
+       }
+
+       return false;
+}
+
+Action::PassiveGrouper::PassiveGrouper(etl::loose_handle<Action::System> instance_,sinfg::String name_):
+       instance_(instance_),
+       name_(name_),
+       redraw_requested_(false),
+       depth_(0)
+{
+       // Add this group onto the group stack
+       instance_->group_stack_.push_front(this);
+}
+
+void
+Action::PassiveGrouper::request_redraw(handle<CanvasInterface> x)
+{
+/*     DEBUGPOINT();
+       if(instance_->group_stack_.empty())
+       {
+               if(x!=canvas_interface_)
+               {
+                       DEBUGPOINT();
+                       x->signal_dirty_preview()();
+               }
+
+               redraw_requested_=false;
+       }
+       else
+       {
+               DEBUGPOINT();
+               if(instance_->group_stack_.back()==this)
+               {
+                       DEBUGPOINT();
+                       redraw_requested_=true;
+               }
+               else
+               {
+                       DEBUGPOINT();
+                       instance_->group_stack_.back()->request_redraw(x);
+                       redraw_requested_=false;
+               }
+               DEBUGPOINT();
+       }
+       DEBUGPOINT();
+*/
+       if(x)
+       {
+               redraw_requested_=true;
+               canvas_interface_=x;
+       }
+}
+
+Action::PassiveGrouper::~PassiveGrouper()
+{
+       assert(instance_->group_stack_.front()==this);
+       
+       // Remove this group from the group stack
+       instance_->group_stack_.pop_front();
+
+       handle<Action::Group> group;
+
+       if(depth_==1)
+       {
+               handle<Action::Undoable> action(instance_->undo_action_stack_.front());
+
+               group=handle<Action::Group>::cast_dynamic(action);
+
+               if(group)
+               {
+                       // If the only action inside of us is a group,
+                       // then we should rename the group to our name.
+                       group->set_name(name_);
+               }
+               else
+               {
+                       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+                       
+                       if(0)if(canvas_specific && canvas_specific->is_dirty() && canvas_specific->get_canvas_interface())
+                       {
+                               if(instance_->group_stack_.empty())
+                                       request_redraw(canvas_specific->get_canvas_interface());                                        
+                       }
+               }
+
+               if(instance_->group_stack_.empty())
+               {
+                       instance_->inc_action_count();
+                       instance_->signal_new_action()(instance_->undo_action_stack_.front());
+               }
+               else
+                       instance_->group_stack_.front()->inc_depth();
+
+       }
+       else
+       if(depth_>0)
+       {
+               group=new Action::Group(name_);
+               
+               for(int i=0;i<depth_;i++)
+       //      for(;depth_;depth_--)
+               {
+                       handle<Action::Undoable> action(instance_->undo_action_stack_.front());
+                       Action::CanvasSpecific* canvas_specific(dynamic_cast<Action::CanvasSpecific*>(action.get()));
+                       
+                       if(0)if(canvas_specific && canvas_specific->is_dirty())
+                       {
+                               group->set_dirty(true);
+                               group->set_canvas(canvas_specific->get_canvas());
+                               group->set_canvas_interface(canvas_specific->get_canvas_interface());
+                       }
+                       
+                       // Copy the action from the undo stack to the group
+                       group->add_action_front(action);
+       
+                       // Remove the action from the undo stack
+                       instance_->undo_action_stack_.pop_front();
+               }
+                       
+               // Push the group onto the stack
+               instance_->undo_action_stack_.push_front(group);
+       
+               if(0)if(group->is_dirty())
+                       request_redraw(group->get_canvas_interface());
+               //      group->get_canvas_interface()->signal_dirty_preview()();
+       
+               if(instance_->group_stack_.empty())
+               {
+                       instance_->inc_action_count();
+                       instance_->signal_new_action()(instance_->undo_action_stack_.front());
+               }
+               else
+                       instance_->group_stack_.front()->inc_depth();
+       }
+       
+       if(0)if(redraw_requested_)
+       {
+               if(instance_->group_stack_.empty())
+               {
+                       assert(canvas_interface_);
+                       DEBUGPOINT();
+                       canvas_interface_->signal_dirty_preview()();
+               }
+               else
+               {
+                       instance_->group_stack_.front()->request_redraw(canvas_interface_);
+                       redraw_requested_=false;
+               }
+       }
+}
+
+void
+Action::PassiveGrouper::cancel()
+{
+       bool error=false;
+
+       // Cancel any groupers that may be on top of us first
+       //while(instance_->group_stack_.front()!=this)
+       //      instance_->group_stack_.front()->cancel();
+       
+       sinfg::warning("Cancel depth: %d",depth_);
+       
+       while(depth_)
+               if(!instance_->undo())
+               {
+                       error=true;
+                       break;
+               }
+       
+       if(error)
+               instance_->get_ui_interface()->error(_("State restore failure"));
+       else
+               redraw_requested_=false;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/action_system.h b/synfig-studio/trunk/src/sinfgapp/action_system.h
new file mode 100644 (file)
index 0000000..266bfb3
--- /dev/null
@@ -0,0 +1,249 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_system.h
+**     \brief Template Header
+**
+**     $Id: action_system.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFGAPP_ACTIONSYSTEM_H
+#define __SINFGAPP_ACTIONSYSTEM_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "action.h"
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <ETL/handle>
+#include <sinfg/canvas.h>
+#include "uimanager.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class CanvasInterface;
+       
+namespace Action {
+
+
+       
+       
+       
+class System;
+
+//! Passive action grouping class
+class PassiveGrouper
+{
+       etl::loose_handle<System> instance_;
+       sinfg::String name_;
+       bool redraw_requested_;
+       int depth_;
+       etl::handle<CanvasInterface> canvas_interface_;
+public:
+
+       PassiveGrouper(etl::loose_handle<System> instance_,sinfg::String name_);
+
+       ~PassiveGrouper();
+
+       const sinfg::String &get_name()const { return name_; }
+
+       void set_name(const sinfg::String &x) { name_=x; }
+
+       etl::loose_handle<System> get_instance() { return instance_; }
+       
+       void request_redraw(etl::handle<CanvasInterface>);
+       
+       void cancel();
+       
+       void inc_depth() { depth_++; }
+
+       void dec_depth() { depth_--; }
+
+       const int &get_depth()const { return depth_; }
+}; // END of class Action::PassiveGrouper
+
+typedef std::list< etl::handle<Action::Undoable> > Stack;
+       
+class System : public etl::shared_object, public sigc::trackable
+{
+       friend class PassiveGrouper;
+               
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+
+       Stack undo_action_stack_;
+       Stack redo_action_stack_;
+
+       etl::handle<Action::Base> most_recent_action_;
+
+       std::list<PassiveGrouper*> group_stack_;
+
+       sigc::signal<void,bool> signal_undo_status_;
+       sigc::signal<void,bool> signal_redo_status_;
+       sigc::signal<void,etl::handle<Action::Undoable> > signal_new_action_;
+       sigc::signal<void> signal_undo_stack_cleared_;
+       sigc::signal<void> signal_redo_stack_cleared_;
+       sigc::signal<void> signal_undo_;
+       sigc::signal<void> signal_redo_;
+       sigc::signal<void,etl::handle<Action::Undoable> > signal_action_status_changed_;
+       
+       mutable sigc::signal<void,bool> signal_unsaved_status_changed_;
+
+       //! If this is non-zero, then the changes have not yet been saved.
+       mutable int action_count_;
+
+       etl::handle<UIInterface> ui_interface_;
+
+       bool clear_redo_stack_on_new_action_;
+       
+       /*
+ -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
+       */
+
+private:
+
+       bool undo_(etl::handle<UIInterface> uim);
+       bool redo_(etl::handle<UIInterface> uim);
+
+       /*
+ -- ** -- S I G N A L   T E R M I N A L S -------------------------------------
+       */
+
+private:
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       System();
+       ~System();
+
+       /*
+       template <typename T> bool
+       perform_action(T x)
+       {
+               etl::handle<Action::Base> action((Action::Base*)new T(x));
+               return perform_action(action);
+       }
+       */
+
+       const etl::handle<Action::Base>& get_most_recent_action() { return most_recent_action_; }
+
+       bool get_clear_redo_stack_on_new_action()const { return clear_redo_stack_on_new_action_; }
+       
+       void set_clear_redo_stack_on_new_action(bool x) { clear_redo_stack_on_new_action_=x; }
+
+       bool perform_action(etl::handle<Action::Base> action);
+
+       bool set_action_status(etl::handle<Action::Undoable> action, bool x);
+
+       const Stack &undo_action_stack()const { return undo_action_stack_; }
+
+       const Stack &redo_action_stack()const { return redo_action_stack_; }
+
+       //! Undoes the last action
+       bool undo();
+
+       //! Redoes the last undone action
+       bool redo();
+       
+       //! Clears the undo stack. 
+       void clear_undo_stack();
+       
+       //! Clears the redo stack. 
+       void clear_redo_stack();
+       
+       //! Increments the action counter
+       /*! \note You should not have to call this under normal circumstances.
+       **      \see dec_action_count(), reset_action_count(), get_action_count() */
+       void inc_action_count()const;
+
+       //! Decrements the action counter
+       /*! \note You should not have to call this under normal circumstances.
+       **      \see inc_action_count(), reset_action_count(), get_action_count() */
+       void dec_action_count()const;
+
+       //! Resets the action counter
+       /*! \note You should not have to call this under normal circumstances.
+       **      \see inc_action_count(), dec_action_count(), get_action_count() */
+       void reset_action_count()const;
+
+       //! Returns the number of actions performed since last save.
+       /*!     \see inc_action_count(), dec_action_count(), reset_action_count() */
+       int get_action_count()const { return action_count_; }
+
+       void set_ui_interface(const etl::handle<UIInterface> &uim) { assert(uim); ui_interface_=uim; }
+       void unset_ui_interface() { ui_interface_=new DefaultUIInterface(); }
+       const etl::handle<UIInterface> &get_ui_interface() { return ui_interface_; }    
+
+       /*
+ -- ** -- S I G N A L   I N T E R F A C E S -----------------------------------
+       */
+
+public:
+
+       sigc::signal<void,bool>& signal_unsaved_status_changed() { return signal_unsaved_status_changed_; }
+
+       sigc::signal<void,bool>& signal_undo_status() { return signal_undo_status_; }
+
+       sigc::signal<void,bool>& signal_redo_status() { return signal_redo_status_; }
+
+       sigc::signal<void>& signal_undo_stack_cleared() { return signal_undo_stack_cleared_; }
+
+       sigc::signal<void>& signal_redo_stack_cleared() { return signal_redo_stack_cleared_; }
+
+       sigc::signal<void>& signal_undo() { return signal_undo_; }
+
+       sigc::signal<void>& signal_redo() { return signal_redo_; }
+
+       //!     Called whenever an undoable action is processed and added to the stack.
+       sigc::signal<void,etl::handle<Action::Undoable> >& signal_new_action() { return signal_new_action_; }
+
+       sigc::signal<void,etl::handle<Action::Undoable> >& signal_action_status_changed() { return signal_action_status_changed_; }
+
+}; // END of class Action::System
+
+
+}; // END of namespace sinfgapp::Action
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointadd.cpp
new file mode 100644 (file)
index 0000000..5dcc281
--- /dev/null
@@ -0,0 +1,204 @@
+/* === S I N F G =========================================================== */
+/*!    \file acitvepointadd.cpp
+**     \brief Template File
+**
+**     $Id: activepointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointAdd);
+ACTION_SET_NAME(Action::ActivepointAdd,"activepoint_add");
+ACTION_SET_LOCAL_NAME(Action::ActivepointAdd,"Add Activepoint");
+ACTION_SET_TASK(Action::ActivepointAdd,"add");
+ACTION_SET_CATEGORY(Action::ActivepointAdd,Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::ActivepointAdd,0);
+ACTION_SET_VERSION(Action::ActivepointAdd,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointAdd,"$Id: activepointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointAdd::ActivepointAdd()
+{
+       activepoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("New Activepoint"))
+               .set_desc(_("Activepoint to be added"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_desc(_("Time where activepoint is to be added"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::ActivepointAdd::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               // We need either a activepoint or a time.
+               if(x.count("activepoint") || x.count("time"))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               if(time_set)
+                       calc_activepoint();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT && !time_set)
+       {
+               activepoint=param.get_activepoint();
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && activepoint.get_time()==Time::begin()-1)
+       {
+               activepoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointAdd::is_ready()const
+{
+       if(!value_node || activepoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a activepoint. In this case, we need to calculate the value
+// of the activepoint
+void
+Action::ActivepointAdd::calc_activepoint()
+{      
+       const Time time(activepoint.get_time());
+       activepoint.set_state(value_node->list[index].status_at_time(time));
+       activepoint.set_priority(0);
+       
+       // In this case, nothing is really changing, so there will be
+       // no need to redraw the window
+       set_dirty(false);
+}
+
+void
+Action::ActivepointAdd::perform()
+{      
+       try { value_node->list[index].find(activepoint.get_time()); throw Error(_("A Activepoint already exists at this point in time"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { if(value_node->list[index].find(activepoint)!=value_node->list[index].timing_info.end()) throw Error(_("This activepoint is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+       
+       value_node->list[index].add(activepoint);
+       value_node->changed();
+       
+       /*if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       */
+}
+
+void
+Action::ActivepointAdd::undo()
+{
+       value_node->list[index].erase(activepoint);
+       value_node->changed();
+       /*
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       */
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointadd.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointadd.h
new file mode 100644 (file)
index 0000000..2eb39f5
--- /dev/null
@@ -0,0 +1,80 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointadd.h
+**     \brief Template File
+**
+**     $Id: activepointadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTADD_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ActivepointAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Activepoint activepoint;
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+
+       bool time_set;
+
+       void calc_activepoint();
+
+public:
+
+       ActivepointAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointremove.cpp
new file mode 100644 (file)
index 0000000..f940cd8
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointremove.cpp
+**     \brief Template File
+**
+**     $Id: activepointremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointRemove);
+ACTION_SET_NAME(Action::ActivepointRemove,"activepoint_remove");
+ACTION_SET_LOCAL_NAME(Action::ActivepointRemove,"Remove Activepoint");
+ACTION_SET_TASK(Action::ActivepointRemove,"remove");
+ACTION_SET_CATEGORY(Action::ActivepointRemove,Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::ActivepointRemove,0);
+ACTION_SET_VERSION(Action::ActivepointRemove,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointRemove,"$Id: activepointremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointRemove::ActivepointRemove()
+{
+       activepoint.set_time(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("Activepoint"))
+               .set_desc(_("Activepoint to be changed"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ActivepointRemove::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT)
+       {
+               activepoint=param.get_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointRemove::is_ready()const
+{
+       if(!value_node || activepoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ActivepointRemove::perform()
+{      
+       ValueNode_DynamicList::ListEntry::ActivepointList::iterator iter;
+       
+       try { iter=value_node->list[index].find(activepoint); }
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find activepoint"));
+       }       
+
+       value_node->list[index].erase(activepoint);
+       value_node->changed();
+       
+       /*
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       */
+}
+
+void
+Action::ActivepointRemove::undo()
+{
+       try { value_node->list[index].find(activepoint.get_time()); throw Error(_("A Activepoint already exists at this point in time"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { if(value_node->list[index].find(activepoint)!=value_node->list[index].timing_info.end()) throw Error(_("This activepoint is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+       
+       value_node->list[index].add(activepoint);
+       value_node->changed();
+       /*
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       */
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointremove.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointremove.h
new file mode 100644 (file)
index 0000000..6c2eb1e
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointremove.h
+**     \brief Template File
+**
+**     $Id: activepointremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTREMOVE_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ActivepointRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+       sinfg::Activepoint activepoint;
+
+public:
+
+       ActivepointRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointset.cpp
new file mode 100644 (file)
index 0000000..42faf94
--- /dev/null
@@ -0,0 +1,289 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointset.cpp
+**     \brief Template File
+**
+**     $Id: activepointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointSet);
+ACTION_SET_NAME(Action::ActivepointSet,"activepoint_set");
+ACTION_SET_LOCAL_NAME(Action::ActivepointSet,"Set Activepoint");
+ACTION_SET_TASK(Action::ActivepointSet,"set");
+ACTION_SET_CATEGORY(Action::ActivepointSet,Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::ActivepointSet,0);
+ACTION_SET_VERSION(Action::ActivepointSet,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointSet,"$Id: activepointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointSet::ActivepointSet()
+{
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("Activepoint"))
+               .set_desc(_("Activepoint to be changed"))
+               .set_supports_multiple()
+       );
+
+       return ret;
+}
+
+bool
+Action::ActivepointSet::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT)
+       {
+               //NOTE: there is no duplication checking at the moment
+               activepoints.push_back(param.get_activepoint());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointSet::is_ready()const
+{
+       if(!value_node || activepoints.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ActivepointSet::perform()
+{      
+       typedef ValueNode_DynamicList::ListEntry::ActivepointList AList;
+       AList::iterator iter;
+
+#if 1  
+       vector<AList::iterator> iters;
+       vector<Activepoint>::iterator i = activepoints.begin(), end = activepoints.end();       
+       
+       for(; i != end; ++i)
+       {
+               try { iters.push_back(value_node->list[index].find(*i)); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       throw Error(_("Unable to find activepoint"));
+               }
+       }
+       
+       //check to see which valuenodes are going to override because of the time...
+       ValueNode_DynamicList::ListEntry::findresult timeiter;
+       
+       for(i = activepoints.begin(); i != end; ++i)
+       {
+               timeiter = value_node->list[index].find_time(i->get_time());
+               
+               bool candelete = timeiter.second;
+       
+               //we only want to track overwrites (not activepoints that are also being modified)
+               if(candelete)
+               {
+                       for(vector<AList::iterator>::iterator ii = iters.begin(); ii != iters.end(); ++ii)
+                       {
+                               if(timeiter.first == *ii)
+                               {
+                                       candelete = false;
+                                       break;
+                               }
+                       }
+               }
+               
+               //if we can still delete it after checking, record it, and then remove them all later
+               if(candelete)
+               {
+                       Activepoint a = *timeiter.first;
+                       overwritten_activepoints.push_back(a);
+               }
+       }
+       
+       //overwrite all the valuenodes we're supposed to set
+       {
+               i = activepoints.begin();
+               for(vector<AList::iterator>::iterator ii = iters.begin(); ii != iters.end() && i != end; ++ii, ++i)
+               {
+                       old_activepoints.push_back(**ii);
+                       **ii = *i; //set the point to the corresponding point in the normal waypoint list
+               }
+       }
+       
+       //remove all the points we're supposed to be overwritting
+       {
+               vector<Activepoint>::iterator   oi = overwritten_activepoints.begin(),
+                                                                               oend = overwritten_activepoints.end();
+               for(; oi != oend; ++oi)
+               {
+                       value_node->list[index].erase(*oi);
+               }
+       }
+
+#else  
+       try { iter=value_node->list[index].find(activepoint); }
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find activepoint"));
+       }       
+
+       //find the value at the old time before we replace it
+       ValueNode_DynamicList::ListEntry::findresult timeiter;
+       timeiter = value_node->list[index].find_time(activepoint.get_time());
+       
+       //we only want to track overwrites (not inplace modifications)
+       if(timeiter.second && activepoint.get_uid() == timeiter.first->get_uid())
+       {
+               timeiter.second = false;
+       }
+               
+       old_activepoint=*iter;
+       *iter=activepoint;
+       
+       if(timeiter.second)
+       {
+               sinfg::info("Erasing the found activepoint");
+               time_overwrite = true;
+               overwritten_ap = *timeiter.first;
+               
+               value_node->list[index].erase(overwritten_ap);
+       }
+       
+#endif
+       
+       value_node->list[index].timing_info.sort();
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
+
+void
+Action::ActivepointSet::undo()
+{
+       ValueNode_DynamicList::ListEntry::ActivepointList::iterator iter;
+
+#if 1  
+       vector<Activepoint>::iterator i = old_activepoints.begin(), end = old_activepoints.end();       
+       
+       for(; i != end; ++i)
+       {
+               try { iter = value_node->list[index].find(*i); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       throw Error(_("Unable to find activepoint"));
+               }
+               
+               //overwrite with old one
+               *iter = *i;
+       }
+               
+       //add back in all the points that we removed before...
+       {
+               vector<Activepoint>::iterator   oi = overwritten_activepoints.begin(),
+                                                                               oend = overwritten_activepoints.end();
+               for(; oi != oend; ++oi)
+               {
+                       value_node->list[index].add(*oi);
+               }
+       }
+
+#else  
+       try { iter=value_node->list[index].find(activepoint); }
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find activepoint"));
+       }       
+
+       *iter=old_activepoint;
+               
+       if(time_overwrite)
+       {
+               value_node->list[index].add(overwritten_ap);
+       }
+#endif
+       
+       value_node->list[index].timing_info.sort();
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointset.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointset.h
new file mode 100644 (file)
index 0000000..8937afe
--- /dev/null
@@ -0,0 +1,80 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointset.h
+**     \brief Template File
+**
+**     $Id: activepointset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTSET_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ActivepointSet :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+       
+       std::vector<sinfg::Activepoint> activepoints;
+       std::vector<sinfg::Activepoint> old_activepoints;       
+
+       std::vector<sinfg::Activepoint> overwritten_activepoints;
+
+public:
+
+       ActivepointSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.cpp
new file mode 100644 (file)
index 0000000..6324840
--- /dev/null
@@ -0,0 +1,212 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsetoff.cpp
+**     \brief Template File
+**
+**     $Id: activepointsetoff.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointsetoff.h"
+#include "activepointsetsmart.h"
+#include "valuenodelinkconnect.h"
+#include "valuenodereplace.h"
+
+#include "activepointset.h"
+#include "activepointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointSetOff);
+ACTION_SET_NAME(Action::ActivepointSetOff,"activepoint_set_off");
+ACTION_SET_LOCAL_NAME(Action::ActivepointSetOff,_("Mark Activepoint as \"Off\""));
+ACTION_SET_TASK(Action::ActivepointSetOff,"set_off");
+ACTION_SET_CATEGORY(Action::ActivepointSetOff,Action::CATEGORY_ACTIVEPOINT|Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ActivepointSetOff,-9);
+ACTION_SET_VERSION(Action::ActivepointSetOff,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointSetOff,"$Id: activepointsetoff.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointSetOff::ActivepointSetOff()
+{
+       activepoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointSetOff::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("Activepoint"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ActivepointSetOff::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+               
+               // We are only a canidate if this canvas is animated.
+               Canvas::Handle canvas(x.find("canvas")->second.get_canvas());
+               if(canvas->rend_desc().get_time_start()==canvas->rend_desc().get_time_end())
+                       return false;
+               
+               // We need either a activepoint or a time.
+               if(x.count("activepoint") || x.count("time"))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointSetOff::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               if(time_set)
+                       calc_activepoint();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT && !time_set)
+       {
+               activepoint=param.get_activepoint();
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && activepoint.get_time()==Time::begin()-1)
+       {
+               activepoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointSetOff::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing value_node");
+
+       if(activepoint.get_time()==(Time::begin()-1))
+               sinfg::error("Missing activepoint");
+       
+       if(!value_node || activepoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a activepoint. In this case, we need to calculate the value
+// of the activepoint
+void
+Action::ActivepointSetOff::calc_activepoint()
+{      
+       const Time time(activepoint.get_time());
+       
+       try { activepoint=*value_node->list[index].find(time); }
+       catch(...)
+       {
+               activepoint.set_time(time);
+               activepoint.set_state(value_node->list[index].status_at_time(time));
+               activepoint.set_priority(0);
+       }
+}
+
+void
+Action::ActivepointSetOff::prepare()
+{
+       clear();
+
+       // Turn the activepoint off
+       activepoint.set_state(false);
+
+       Action::Handle action(ActivepointSetSmart::create());
+       
+       action->set_param("edit_mode",get_edit_mode());
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("value_desc",value_desc);
+       action->set_param("activepoint",activepoint);
+
+       assert(action->is_ready());
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+       
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointsetoff.h
new file mode 100644 (file)
index 0000000..74582ca
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsetoff.h
+**     \brief Template File
+**
+**     $Id: activepointsetoff.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTSETOFF_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTSETOFF_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include <list>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ActivepointSetOff :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+       bool time_set;
+       sinfg::Activepoint activepoint;
+
+       void calc_activepoint();
+
+public:
+
+       ActivepointSetOff();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointseton.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointseton.cpp
new file mode 100644 (file)
index 0000000..154893e
--- /dev/null
@@ -0,0 +1,212 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointseton.cpp
+**     \brief Template File
+**
+**     $Id: activepointseton.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointseton.h"
+#include "activepointsetsmart.h"
+#include "valuenodelinkconnect.h"
+#include "valuenodereplace.h"
+
+#include "activepointset.h"
+#include "activepointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointSetOn);
+ACTION_SET_NAME(Action::ActivepointSetOn,"activepoint_set_on");
+ACTION_SET_LOCAL_NAME(Action::ActivepointSetOn,_("Mark Activepoint as \"On\""));
+ACTION_SET_TASK(Action::ActivepointSetOn,"set_on");
+ACTION_SET_CATEGORY(Action::ActivepointSetOn,Action::CATEGORY_ACTIVEPOINT|Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ActivepointSetOn,-10);
+ACTION_SET_VERSION(Action::ActivepointSetOn,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointSetOn,"$Id: activepointseton.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointSetOn::ActivepointSetOn()
+{
+       activepoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointSetOn::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("Activepoint"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ActivepointSetOn::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               // We are only a canidate if this canvas is animated.
+               Canvas::Handle canvas(x.find("canvas")->second.get_canvas());
+               if(canvas->rend_desc().get_time_start()==canvas->rend_desc().get_time_end())
+                       return false;
+
+               // We need either a activepoint or a time.
+               if(x.count("activepoint") || x.count("time"))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointSetOn::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               if(time_set)
+                       calc_activepoint();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT && !time_set)
+       {
+               activepoint=param.get_activepoint();
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && activepoint.get_time()==Time::begin()-1)
+       {
+               activepoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointSetOn::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing value_node");
+
+       if(activepoint.get_time()==(Time::begin()-1))
+               sinfg::error("Missing activepoint");
+       
+       if(!value_node || activepoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a activepoint. In this case, we need to calculate the value
+// of the activepoint
+void
+Action::ActivepointSetOn::calc_activepoint()
+{      
+       const Time time(activepoint.get_time());
+       
+       try { activepoint=*value_node->list[index].find(time); }
+       catch(...)
+       {
+               activepoint.set_time(time);
+               activepoint.set_state(value_node->list[index].status_at_time(time));
+               activepoint.set_priority(0);
+       }
+}
+
+void
+Action::ActivepointSetOn::prepare()
+{
+       clear();
+
+       // Turn the activepoint off
+       activepoint.set_state(true);
+
+       Action::Handle action(ActivepointSetSmart::create());
+       
+       action->set_param("edit_mode",get_edit_mode());
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("value_desc",value_desc);
+       action->set_param("activepoint",activepoint);
+
+       assert(action->is_ready());
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+       
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointseton.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointseton.h
new file mode 100644 (file)
index 0000000..5198109
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointseton.h
+**     \brief Template File
+**
+**     $Id: activepointseton.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTSETON_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTSETON_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include <list>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ActivepointSetOn :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+       sinfg::Activepoint activepoint;
+       bool time_set;
+
+       void calc_activepoint();
+
+public:
+
+       ActivepointSetOn();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.cpp
new file mode 100644 (file)
index 0000000..2a85ccc
--- /dev/null
@@ -0,0 +1,364 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsetsmart.cpp
+**     \brief Template File
+**
+**     $Id: activepointsetsmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointsetsmart.h"
+#include "valuenodelinkconnect.h"
+#include "valuenodereplace.h"
+
+#include "activepointset.h"
+#include "activepointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointSetSmart);
+ACTION_SET_NAME(Action::ActivepointSetSmart,"activepoint_set_smart");
+ACTION_SET_LOCAL_NAME(Action::ActivepointSetSmart,_("Set Activepoint (Smart)"));
+ACTION_SET_TASK(Action::ActivepointSetSmart,"set");
+ACTION_SET_CATEGORY(Action::ActivepointSetSmart,Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::ActivepointSetSmart,0);
+ACTION_SET_VERSION(Action::ActivepointSetSmart,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointSetSmart,"$Id: activepointsetsmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointSetSmart::ActivepointSetSmart()
+{
+       activepoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ActivepointSetSmart::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("New Activepoint"))
+               .set_desc(_("Activepoint to be added"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_desc(_("Time where activepoint is to be added"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ActivepointSetSmart::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               // We need either a activepoint or a time.
+               if(x.count("activepoint") || x.count("time"))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ActivepointSetSmart::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               if(time_set)
+                       calc_activepoint();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT && !time_set)
+       {
+               activepoint=param.get_activepoint();
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && activepoint.get_time()==Time::begin()-1)
+       {
+               activepoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointSetSmart::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing value_node");
+
+       if(activepoint.get_time()==(Time::begin()-1))
+               sinfg::error("Missing activepoint");
+       
+       if(!value_node || activepoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a activepoint. In this case, we need to calculate the value
+// of the activepoint
+void
+Action::ActivepointSetSmart::calc_activepoint()
+{      
+/*
+       const Time time(activepoint.get_time());
+       activepoint.set_state(value_node->list[index].status_at_time(time));
+       activepoint.set_priority(0);
+*/
+
+       activepoint=value_node->list[index].new_activepoint_at_time(activepoint.get_time());
+
+       // In this case, nothing is really changing, so there will be
+       // no need to redraw the window
+       set_dirty(false);
+}
+
+void
+Action::ActivepointSetSmart::enclose_activepoint(const sinfg::Activepoint& activepoint)
+{
+       times.insert(activepoint.get_time());                   
+
+       if(get_edit_mode()&MODE_ANIMATE_PAST) try
+       {
+               // Try to find prev keyframe
+               Keyframe keyframe(*get_canvas()->keyframe_list().find_prev(activepoint.get_time()));
+
+               if(times.count(keyframe.get_time()))
+                       throw int();
+               else
+                       times.insert(keyframe.get_time());                      
+               
+               try { value_node->list[index].find(keyframe.get_time()); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       Action::Handle action(ActivepointAdd::create());
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_desc",value_desc);
+               
+                       if(!value_node->list[index].timing_info.empty())
+                       {       
+                               action->set_param("time",keyframe.get_time());
+                       }
+                       else
+                       {
+                               sinfg::Activepoint tmp;
+                               
+                               tmp.set_state(true);
+                               tmp.set_time(keyframe.get_time());
+                               action->set_param("activepoint",tmp);
+                       }
+
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+               
+                       add_action_front(action);
+               }                                               
+       }
+       catch(int) { }
+       catch(sinfg::Exception::NotFound) { }
+
+       if(get_edit_mode()&MODE_ANIMATE_FUTURE)try
+       {
+               // Try to find next keyframe
+               Keyframe keyframe(*get_canvas()->keyframe_list().find_next(activepoint.get_time()));
+
+               if(times.count(keyframe.get_time()))
+                       throw int();
+               else
+                       times.insert(keyframe.get_time());                      
+               
+               try { value_node->list[index].find(keyframe.get_time()); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       Action::Handle action(ActivepointAdd::create());
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_desc",value_desc);
+               
+                       if(!value_node->list[index].timing_info.empty())
+                       {       
+                               action->set_param("time",keyframe.get_time());
+                       }
+                       else
+                       {
+                               sinfg::Activepoint tmp;
+                               
+                               tmp.set_state(true);
+                               tmp.set_time(keyframe.get_time());
+                               action->set_param("activepoint",tmp);
+                       }
+
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+               
+                       add_action_front(action);
+               }                                               
+       }
+       catch(int) { }
+       catch(sinfg::Exception::NotFound) { }
+}
+
+void
+Action::ActivepointSetSmart::prepare()
+{
+       clear();
+       times.clear();
+       
+       // First, we need to to add any activepoints necessary to
+       // maintain the integrity of the keyframes.
+       enclose_activepoint(activepoint);
+       
+       try
+       {
+               if(value_node->list[index].find(activepoint)==value_node->list[index].timing_info.end())
+                       throw int();
+               
+               // Then, lets try to replace the old activepoint, if it exists
+               enclose_activepoint(*value_node->list[index].find(activepoint));
+
+               Action::Handle action(ActivepointSet::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",value_desc);
+               action->set_param("activepoint",activepoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               
+               return;
+       }
+       catch(int){}
+       catch(Exception::NotFound){}
+
+       try
+       {
+               // Check to see if a activepoint exists at this point in time
+               activepoint.mimic(*value_node->list[index].find(activepoint.get_time()));
+
+               enclose_activepoint(*value_node->list[index].find(activepoint.get_time()));
+               
+               Action::Handle action(ActivepointSet::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",value_desc);
+               action->set_param("activepoint",activepoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               
+               return;
+       }
+       catch(int){}
+       catch(Exception::NotFound){}
+       
+       try
+       {
+               // At this point we know that the old activepoint doesn't exist,
+               // so we need to create it.
+               Action::Handle action(ActivepointAdd::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",value_desc);
+               action->set_param("activepoint",activepoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               
+               return;
+       }
+       catch(int){}
+       catch(Exception::NotFound){}
+       
+       throw Error(_("Unable to determine how to procede. This is a bug."));
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointsetsmart.h
new file mode 100644 (file)
index 0000000..6dcb966
--- /dev/null
@@ -0,0 +1,82 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsetsmart.h
+**     \brief Template File
+**
+**     $Id: activepointsetsmart.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_ACTIVEPOINTSETSMART_H
+#define __SINFG_APP_ACTION_ACTIVEPOINTSETSMART_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+#include <list>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ActivepointSetSmart :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+       sinfg::Activepoint activepoint;
+       bool time_set;
+
+       void calc_activepoint();
+       void enclose_activepoint(const sinfg::Activepoint& activepoint);
+
+       std::set<sinfg::Time> times;
+
+public:
+
+       ActivepointSetSmart();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.cpp
new file mode 100644 (file)
index 0000000..c1afdc6
--- /dev/null
@@ -0,0 +1,182 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsimpleadd.cpp
+**     \brief Simple add activepoint File
+**
+**     $Id: activepointsimpleadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "activepointsimpleadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ActivepointSimpleAdd);
+ACTION_SET_NAME(Action::ActivepointSimpleAdd,"waypoint_simpleadd");
+ACTION_SET_LOCAL_NAME(Action::ActivepointSimpleAdd,"Simply Add Waypoint");
+ACTION_SET_TASK(Action::ActivepointSimpleAdd,"add");
+ACTION_SET_CATEGORY(Action::ActivepointSimpleAdd,Action::CATEGORY_WAYPOINT);
+ACTION_SET_PRIORITY(Action::ActivepointSimpleAdd,0);
+ACTION_SET_VERSION(Action::ActivepointSimpleAdd,"0.0");
+ACTION_SET_CVS_ID(Action::ActivepointSimpleAdd,"$Id: activepointsimpleadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ActivepointSimpleAdd::ActivepointSimpleAdd()
+{
+       set_dirty(true);
+       activepoint.set_time(Time::begin()-1);
+}
+
+Action::ParamVocab
+Action::ActivepointSimpleAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("Destination ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("activepoint",Param::TYPE_ACTIVEPOINT)
+               .set_local_name(_("Activepoint"))
+               .set_desc(_("Activepoint to be added"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ActivepointSimpleAdd::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ActivepointSimpleAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               return true;
+       }
+       if(name=="activepoint" && param.get_type()==Param::TYPE_ACTIVEPOINT)
+       {
+               activepoint = param.get_activepoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ActivepointSimpleAdd::is_ready()const
+{
+       if(!value_node && activepoint.get_time() != (Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ActivepointSimpleAdd::perform()
+{      
+       //remove any pretenders that lie at our destination
+       ValueNode_DynamicList::ListEntry::findresult iter = value_node->list[index]
+                                                                                                                       .find_time(activepoint.get_time());
+       
+       time_overwrite = false;
+       if(iter.second)
+       {
+               overwritten_ap = *iter.first;
+               time_overwrite = true;
+               value_node->list[index].erase(overwritten_ap);
+       }
+       
+       //add the value node in since it's safe
+       value_node->list[index].add(activepoint);
+       
+       //sort them...
+       value_node->list[index].timing_info.sort();
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
+
+void
+Action::ActivepointSimpleAdd::undo()
+{
+       //remove our old version...
+       ValueNode_DynamicList::ListEntry::findresult iter = value_node->list[index].find_uid(activepoint);
+       
+       if(!iter.second)
+       {
+               throw Error(_("The activepoint to remove no longer exists"));
+       }
+       
+       //remove the offending value
+       value_node->list[index].erase(*iter.first); //could also just use waypoint
+       
+       if(time_overwrite)
+       {
+               value_node->list[index].add(overwritten_ap);                            
+       }
+       
+       //sort them...
+       value_node->list[index].timing_info.sort();
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.h b/synfig-studio/trunk/src/sinfgapp/actions/activepointsimpleadd.h
new file mode 100644 (file)
index 0000000..8e0e5eb
--- /dev/null
@@ -0,0 +1,80 @@
+/* === S I N F G =========================================================== */
+/*!    \file activepointsimpleadd.h
+**     \brief A simple add a activepoint function Header
+**
+**     $Id: activepointsimpleadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_ACTIVEPOINTSIMPLEADD_H
+#define __SINFG_ACTIVEPOINTSIMPLEADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ActivepointSimpleAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+       
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int     index;
+       
+       sinfg::Activepoint activepoint;
+
+       bool time_overwrite;
+       sinfg::Activepoint overwritten_ap;
+
+public:
+
+       ActivepointSimpleAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.cpp b/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.cpp
new file mode 100644 (file)
index 0000000..492dc38
--- /dev/null
@@ -0,0 +1,179 @@
+/* === S I N F G =========================================================== */
+/*!    \file blinepointtangentmerge.cpp
+**     \brief Template File
+**
+**     $Id: blinepointtangentmerge.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "blinepointtangentmerge.h"
+#include "valuedescset.h"
+
+#include "activepointset.h"
+#include "activepointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::BLinePointTangentMerge);
+ACTION_SET_NAME(Action::BLinePointTangentMerge,"bline_point_tangent_merge");
+ACTION_SET_LOCAL_NAME(Action::BLinePointTangentMerge,_("Merge Tangents"));
+ACTION_SET_TASK(Action::BLinePointTangentMerge,"merge");
+ACTION_SET_CATEGORY(Action::BLinePointTangentMerge,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::BLinePointTangentMerge,0);
+ACTION_SET_VERSION(Action::BLinePointTangentMerge,"0.0");
+ACTION_SET_CVS_ID(Action::BLinePointTangentMerge,"$Id: blinepointtangentmerge.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::BLinePointTangentMerge::BLinePointTangentMerge()
+{
+       time=(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::BLinePointTangentMerge::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode of BLinePoint"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::BLinePointTangentMerge::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueNode_Composite::Handle value_node;
+               value_node=ValueNode_Composite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
+               if(!value_node || value_node->get_type()!=ValueBase::TYPE_BLINEPOINT)
+                       return false;
+               sinfg::Time time(x.find("time")->second.get_time());
+               if((*value_node->get_link("split"))(time).get(bool())==false)
+                       return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::BLinePointTangentMerge::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=value_node.cast_dynamic(param.get_value_node());
+               
+               return (bool)(value_node);
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::BLinePointTangentMerge::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing or bad value_node");
+
+       if(time==(Time::begin()-1))
+               sinfg::error("Missing time");
+       
+       if(!value_node || time==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::BLinePointTangentMerge::prepare()
+{
+       clear();
+
+       Action::Handle action;
+       
+       {
+               action=Action::create("value_desc_set");
+               if(!action)
+                       throw Error(_("Couldn't find action \"value_desc_set\""));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,3));
+               action->set_param("time",time);
+               action->set_param("new_value",sinfg::ValueBase(false));
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+       }
+       {
+               action=Action::create("value_desc_set");
+               if(!action)
+                       throw Error(_("Couldn't find action \"value_desc_set\""));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,5));
+               action->set_param("time",time);
+               action->set_param("new_value",(*value_node->get_link("t1"))(time));
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+       }
+       
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.h b/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentmerge.h
new file mode 100644 (file)
index 0000000..7304be0
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file blinepointtangentmerge.h
+**     \brief Template File
+**
+**     $Id: blinepointtangentmerge.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_BLINEPOINTTANGENTMERGE_H
+#define __SINFG_APP_ACTION_BLINEPOINTTANGENTMERGE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/blinepoint.h>
+#include <sinfg/valuenode_composite.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class BLinePointTangentMerge :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_Composite::Handle value_node;
+       sinfg::Time time;
+
+public:
+
+       BLinePointTangentMerge();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.cpp b/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.cpp
new file mode 100644 (file)
index 0000000..4220744
--- /dev/null
@@ -0,0 +1,179 @@
+/* === S I N F G =========================================================== */
+/*!    \file blinepointtangentsplit.cpp
+**     \brief Template File
+**
+**     $Id: blinepointtangentsplit.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "blinepointtangentsplit.h"
+#include "valuedescset.h"
+
+#include "activepointset.h"
+#include "activepointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::BLinePointTangentSplit);
+ACTION_SET_NAME(Action::BLinePointTangentSplit,"bline_point_tangent_split");
+ACTION_SET_LOCAL_NAME(Action::BLinePointTangentSplit,_("Split Tangents"));
+ACTION_SET_TASK(Action::BLinePointTangentSplit,"split");
+ACTION_SET_CATEGORY(Action::BLinePointTangentSplit,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::BLinePointTangentSplit,0);
+ACTION_SET_VERSION(Action::BLinePointTangentSplit,"0.0");
+ACTION_SET_CVS_ID(Action::BLinePointTangentSplit,"$Id: blinepointtangentsplit.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::BLinePointTangentSplit::BLinePointTangentSplit()
+{
+       time=(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::BLinePointTangentSplit::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode of BLinePoint"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::BLinePointTangentSplit::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueNode_Composite::Handle value_node;
+               value_node=ValueNode_Composite::Handle::cast_dynamic(x.find("value_node")->second.get_value_node());
+               if(!value_node || value_node->get_type()!=ValueBase::TYPE_BLINEPOINT)
+                       return false;
+               sinfg::Time time(x.find("time")->second.get_time());
+               if((*value_node->get_link("split"))(time).get(bool())==true)
+                       return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::BLinePointTangentSplit::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=value_node.cast_dynamic(param.get_value_node());
+               
+               return (bool)(value_node);
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::BLinePointTangentSplit::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing or bad value_node");
+
+       if(time==(Time::begin()-1))
+               sinfg::error("Missing time");
+       
+       if(!value_node || time==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::BLinePointTangentSplit::prepare()
+{
+       clear();
+
+       Action::Handle action;
+       
+       {
+               action=Action::create("value_desc_set");
+               if(!action)
+                       throw Error(_("Couldn't find action \"value_desc_set\""));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,3));
+               action->set_param("time",time);
+               action->set_param("new_value",sinfg::ValueBase(true));
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+       }
+       {
+               action=Action::create("value_desc_set");
+               if(!action)
+                       throw Error(_("Couldn't find action \"value_desc_set\""));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,5));
+               action->set_param("time",time);
+               action->set_param("new_value",(*value_node->get_link("t1"))(time));
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+       }
+       
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.h b/synfig-studio/trunk/src/sinfgapp/actions/blinepointtangentsplit.h
new file mode 100644 (file)
index 0000000..790c705
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file blinepointtangentsplit.h
+**     \brief Template File
+**
+**     $Id: blinepointtangentsplit.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_BLINEPOINTTANGENTSPLIT_H
+#define __SINFG_APP_ACTION_BLINEPOINTTANGENTSPLIT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/blinepoint.h>
+#include <sinfg/valuenode_composite.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class BLinePointTangentSplit :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_Composite::Handle value_node;
+       sinfg::Time time;
+
+public:
+
+       BLinePointTangentSplit();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/canvasadd.cpp
new file mode 100644 (file)
index 0000000..4f8a7a8
--- /dev/null
@@ -0,0 +1,150 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasadd.cpp
+**     \brief Template File
+**
+**     $Id: canvasadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvasadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::CanvasAdd);
+ACTION_SET_NAME(Action::CanvasAdd,"canvas_add");
+ACTION_SET_LOCAL_NAME(Action::CanvasAdd,"Add Child Canvas");
+ACTION_SET_TASK(Action::CanvasAdd,"add");
+ACTION_SET_CATEGORY(Action::CanvasAdd,Action::CATEGORY_CANVAS);
+ACTION_SET_PRIORITY(Action::CanvasAdd,0);
+ACTION_SET_VERSION(Action::CanvasAdd,"0.0");
+ACTION_SET_CVS_ID(Action::CanvasAdd,"$Id: canvasadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::CanvasAdd::CanvasAdd()
+{
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::CanvasAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("src",Param::TYPE_CANVAS)
+               .set_local_name(_("New Canvas"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("id",Param::TYPE_STRING)
+               .set_local_name(_("ID"))
+               .set_desc(_("The name that you want this canvas to be"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::CanvasAdd::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::CanvasAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="src" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               new_canvas=param.get_canvas();
+               
+               return true;
+       }
+       if(name=="id" && param.get_type()==Param::TYPE_STRING)
+       {
+               id=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::CanvasAdd::is_ready()const
+{
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::CanvasAdd::perform()
+{
+       if(!new_canvas)
+       {
+               new_canvas=get_canvas()->new_child_canvas(id);
+       }
+       else
+       {
+               if(new_canvas->is_inline())
+               {
+                       inline_parent=new_canvas->parent();
+               }
+               get_canvas()->add_child_canvas(new_canvas,id);
+       }
+
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_canvas_added()(new_canvas);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::CanvasAdd::undo()
+{
+       get_canvas()->remove_child_canvas(new_canvas);
+
+       if(inline_parent)
+               new_canvas->set_inline(inline_parent);          
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_canvas_removed()(new_canvas);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasadd.h b/synfig-studio/trunk/src/sinfgapp/actions/canvasadd.h
new file mode 100644 (file)
index 0000000..7926877
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasadd.h
+**     \brief Template File
+**
+**     $Id: canvasadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_CANVASADD_H
+#define __SINFG_APP_ACTION_CANVASADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/renddesc.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class CanvasAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Canvas::Handle new_canvas;
+       sinfg::String id;
+
+       sinfg::Canvas::Handle inline_parent;
+
+public:
+
+       CanvasAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/canvasremove.cpp
new file mode 100644 (file)
index 0000000..81302a8
--- /dev/null
@@ -0,0 +1,133 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasremove.cpp
+**     \brief Template File
+**
+**     $Id: canvasremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvasremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::CanvasRemove);
+ACTION_SET_NAME(Action::CanvasRemove,"canvas_remove");
+ACTION_SET_LOCAL_NAME(Action::CanvasRemove,"Remove Canvas");
+ACTION_SET_TASK(Action::CanvasRemove,"remove");
+ACTION_SET_CATEGORY(Action::CanvasRemove,Action::CATEGORY_CANVAS);
+ACTION_SET_PRIORITY(Action::CanvasRemove,0);
+ACTION_SET_VERSION(Action::CanvasRemove,"0.0");
+ACTION_SET_CVS_ID(Action::CanvasRemove,"$Id: canvasremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::CanvasRemove::CanvasRemove()
+{
+}
+
+Action::ParamVocab
+Action::CanvasRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       return ret;
+}
+
+bool
+Action::CanvasRemove::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               Canvas::Handle canvas=x.find("canvas")->second.get_canvas();
+               assert(canvas);
+               // We cannot remove the root canvas.
+               if(canvas->is_root())
+                       return false;
+               
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::CanvasRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::CanvasRemove::is_ready()const
+{
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::CanvasRemove::perform()
+{
+       // We cannot remove the root canvas.
+       if(get_canvas()->is_root())
+               throw Error(_("You cannot remove the root canvas!"));
+
+       if(get_canvas()->is_inline())
+               throw Error(_("You cannot remove an inline canvas!"));
+       
+       parent_canvas=get_canvas()->parent();
+       canvas_id=get_canvas()->get_id();
+       
+       assert(parent_canvas);
+       
+       parent_canvas->remove_child_canvas(get_canvas());
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_canvas_removed()(get_canvas());
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::CanvasRemove::undo()
+{
+       parent_canvas->add_child_canvas(get_canvas(), canvas_id);
+
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_canvas_added()(get_canvas());
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasremove.h b/synfig-studio/trunk/src/sinfgapp/actions/canvasremove.h
new file mode 100644 (file)
index 0000000..dd9cca2
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasremove.h
+**     \brief Template File
+**
+**     $Id: canvasremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_CANVASREMOVE_H
+#define __SINFG_APP_ACTION_CANVASREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/renddesc.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class CanvasRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+       sinfg::Canvas::Handle parent_canvas;
+       sinfg::String   canvas_id;
+public:
+
+       CanvasRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.cpp
new file mode 100644 (file)
index 0000000..97f12ad
--- /dev/null
@@ -0,0 +1,125 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasrenddescset.cpp
+**     \brief Template File
+**
+**     $Id: canvasrenddescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "canvasrenddescset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::CanvasRendDescSet);
+ACTION_SET_NAME(Action::CanvasRendDescSet,"canvas_rend_desc_set");
+ACTION_SET_LOCAL_NAME(Action::CanvasRendDescSet,"Set Canvas RendDesc");
+ACTION_SET_TASK(Action::CanvasRendDescSet,"set");
+ACTION_SET_CATEGORY(Action::CanvasRendDescSet,Action::CATEGORY_CANVAS);
+ACTION_SET_PRIORITY(Action::CanvasRendDescSet,0);
+ACTION_SET_VERSION(Action::CanvasRendDescSet,"0.0");
+ACTION_SET_CVS_ID(Action::CanvasRendDescSet,"$Id: canvasrenddescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::CanvasRendDescSet::CanvasRendDescSet()
+{
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::CanvasRendDescSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("rend_desc",Param::TYPE_RENDDESC)
+               .set_local_name(_("RendDesc"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::CanvasRendDescSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::CanvasRendDescSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="rend_desc" && param.get_type()==Param::TYPE_RENDDESC)
+       {
+               new_rend_desc=param.get_rend_desc();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::CanvasRendDescSet::is_ready()const
+{
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::CanvasRendDescSet::perform()
+{
+       old_rend_desc=get_canvas()->rend_desc();
+
+       get_canvas()->rend_desc()=new_rend_desc;
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_rend_desc_changed()();
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::CanvasRendDescSet::undo()
+{
+       get_canvas()->rend_desc()=old_rend_desc;
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_rend_desc_changed()();
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.h b/synfig-studio/trunk/src/sinfgapp/actions/canvasrenddescset.h
new file mode 100644 (file)
index 0000000..c089bee
--- /dev/null
@@ -0,0 +1,74 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasrenddescset.h
+**     \brief Template File
+**
+**     $Id: canvasrenddescset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_CANVASRENDDESCSET_H
+#define __SINFG_APP_ACTION_CANVASRENDDESCSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/renddesc.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class CanvasRendDescSet :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::RendDesc new_rend_desc;
+       sinfg::RendDesc old_rend_desc;
+
+public:
+
+       CanvasRendDescSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/colorset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/colorset.cpp
new file mode 100644 (file)
index 0000000..f117b19
--- /dev/null
@@ -0,0 +1,145 @@
+/* === S I N F G =========================================================== */
+/*!    \file colorset.cpp
+**     \brief Template File
+**
+**     $Id: colorset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamset.h"
+#include "valuenodeconstset.h"
+#include "valuedescconnect.h"
+#include "waypointsetsmart.h"
+
+#include "colorset.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ColorSet);
+ACTION_SET_NAME(Action::ColorSet,"color_set");
+ACTION_SET_LOCAL_NAME(Action::ColorSet,"Apply Default Color");
+ACTION_SET_TASK(Action::ColorSet,"set");
+ACTION_SET_CATEGORY(Action::ColorSet,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ColorSet,0);
+ACTION_SET_VERSION(Action::ColorSet,"0.0");
+ACTION_SET_CVS_ID(Action::ColorSet,"$Id: colorset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ColorSet::ColorSet():
+       time(0)
+{
+}
+
+Action::ParamVocab
+Action::ColorSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ColorSet::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x))
+               return false;
+       return x.find("value_desc")->second.get_value_desc().get_value_type()==ValueBase::TYPE_COLOR;
+}
+
+bool
+Action::ColorSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               // Grab the value_desc
+               value_desc=param.get_value_desc();
+               
+               // Grab the current color
+               color=sinfgapp::Main::get_foreground_color();
+               
+               return value_desc.get_value_type()==ValueBase::TYPE_COLOR;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ColorSet::is_ready()const
+{
+       if(!value_desc || value_desc.get_value_type()!=ValueBase::TYPE_COLOR)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ColorSet::prepare()
+{
+       clear();
+       
+       Action::Handle action;
+       action=Action::create("value_desc_set");
+               
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("value_desc",value_desc);
+       action->set_param("new_value",ValueBase(color));
+       action->set_param("time",time);
+       
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/colorset.h b/synfig-studio/trunk/src/sinfgapp/actions/colorset.h
new file mode 100644 (file)
index 0000000..fac71e2
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file colorset.h
+**     \brief Template File
+**
+**     $Id: colorset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_COLORSET_H
+#define __SINFG_APP_ACTION_COLORSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ColorSet :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::Color color;
+       sinfg::Time time;
+
+public:
+
+       ColorSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/editmodeset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/editmodeset.cpp
new file mode 100644 (file)
index 0000000..4c52efb
--- /dev/null
@@ -0,0 +1,128 @@
+/* === S I N F G =========================================================== */
+/*!    \file editmodeset.cpp
+**     \brief Template File
+**
+**     $Id: editmodeset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "editmodeset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::EditModeSet);
+ACTION_SET_NAME(Action::EditModeSet,"edit_mode_set");
+ACTION_SET_LOCAL_NAME(Action::EditModeSet,"Set Edit Mode");
+ACTION_SET_TASK(Action::EditModeSet,"set");
+ACTION_SET_CATEGORY(Action::EditModeSet,Action::CATEGORY_OTHER);
+ACTION_SET_PRIORITY(Action::EditModeSet,0);
+ACTION_SET_VERSION(Action::EditModeSet,"0.0");
+ACTION_SET_CVS_ID(Action::EditModeSet,"$Id: editmodeset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::EditModeSet::EditModeSet()
+{
+}
+
+Action::ParamVocab
+Action::EditModeSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("edit_mode",Param::TYPE_EDITMODE)
+               .set_local_name(_("New Edit Mode"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::EditModeSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::EditModeSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+/*
+       if(name=="edit_mode" && param.get_type()==Param::TYPE_EDITMODE)
+       {
+               set_edit_mode(param.get_edit_mode());
+               
+               return true;
+       }
+*/
+       
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::EditModeSet::is_ready()const
+{
+       return Action::CanvasSpecific::is_ready() && get_canvas_interface();
+}
+
+void
+Action::EditModeSet::perform()
+{
+       set_dirty(false);
+
+       old_edit_mode=get_canvas_interface()->get_mode();
+
+       if(old_edit_mode==get_edit_mode())
+               return;
+
+       get_canvas_interface()->mode_=get_edit_mode();
+               
+       get_canvas_interface()->signal_mode_changed_(get_edit_mode());
+}
+
+void
+Action::EditModeSet::undo()
+{
+       set_dirty(false);
+
+       if(old_edit_mode==get_edit_mode())
+               return;
+
+       get_canvas_interface()->mode_=old_edit_mode;
+               
+       get_canvas_interface()->signal_mode_changed_(old_edit_mode);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/editmodeset.h b/synfig-studio/trunk/src/sinfgapp/actions/editmodeset.h
new file mode 100644 (file)
index 0000000..4ef3de8
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file editmodeset.h
+**     \brief Template File
+**
+**     $Id: editmodeset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_EDITMODESET_H
+#define __SINFG_APP_ACTION_EDITMODESET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <sinfgapp/editmode.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class EditModeSet :
+       public Undoable,
+       public CanvasSpecific
+{
+       EditMode old_edit_mode;
+public:
+
+       EditModeSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/gradientset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/gradientset.cpp
new file mode 100644 (file)
index 0000000..19f9337
--- /dev/null
@@ -0,0 +1,145 @@
+/* === S I N F G =========================================================== */
+/*!    \file gradientset.cpp
+**     \brief Template File
+**
+**     $Id: gradientset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamset.h"
+#include "valuenodeconstset.h"
+#include "valuedescconnect.h"
+#include "waypointsetsmart.h"
+
+#include "gradientset.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::GradientSet);
+ACTION_SET_NAME(Action::GradientSet,"gradient_set");
+ACTION_SET_LOCAL_NAME(Action::GradientSet,"Apply Default Gradient");
+ACTION_SET_TASK(Action::GradientSet,"set");
+ACTION_SET_CATEGORY(Action::GradientSet,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::GradientSet,0);
+ACTION_SET_VERSION(Action::GradientSet,"0.0");
+ACTION_SET_CVS_ID(Action::GradientSet,"$Id: gradientset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::GradientSet::GradientSet():
+       time(0)
+{
+}
+
+Action::ParamVocab
+Action::GradientSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::GradientSet::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x))
+               return false;
+       return x.find("value_desc")->second.get_value_desc().get_value_type()==ValueBase::TYPE_GRADIENT;
+}
+
+bool
+Action::GradientSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               // Grab the value_desc
+               value_desc=param.get_value_desc();
+               
+               // Grab the current gradient
+               gradient=sinfgapp::Main::get_gradient();
+               
+               return value_desc.get_value_type()==ValueBase::TYPE_GRADIENT;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::GradientSet::is_ready()const
+{
+       if(!value_desc || value_desc.get_value_type()!=ValueBase::TYPE_GRADIENT)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::GradientSet::prepare()
+{
+       clear();
+       
+       Action::Handle action;
+       action=Action::create("value_desc_set");
+               
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("value_desc",value_desc);
+       action->set_param("new_value",ValueBase(gradient));
+       action->set_param("time",time);
+       
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/gradientset.h b/synfig-studio/trunk/src/sinfgapp/actions/gradientset.h
new file mode 100644 (file)
index 0000000..f4f69a5
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file gradientset.h
+**     \brief Template File
+**
+**     $Id: gradientset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_GRADIENTSET_H
+#define __SINFG_APP_ACTION_GRADIENTSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+#include <sinfg/gradient.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class GradientSet :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::Gradient gradient;
+       sinfg::Time time;
+
+public:
+
+       GradientSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.cpp b/synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.cpp
new file mode 100644 (file)
index 0000000..9b21c9d
--- /dev/null
@@ -0,0 +1,144 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.cpp
+**     \brief Template File
+**
+**     $Id: groupaddlayers.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "groupaddlayers.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::GroupAddLayers);
+ACTION_SET_NAME(Action::GroupAddLayers,"group_add_layers");
+ACTION_SET_LOCAL_NAME(Action::GroupAddLayers,"Add Layers to Group");
+ACTION_SET_TASK(Action::GroupAddLayers,"add");
+ACTION_SET_CATEGORY(Action::GroupAddLayers,Action::CATEGORY_LAYER|Action::CATEGORY_GROUP);
+ACTION_SET_PRIORITY(Action::GroupAddLayers,0);
+ACTION_SET_VERSION(Action::GroupAddLayers,"0.0");
+ACTION_SET_CVS_ID(Action::GroupAddLayers,"$Id: groupaddlayers.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::GroupAddLayers::GroupAddLayers()
+{
+}
+
+Action::ParamVocab
+Action::GroupAddLayers::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be added to group"))
+               .set_supports_multiple()
+       );
+
+       ret.push_back(ParamDesc("group",Param::TYPE_STRING)
+               .set_local_name(_("Group"))
+               .set_desc(_("Name of the Group to add the Layers to"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::GroupAddLayers::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::GroupAddLayers::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               std::pair<sinfg::Layer::Handle,String> layer_pair;
+               layer_pair.first=param.get_layer();
+               layer_list.push_back(layer_pair);
+               
+               return true;
+       }
+
+       if(name=="group" && param.get_type()==Param::TYPE_STRING)
+       {
+               group=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::GroupAddLayers::is_ready()const
+{
+       if(layer_list.empty() || group.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::GroupAddLayers::perform()
+{
+       std::list<std::pair<sinfg::Layer::Handle,String> >::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               Layer::Handle layer(iter->first);
+               iter->second=layer->get_group();
+               
+               layer->add_to_group(group);
+       }
+}
+
+void
+Action::GroupAddLayers::undo()
+{
+       std::list<std::pair<sinfg::Layer::Handle,String> >::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               Layer::Handle layer(iter->first);
+               
+               layer->remove_from_group(group);
+               
+               layer->add_to_group(iter->second);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.h b/synfig-studio/trunk/src/sinfgapp/actions/groupaddlayers.h
new file mode 100644 (file)
index 0000000..1e25861
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_groupaddlayers.h
+**     \brief Template File
+**
+**     $Id: groupaddlayers.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_GROUPADDLAYERS_H
+#define __SINFG_APP_ACTION_GROUPADDLAYERS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class GroupAddLayers :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       // List contains the layers and their previous groups
+       std::list<std::pair<sinfg::Layer::Handle,sinfg::String> > layer_list;
+       
+       // The name of the new group
+       sinfg::String group;
+
+public:
+
+       GroupAddLayers();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/groupremove.cpp
new file mode 100644 (file)
index 0000000..22d2e27
--- /dev/null
@@ -0,0 +1,133 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.cpp
+**     \brief Template File
+**
+**     $Id: groupremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "groupremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::GroupRemove);
+ACTION_SET_NAME(Action::GroupRemove,"group_remove");
+ACTION_SET_LOCAL_NAME(Action::GroupRemove,"Remove Group");
+ACTION_SET_TASK(Action::GroupRemove,"remove");
+ACTION_SET_CATEGORY(Action::GroupRemove,Action::CATEGORY_GROUP);
+ACTION_SET_PRIORITY(Action::GroupRemove,0);
+ACTION_SET_VERSION(Action::GroupRemove,"0.0");
+ACTION_SET_CVS_ID(Action::GroupRemove,"$Id: groupremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::GroupRemove::GroupRemove()
+{
+}
+
+Action::ParamVocab
+Action::GroupRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("group",Param::TYPE_STRING)
+               .set_local_name(_("Group"))
+               .set_desc(_("Name of the Group to remove"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::GroupRemove::is_canidate(const ParamList &x)
+{
+       bool ret(canidate_check(get_param_vocab(),x));
+       if(!ret)
+       {
+               sinfg::info("Action::GroupRemove::is_canidate(): failed canidate check");
+               ParamList::const_iterator iter;
+               for(iter=x.begin();iter!=x.end();++iter)
+               {
+                       sinfg::info("PARAM: %s",iter->first.c_str());
+               }
+       }
+       return ret;
+}
+
+bool
+Action::GroupRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="group" && param.get_type()==Param::TYPE_STRING)
+       {
+               group=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::GroupRemove::is_ready()const
+{
+       if(group.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::GroupRemove::perform()
+{
+       layer_list=get_canvas()->get_layers_in_group(group);
+       
+       std::set<sinfg::Layer::Handle>::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               (*iter)->remove_from_group(group);
+       }
+}
+
+void
+Action::GroupRemove::undo()
+{
+       std::set<sinfg::Layer::Handle>::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               (*iter)->add_to_group(group);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupremove.h b/synfig-studio/trunk/src/sinfgapp/actions/groupremove.h
new file mode 100644 (file)
index 0000000..8c1ee1b
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_groupaddlayers.h
+**     \brief Template File
+**
+**     $Id: groupremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_GROUPREMOVE_H
+#define __SINFG_APP_ACTION_GROUPREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class GroupRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       // List contains the layers
+       std::set<sinfg::Layer::Handle> layer_list;
+       
+       // The name of the group to remove
+       sinfg::String group;
+
+public:
+
+       GroupRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.cpp b/synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.cpp
new file mode 100644 (file)
index 0000000..4c76fd0
--- /dev/null
@@ -0,0 +1,142 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.cpp
+**     \brief Template File
+**
+**     $Id: groupremovelayers.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "groupremovelayers.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::GroupRemoveLayers);
+ACTION_SET_NAME(Action::GroupRemoveLayers,"group_remove_layers");
+ACTION_SET_LOCAL_NAME(Action::GroupRemoveLayers,"Remove Layers from a Group");
+ACTION_SET_TASK(Action::GroupRemoveLayers,"remove");
+ACTION_SET_CATEGORY(Action::GroupRemoveLayers,Action::CATEGORY_LAYER|Action::CATEGORY_GROUP);
+ACTION_SET_PRIORITY(Action::GroupRemoveLayers,0);
+ACTION_SET_VERSION(Action::GroupRemoveLayers,"0.0");
+ACTION_SET_CVS_ID(Action::GroupRemoveLayers,"$Id: groupremovelayers.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::GroupRemoveLayers::GroupRemoveLayers()
+{
+}
+
+Action::ParamVocab
+Action::GroupRemoveLayers::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be added to group"))
+               .set_supports_multiple()
+       );
+
+       ret.push_back(ParamDesc("group",Param::TYPE_STRING)
+               .set_local_name(_("Group"))
+               .set_desc(_("Name of the Group to add the Layers to"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::GroupRemoveLayers::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::GroupRemoveLayers::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               std::pair<sinfg::Layer::Handle,String> layer_pair;
+               layer_pair.first=param.get_layer();
+               layer_list.push_back(layer_pair);
+               
+               return true;
+       }
+
+       if(name=="group" && param.get_type()==Param::TYPE_STRING)
+       {
+               group=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::GroupRemoveLayers::is_ready()const
+{
+       if(layer_list.empty() || group.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::GroupRemoveLayers::perform()
+{
+       std::list<std::pair<sinfg::Layer::Handle,String> >::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               Layer::Handle layer(iter->first);
+               iter->second=layer->get_group();
+               
+               layer->remove_from_group(group);
+       }
+}
+
+void
+Action::GroupRemoveLayers::undo()
+{
+       std::list<std::pair<sinfg::Layer::Handle,String> >::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               Layer::Handle layer(iter->first);
+               
+               layer->add_to_group(iter->second);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.h b/synfig-studio/trunk/src/sinfgapp/actions/groupremovelayers.h
new file mode 100644 (file)
index 0000000..26875b2
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_groupremovelayers.h
+**     \brief Template File
+**
+**     $Id: groupremovelayers.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_GROUPREMOVELAYERS_H
+#define __SINFG_APP_ACTION_GROUPREMOVELAYERS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class GroupRemoveLayers :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       // List contains the layers and their previous groups
+       std::list<std::pair<sinfg::Layer::Handle,sinfg::String> > layer_list;
+       
+       // The name of the new group
+       sinfg::String group;
+
+public:
+
+       GroupRemoveLayers();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/grouprename.cpp b/synfig-studio/trunk/src/sinfgapp/actions/grouprename.cpp
new file mode 100644 (file)
index 0000000..d55c26e
--- /dev/null
@@ -0,0 +1,129 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.cpp
+**     \brief Template File
+**
+**     $Id: grouprename.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "grouprename.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::GroupRename);
+ACTION_SET_NAME(Action::GroupRename,"group_rename");
+ACTION_SET_LOCAL_NAME(Action::GroupRename,"Rename Group");
+ACTION_SET_TASK(Action::GroupRename,"rename");
+ACTION_SET_CATEGORY(Action::GroupRename,Action::CATEGORY_GROUP);
+ACTION_SET_PRIORITY(Action::GroupRename,0);
+ACTION_SET_VERSION(Action::GroupRename,"0.0");
+ACTION_SET_CVS_ID(Action::GroupRename,"$Id: grouprename.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::GroupRename::GroupRename()
+{
+}
+
+Action::ParamVocab
+Action::GroupRename::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("group",Param::TYPE_STRING)
+               .set_local_name(_("Old Group"))
+               .set_desc(_("Name of the Group to rename"))
+       );
+
+       ret.push_back(ParamDesc("new_group",Param::TYPE_STRING)
+               .set_local_name(_("New Group"))
+               .set_desc(_("New name for group"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::GroupRename::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::GroupRename::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="group" && param.get_type()==Param::TYPE_STRING)
+       {
+               old_group_name=param.get_string();
+               
+               return true;
+       }
+
+       if(name=="new_group" && param.get_type()==Param::TYPE_STRING)
+       {
+               new_group_name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::GroupRename::is_ready()const
+{
+       if(old_group_name.empty()||new_group_name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::GroupRename::perform()
+{
+       if(get_canvas()->get_groups().count(new_group_name)!=0)
+       {
+               throw Error(_("A group with the name \"%s\" already exists!"),new_group_name.c_str());
+       }
+       get_canvas()->rename_group(old_group_name,new_group_name);
+}
+
+void
+Action::GroupRename::undo()
+{
+       get_canvas()->rename_group(new_group_name,old_group_name);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/grouprename.h b/synfig-studio/trunk/src/sinfgapp/actions/grouprename.h
new file mode 100644 (file)
index 0000000..d16d68d
--- /dev/null
@@ -0,0 +1,80 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_grouprename.h
+**     \brief Template File
+**
+**     $Id: grouprename.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_GROUPRENAME_H
+#define __SINFG_APP_ACTION_GROUPRENAME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class GroupRename :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       // List contains the layers
+       std::set<sinfg::Layer::Handle> layer_list;
+       
+       // The name of the group to remove
+       sinfg::String old_group_name;
+
+       sinfg::String new_group_name;
+
+public:
+
+       GroupRename();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.cpp
new file mode 100644 (file)
index 0000000..5757109
--- /dev/null
@@ -0,0 +1,136 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeadd.cpp
+**     \brief Template File
+**
+**     $Id: keyframeadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframeadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeAdd);
+ACTION_SET_NAME(Action::KeyframeAdd,"keyframe_add");
+ACTION_SET_LOCAL_NAME(Action::KeyframeAdd,"Add Keyframe");
+ACTION_SET_TASK(Action::KeyframeAdd,"add");
+ACTION_SET_CATEGORY(Action::KeyframeAdd,Action::CATEGORY_KEYFRAME);
+ACTION_SET_PRIORITY(Action::KeyframeAdd,0);
+ACTION_SET_VERSION(Action::KeyframeAdd,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeAdd,"$Id: keyframeadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeAdd::KeyframeAdd()
+{
+       keyframe.set_time(Time::begin()-1);
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::KeyframeAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("New Keyframe"))
+               .set_desc(_("Keyframe to be added"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeAdd::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x))
+               return false;
+       
+       return true;
+}
+
+bool
+Action::KeyframeAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               keyframe=param.get_keyframe();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeAdd::is_ready()const
+{
+       if(keyframe.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeAdd::perform()
+{      
+       try { get_canvas()->keyframe_list().find(keyframe.get_time()); throw Error(_("A Keyframe already exists at this point in time"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { get_canvas()->keyframe_list().find(keyframe); throw Error(_("This keyframe is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+       
+       get_canvas()->keyframe_list().add(keyframe);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_added()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::KeyframeAdd::undo()
+{
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_removed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+
+       get_canvas()->keyframe_list().erase(keyframe);  
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframeadd.h
new file mode 100644 (file)
index 0000000..635e251
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeadd.h
+**     \brief Template File
+**
+**     $Id: keyframeadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMEADD_H
+#define __SINFG_APP_ACTION_KEYFRAMEADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Keyframe keyframe;
+
+public:
+
+       KeyframeAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.cpp
new file mode 100644 (file)
index 0000000..2cc348b
--- /dev/null
@@ -0,0 +1,243 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeduplicate.cpp
+**     \brief Template File
+**
+**     $Id: keyframeduplicate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframeduplicate.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+#include "activepointsetsmart.h"
+#include "waypointsetsmart.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeDuplicate);
+ACTION_SET_NAME(Action::KeyframeDuplicate,"keyframe_duplicate");
+ACTION_SET_LOCAL_NAME(Action::KeyframeDuplicate,"Duplicate Keyframe");
+ACTION_SET_TASK(Action::KeyframeDuplicate,"duplicate");
+ACTION_SET_CATEGORY(Action::KeyframeDuplicate,Action::CATEGORY_KEYFRAME);
+ACTION_SET_PRIORITY(Action::KeyframeDuplicate,0);
+ACTION_SET_VERSION(Action::KeyframeDuplicate,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeDuplicate,"$Id: keyframeduplicate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeDuplicate::KeyframeDuplicate()
+{
+       new_keyframe.set_time(Time::begin()-1);
+       keyframe.set_time(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::KeyframeDuplicate::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("Keyframe"))
+               .set_desc(_("Keyframe to be duplicated"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeDuplicate::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::KeyframeDuplicate::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               keyframe=param.get_keyframe();
+               new_keyframe.set_description(keyframe.get_description()+_(" (Duplicate)"));
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               new_keyframe.set_time(param.get_time());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeDuplicate::is_ready()const
+{
+       if(keyframe.get_time()==(Time::begin()-1) || new_keyframe.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeDuplicate::prepare()
+{
+       clear();
+
+       const sinfg::Time old_time=keyframe.get_time();
+       const sinfg::Time new_time=new_keyframe.get_time();
+
+       try { get_canvas()->keyframe_list().find(keyframe);}
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find the given keyframe"));
+       }       
+
+       try { if(get_canvas()->keyframe_list().find(new_time)!=get_canvas()->keyframe_list().end()) throw Error(_("A Keyframe already exists at this point in time"));}
+       catch(...) { }                  
+
+       // If the times are different, then we 
+       // will need to romp through the valuenodes
+       // and add actions to update their values.
+       if(new_time!=old_time)
+       {
+               std::vector<sinfgapp::ValueDesc> value_desc_list;
+               get_canvas_interface()->find_important_value_descs(value_desc_list);
+               while(!value_desc_list.empty())
+               {
+                       process_value_desc(value_desc_list.back());
+                       value_desc_list.pop_back();
+               }
+       }
+}
+
+void
+Action::KeyframeDuplicate::process_value_desc(const sinfgapp::ValueDesc& value_desc)
+{      
+       const sinfg::Time old_time=keyframe.get_time();
+       const sinfg::Time new_time=new_keyframe.get_time();
+
+       if(value_desc.is_value_node())
+       {
+               ValueNode::Handle value_node(value_desc.get_value_node());
+       
+               // If we are a dynamic list, then we need to update the ActivePoints
+               if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+               {
+                       ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
+                       int i;
+                       
+                       for(i=0;i<value_node->link_count();i++)
+                       {
+                               sinfgapp::ValueDesc value_desc(value_node,i);
+                               Activepoint activepoint(value_node->list[i].new_activepoint_at_time(old_time));
+                               activepoint.set_time(new_time);
+
+                               Action::Handle action(ActivepointSetSmart::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_desc",value_desc);
+                               action->set_param("activepoint",activepoint);
+
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action_front(action);                                               
+                       }
+               }
+               else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
+               {
+                       ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_node));
+                       Waypoint waypoint(value_node->new_waypoint_at_time(old_time));
+                       waypoint.set_time(new_time);
+                       
+                       Action::Handle action(WaypointSetSmart::create());
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_node",ValueNode::Handle(value_node));
+                       action->set_param("waypoint",waypoint);
+       
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+               
+                       add_action_front(action);                                               
+               }
+       }
+}
+
+void
+Action::KeyframeDuplicate::perform()
+{
+       try { get_canvas()->keyframe_list().find(new_keyframe.get_time()); throw Error(_("A Keyframe already exists at this point in time"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { get_canvas()->keyframe_list().find(new_keyframe); throw Error(_("This keyframe is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       Action::Super::perform();
+       
+       get_canvas()->keyframe_list().add(new_keyframe);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_added()(new_keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::KeyframeDuplicate::undo()
+{
+       Action::Super::undo();
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_removed()(new_keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+
+       get_canvas()->keyframe_list().erase(new_keyframe);      
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframeduplicate.h
new file mode 100644 (file)
index 0000000..23affe8
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeduplicate.h
+**     \brief Template File
+**
+**     $Id: keyframeduplicate.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMEDUPLICATE_H
+#define __SINFG_APP_ACTION_KEYFRAMEDUPLICATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeDuplicate :
+       public Super
+{
+private:
+
+       sinfg::Keyframe keyframe;
+       sinfg::Keyframe new_keyframe;
+
+       void process_value_desc(const sinfgapp::ValueDesc& value_desc);
+
+public:
+
+       KeyframeDuplicate();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.cpp
new file mode 100644 (file)
index 0000000..e9796af
--- /dev/null
@@ -0,0 +1,231 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeremove.cpp
+**     \brief Template File
+**
+**     $Id: keyframeremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframeremove.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+#include "activepointremove.h"
+#include "waypointremove.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeRemove);
+ACTION_SET_NAME(Action::KeyframeRemove,"keyframe_remove");
+ACTION_SET_LOCAL_NAME(Action::KeyframeRemove,"Remove Keyframe");
+ACTION_SET_TASK(Action::KeyframeRemove,"remove");
+ACTION_SET_CATEGORY(Action::KeyframeRemove,Action::CATEGORY_KEYFRAME);
+ACTION_SET_PRIORITY(Action::KeyframeRemove,0);
+ACTION_SET_VERSION(Action::KeyframeRemove,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeRemove,"$Id: keyframeremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeRemove::KeyframeRemove()
+{
+       keyframe.set_time(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::KeyframeRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("Keyframe"))
+               .set_desc(_("Keyframe to be removed"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeRemove::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::KeyframeRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               keyframe=param.get_keyframe();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeRemove::is_ready()const
+{
+       if(keyframe.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeRemove::prepare()
+{
+       clear();
+
+       try { get_canvas()->keyframe_list().find(keyframe);}
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find the given keyframe"));
+       }       
+
+       
+       {
+               std::vector<sinfgapp::ValueDesc> value_desc_list;
+               get_canvas_interface()->find_important_value_descs(value_desc_list);
+               while(!value_desc_list.empty())
+               {
+                       process_value_desc(value_desc_list.back());
+                       value_desc_list.pop_back();
+               }
+       }
+}
+
+void
+Action::KeyframeRemove::process_value_desc(const sinfgapp::ValueDesc& value_desc)
+{      
+       const sinfg::Time time(keyframe.get_time());
+
+       if(value_desc.is_value_node())
+       {
+               ValueNode::Handle value_node(value_desc.get_value_node());
+       
+               // If we are a dynamic list, then we need to update the ActivePoints
+               if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+               {
+                       ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
+                       int i;
+                       for(i=0;i<value_node->link_count();i++)
+                       try
+                       {
+                               Activepoint activepoint;
+                               activepoint=*value_node->list[i].find(time);
+
+                               sinfgapp::ValueDesc value_desc(value_node,i);
+
+                               Action::Handle action(ActivepointRemove::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_desc",value_desc);
+                               action->set_param("activepoint",activepoint);
+
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action_front(action);                                               
+                       }
+                       catch(...)
+                       {
+                       }
+               }
+               else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
+               try
+               {
+                       ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_node));
+                       Waypoint waypoint;
+                       waypoint=*value_node->find(time);
+                       assert(waypoint.get_time()==time);
+                       
+                       Action::Handle action(WaypointRemove::create());
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_node",ValueNode::Handle(value_node));
+                       action->set_param("waypoint",waypoint);
+       
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+               
+                       add_action_front(action);                                               
+               }
+               catch(...)
+               {
+               }
+       }
+}
+
+
+void
+Action::KeyframeRemove::perform()
+{
+       Action::Super::perform();
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_removed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+
+       get_canvas()->keyframe_list().erase(keyframe);  
+}
+
+void
+Action::KeyframeRemove::undo()
+{
+       try { get_canvas()->keyframe_list().find(keyframe.get_time()); throw Error(_("A Keyframe already exists at this point in time"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { get_canvas()->keyframe_list().find(keyframe); throw Error(_("This keyframe is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+
+       Action::Super::undo();
+       
+       get_canvas()->keyframe_list().add(keyframe);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_added()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframeremove.h
new file mode 100644 (file)
index 0000000..f6b4903
--- /dev/null
@@ -0,0 +1,75 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeremove.h
+**     \brief Template File
+**
+**     $Id: keyframeremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMEREMOVE_H
+#define __SINFG_APP_ACTION_KEYFRAMEREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeRemove :
+       public Super
+{
+private:
+
+       sinfg::Keyframe keyframe;
+
+       void process_value_desc(const sinfgapp::ValueDesc& value_desc);
+
+public:
+
+       KeyframeRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframeset.cpp
new file mode 100644 (file)
index 0000000..31764f5
--- /dev/null
@@ -0,0 +1,429 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeset.cpp
+**     \brief Template File
+**
+**     $Id: keyframeset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframeset.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+#include "activepointsetsmart.h"
+#include "waypointsetsmart.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeSet);
+ACTION_SET_NAME(Action::KeyframeSet,"keyframe_set");
+ACTION_SET_LOCAL_NAME(Action::KeyframeSet,"Set Keyframe");
+ACTION_SET_TASK(Action::KeyframeSet,"set");
+ACTION_SET_CATEGORY(Action::KeyframeSet,Action::CATEGORY_KEYFRAME|Action::CATEGORY_HIDDEN);
+ACTION_SET_PRIORITY(Action::KeyframeSet,0);
+ACTION_SET_VERSION(Action::KeyframeSet,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeSet,"$Id: keyframeset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeSet::KeyframeSet()
+{
+       keyframe.set_time(Time::begin()-1);
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::KeyframeSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("New Keyframe"))
+               .set_desc(_("Keyframe to be added"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::KeyframeSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               sinfg::info("KeyframeSet::set_param():old_time: %s",keyframe.get_time().get_string().c_str());
+               keyframe=param.get_keyframe();
+               sinfg::info("KeyframeSet::set_param():new_time: %s",keyframe.get_time().get_string().c_str());
+               sinfg::info("KeyframeSet::set_param():get_keyframe(): %s",param.get_keyframe().get_time().get_string().c_str());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeSet::is_ready()const
+{
+       if(keyframe.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeSet::prepare()
+{
+       clear();
+       guid_set.clear();
+       
+       
+
+       
+       
+       //sinfg::info("new_time: %s",new_time.get_string().c_str());
+       //sinfg::info("old_time: %s",old_time.get_string().c_str());
+       
+       try { if(get_canvas()->keyframe_list().find(new_time)!=get_canvas()->keyframe_list().end()) throw Error(_("A Keyframe already exists at this point in time"));}
+       catch(...) { }  
+
+
+       // If the times are different, then we 
+       // will need to romp through the valuenodes
+       // and add actions to update their values.
+       if(new_time!=old_time)
+       {
+               std::vector<sinfgapp::ValueDesc> value_desc_list;
+               get_canvas_interface()->find_important_value_descs(value_desc_list);
+               while(!value_desc_list.empty())
+               {
+                       process_value_desc(value_desc_list.back());
+                       value_desc_list.pop_back();
+               }
+       }
+}
+
+#define old_2_new(x)   (((x)-old_begin)/(old_end-old_begin)*(new_end-new_begin)+new_begin)
+
+int
+Action::KeyframeSet::scale_activepoints(const sinfgapp::ValueDesc& value_desc,const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end)
+{
+       ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_static(value_desc.get_parent_value_node()));
+       ValueNode_DynamicList::ListEntry& list_entry(value_node->list[value_desc.get_index()]);
+       
+       std::vector<Activepoint*> selected;
+       std::vector<Activepoint*>::iterator iter;
+       
+       if(list_entry.find(old_begin,old_end,selected))
+       {
+               // check to make sure this operation is OK
+               for(iter=selected.begin();iter!=selected.end();++iter)
+               {
+                       try
+                       {
+                               Time new_time(old_2_new((*iter)->get_time()));
+                               if(new_time>=old_begin && new_time<old_end)
+                                       continue;
+                               list_entry.find(new_time);
+                               // If we found a activepoint already at that time, then
+                               // we need to abort
+                               //throw Exception::BadTime(_("Activepoint Conflict"));
+                       }
+                       catch(Exception::NotFound) { }
+               }
+               
+               int ret(0);
+               while(!selected.empty())
+               {
+                       if(selected.back()->get_time()!=old_2_new(selected.back()->get_time()))
+                       {
+                               Action::Handle action(Action::create("activepoint_set"));
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_desc",value_desc);
+                               
+                               Activepoint activepoint(*selected.back());
+                               activepoint.set_time(old_2_new(selected.back()->get_time()));
+
+                               action->set_param("activepoint",activepoint);
+
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action_front(action);                                               
+
+                               ret++;
+                       }
+                       selected.pop_back();
+               }
+               return ret;
+       }
+       return 0;
+}
+
+int
+Action::KeyframeSet::scale_waypoints(const sinfgapp::ValueDesc& value_desc,const Time& old_begin,const Time& old_end,const Time& new_begin,const Time& new_end)
+{
+       ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_static(value_desc.get_value_node()));
+       
+       std::vector<Waypoint*> selected;
+       std::vector<Waypoint*>::iterator iter;
+       
+       if(value_node->find(old_begin,old_end,selected))
+       {
+               // check to make sure this operation is OK
+               for(iter=selected.begin();iter!=selected.end();++iter)
+               {
+                       try
+                       {
+                               Time new_time(old_2_new((*iter)->get_time()));
+                               if(new_time>=old_begin && new_time<old_end)
+                                       continue;
+                               value_node->find(new_time);
+                               // If we found a waypoint point already at that time, then
+                               // we need to abort
+                               //sinfg::info(_("old_begin: %s, old_end: %s"),old_begin.get_string().c_str(),old_end.get_string().c_str());
+                               //sinfg::info(_("new_begin: %s, new_end: %s"),new_begin.get_string().c_str(),new_end.get_string().c_str());
+                               //throw Exception::BadTime(strprintf(_("Waypoint Conflict, old: %s, new: %s"),(*iter)->get_time().get_string().c_str(),new_time.get_string().c_str()));
+                       }
+                       catch(Exception::NotFound) { }
+               }
+               
+               int ret(0);
+               while(!selected.empty())
+               {
+                       if(selected.back()->get_time()!=old_2_new(selected.back()->get_time()))
+                       {
+                               Action::Handle action(Action::create("waypoint_set"));
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle::cast_static(value_node));
+                               
+                               Waypoint waypoint(*selected.back());
+                               waypoint.set_time(old_2_new(selected.back()->get_time()));
+
+                               action->set_param("waypoint",waypoint);
+
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action_front(action);                                               
+
+                               ret++;
+                       }
+                       selected.pop_back();
+               }
+               return ret;
+       }
+       return 0;
+}
+
+void
+Action::KeyframeSet::process_value_desc(const sinfgapp::ValueDesc& value_desc)
+{      
+       if(value_desc.is_value_node())
+       {               
+               ValueNode::Handle value_node(value_desc.get_value_node());
+
+               //if(guid_set.count(value_node->get_guid()))
+               //      return;
+               //guid_set.insert(value_node->get_guid());
+
+               // If we are a dynamic list, then we need to update the ActivePoints
+               if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+               {
+                       ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
+                       int i;
+                       for(i=0;i<value_node->link_count();i++)
+                       {
+                               sinfgapp::ValueDesc value_desc(value_node,i);
+                               if(new_time>keyframe_prev && new_time<keyframe_next)
+                               {
+                                       // In this circumstance, we need to adjust any
+                                       // activepoints between the previous and next
+                                       // keyframes
+                                       scale_activepoints(value_desc,keyframe_prev,old_time,keyframe_prev,new_time);
+                                       scale_activepoints(value_desc,old_time,keyframe_next,new_time,keyframe_next);
+                               }
+                               //else
+                               {       
+                                       Action::Handle action(ActivepointSetSmart::create());
+                                       
+                                       action->set_param("canvas",get_canvas());
+                                       action->set_param("canvas_interface",get_canvas_interface());
+                                       action->set_param("value_desc",value_desc);
+                                       
+                                       Activepoint activepoint;
+                                       try
+                                       {
+                                               activepoint=*value_node->list[i].find(old_time);
+                                               activepoint.set_time(new_time);
+                                       }
+                                       catch(...)
+                                       {
+                                               activepoint.set_time(new_time);
+                                               activepoint.set_state(value_node->list[i].status_at_time(old_time));
+                                               activepoint.set_priority(0);
+                                       }
+                                       action->set_param("activepoint",activepoint);
+       
+                                       assert(action->is_ready());
+                                       if(!action->is_ready())
+                                               throw Error(Error::TYPE_NOTREADY);
+                               
+                                       add_action_front(action);
+                               }
+                       }
+               }
+               else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
+               {
+                       if(new_time>keyframe_prev && new_time<keyframe_next)
+                       {
+                                       // In this circumstance, we need to adjust any
+                                       // waypoints between the previous and next
+                                       // keyframes
+                                       scale_waypoints(value_desc,keyframe_prev,old_time,keyframe_prev,new_time);
+                                       scale_waypoints(value_desc,old_time,keyframe_next,new_time,keyframe_next);
+                       }
+                       //else
+                       {
+                               ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_node));
+                               
+                               Action::Handle action(WaypointSetSmart::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle(value_node));
+                               
+                               Waypoint waypoint;
+                               try
+                               {
+                                       waypoint=*value_node->find(old_time);
+                                       waypoint.set_time(new_time);
+                               }
+                               catch(...)
+                               {
+                                       waypoint.set_time(new_time);
+                                       waypoint.set_value((*value_node)(old_time));
+                               }
+                               action->set_param("waypoint",waypoint);
+               
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action_front(action);
+                       }
+               }
+       }
+}
+
+
+void
+Action::KeyframeSet::perform()
+{
+
+       old_time=get_canvas()->keyframe_list().find(keyframe)->get_time();
+       new_time=keyframe.get_time();
+       
+       try { get_canvas()->keyframe_list().find(keyframe);}
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find the given keyframe"));
+       }       
+       
+       // Check for colisions
+       if(old_time!=new_time)
+       {
+               try {
+                       get_canvas()->keyframe_list().find(new_time);
+                       throw Error(_("Cannot change keyframe time because another keyframe already exists with that time."));
+               }
+               catch(Exception::NotFound) { }
+       }
+       try { keyframe_next=get_canvas()->keyframe_list().find_next(old_time)->get_time(); }
+       catch(...) { keyframe_next=Time::end(); }
+       try { keyframe_prev=get_canvas()->keyframe_list().find_prev(old_time)->get_time(); }
+       catch(...) { keyframe_prev=Time::begin(); }
+
+       old_keyframe=*get_canvas()->keyframe_list().find(keyframe);
+       *get_canvas()->keyframe_list().find(keyframe)=keyframe;
+       
+       get_canvas()->keyframe_list().sync();
+
+       try{
+               Action::Super::perform();
+       } catch(...)
+       {
+               *get_canvas()->keyframe_list().find(old_keyframe)=old_keyframe;
+
+               get_canvas()->keyframe_list().sync();
+               throw;
+       }
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_changed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::KeyframeSet::undo()
+{
+       Action::Super::undo();
+
+       *get_canvas()->keyframe_list().find(old_keyframe)=old_keyframe;
+
+       get_canvas()->keyframe_list().sync();
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_changed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframeset.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframeset.h
new file mode 100644 (file)
index 0000000..a943eea
--- /dev/null
@@ -0,0 +1,88 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeset.h
+**     \brief Template File
+**
+**     $Id: keyframeset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMESET_H
+#define __SINFG_APP_ACTION_KEYFRAMESET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+#include <sinfg/time.h>
+#include <sinfg/guid.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeSet :
+       public Super
+{
+private:
+
+       sinfg::Keyframe keyframe;
+       sinfg::Keyframe old_keyframe;
+       sinfg::Time old_time;
+       sinfg::Time new_time;
+
+       sinfg::Time keyframe_prev,keyframe_next;
+       
+       std::set<sinfg::GUID> guid_set;
+
+       void process_value_desc(const sinfgapp::ValueDesc& value_desc);
+       
+       int scale_activepoints(const sinfgapp::ValueDesc& value_desc,const sinfg::Time& old_begin,const sinfg::Time& old_end,const sinfg::Time& new_begin,const sinfg::Time& new_end);
+       int scale_waypoints(const sinfgapp::ValueDesc& value_desc,const sinfg::Time& old_begin,const sinfg::Time& old_end,const sinfg::Time& new_begin,const sinfg::Time& new_end);
+
+public:
+
+       KeyframeSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.cpp
new file mode 100644 (file)
index 0000000..ad311c2
--- /dev/null
@@ -0,0 +1,259 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeset.cpp
+**     \brief Template File
+**
+**     $Id: keyframesetdelta.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframesetdelta.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+#include "activepointsetsmart.h"
+#include "waypointsetsmart.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeSetDelta);
+ACTION_SET_NAME(Action::KeyframeSetDelta,"keyframe_set_delta");
+ACTION_SET_LOCAL_NAME(Action::KeyframeSetDelta,"Set Keyframe Delta");
+ACTION_SET_TASK(Action::KeyframeSetDelta,"set");
+ACTION_SET_CATEGORY(Action::KeyframeSetDelta,Action::CATEGORY_KEYFRAME|Action::CATEGORY_HIDDEN);
+ACTION_SET_PRIORITY(Action::KeyframeSetDelta,0);
+ACTION_SET_VERSION(Action::KeyframeSetDelta,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeSetDelta,"$Id: keyframesetdelta.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeSetDelta::KeyframeSetDelta():
+       delta(0)
+{
+       keyframe.set_time(Time::end());
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::KeyframeSetDelta::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("Keyframe"))
+       );
+       ret.push_back(ParamDesc("delta",Param::TYPE_KEYFRAME)
+               .set_local_name(_("Delta"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeSetDelta::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::KeyframeSetDelta::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               keyframe=param.get_keyframe();
+               return true;
+       }
+       if(name=="delta" && param.get_type()==Param::TYPE_TIME)
+       {
+               delta=param.get_time();
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeSetDelta::is_ready()const
+{
+       if(keyframe.get_time()==Time::end())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeSetDelta::prepare()
+{
+       clear();
+       value_desc_list.clear();
+       get_canvas_interface()->find_important_value_descs(value_desc_list);
+
+       
+       Time time(get_canvas()->keyframe_list().find(keyframe)->get_time());
+       
+       std::vector<sinfgapp::ValueDesc>::iterator iter;
+               DEBUGPOINT();
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               ValueDesc& value_desc(*iter);
+               ValueNode_Animated::Handle value_node(
+                       ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
+               );
+               
+               if(!value_node)
+                       continue;
+               
+               try{
+                       value_node->find(time);
+                       // if we got to this point, then we know that
+                       // a waypoint already exists here and we don't
+                       // need to add a new one.
+                       continue;
+               }catch(...)
+               {
+                       // Make sure there is something previous
+                       try{
+                               value_node->find_prev(time);
+                       }catch(...)
+                       {
+                               continue;
+                       }
+               }
+               Action::Handle action(Action::create("waypoint_set_smart"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_node",ValueNode::Handle::cast_static(value_node));
+
+               action->set_param("time",time);
+
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);                                             
+       }
+}
+
+void
+Action::KeyframeSetDelta::perform()
+{
+       if(!delta)
+               return;
+       Action::Super::perform();
+       
+//     Time location(keyframe.get_time());
+       Time location(get_canvas()->keyframe_list().find(keyframe)->get_time());        
+       Time delta(delta);
+       
+       get_canvas()->keyframe_list().insert_time(location,delta);
+
+       std::vector<sinfgapp::ValueDesc>::iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               ValueDesc& value_desc(*iter);
+               if(!value_desc.is_value_node())
+                       continue;
+               ValueNode_Animated::Handle animated(
+                       ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
+               );
+               if(animated)
+               {
+                       animated->insert_time(location,delta);
+                       continue;
+               }
+               ValueNode_DynamicList::Handle dyn_list(
+                       ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
+               );
+               if(dyn_list)
+               {
+                       dyn_list->insert_time(location,delta);
+                       continue;
+               }
+       }
+
+       // Signal that something has changed
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_changed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::KeyframeSetDelta::undo()
+{
+       if(!delta)
+               return;
+       
+//     Time location(keyframe.get_time());
+       Time location(get_canvas()->keyframe_list().find(keyframe)->get_time());        
+       Time delta(-delta);
+       
+       get_canvas()->keyframe_list().insert_time(location,delta);
+
+       std::vector<sinfgapp::ValueDesc>::iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               ValueDesc& value_desc(*iter);
+               if(!value_desc.is_value_node())
+                       continue;
+               ValueNode_Animated::Handle animated(
+                       ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
+               );
+               if(animated)
+               {
+                       animated->insert_time(location,delta);
+                       continue;
+               }
+               ValueNode_DynamicList::Handle dyn_list(
+                       ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())
+               );
+               if(dyn_list)
+               {
+                       dyn_list->insert_time(location,delta);
+                       continue;
+               }
+       }
+
+       Action::Super::undo();
+
+       // Signal that something has changed
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_keyframe_changed()(keyframe);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframesetdelta.h
new file mode 100644 (file)
index 0000000..5e993f8
--- /dev/null
@@ -0,0 +1,83 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeset.h
+**     \brief Template File
+**
+**     $Id: keyframesetdelta.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMESETDELTA_H
+#define __SINFG_APP_ACTION_KEYFRAMESETDELTA_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+#include <sinfg/time.h>
+#include <sinfg/guid.h>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeSetDelta :
+       public Super
+{
+private:
+       sinfg::Keyframe keyframe;
+       sinfg::Time delta;
+
+       std::vector<sinfgapp::ValueDesc> value_desc_list;
+
+       void process_value_desc(const sinfgapp::ValueDesc& value_desc);
+       
+       int scale_activepoints(const sinfgapp::ValueDesc& value_desc,const sinfg::Time& old_begin,const sinfg::Time& old_end,const sinfg::Time& new_begin,const sinfg::Time& new_end);
+       int scale_waypoints(const sinfgapp::ValueDesc& value_desc,const sinfg::Time& old_begin,const sinfg::Time& old_end,const sinfg::Time& new_begin,const sinfg::Time& new_end);
+
+public:
+
+       KeyframeSetDelta();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.cpp
new file mode 100644 (file)
index 0000000..17b9a7f
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframeset.cpp
+**     \brief Template File
+**
+**     $Id: keyframewaypointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "keyframewaypointset.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+#include "activepointsetsmart.h"
+#include "waypointsetsmart.h"
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::KeyframeWaypointSet);
+ACTION_SET_NAME(Action::KeyframeWaypointSet,"keyframe_waypoint_set");
+ACTION_SET_LOCAL_NAME(Action::KeyframeWaypointSet,"Set Waypoints at Keyframe");
+ACTION_SET_TASK(Action::KeyframeWaypointSet,"set");
+ACTION_SET_CATEGORY(Action::KeyframeWaypointSet,Action::CATEGORY_KEYFRAME);
+ACTION_SET_PRIORITY(Action::KeyframeWaypointSet,0);
+ACTION_SET_VERSION(Action::KeyframeWaypointSet,"0.0");
+ACTION_SET_CVS_ID(Action::KeyframeWaypointSet,"$Id: keyframewaypointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::KeyframeWaypointSet::KeyframeWaypointSet()
+{
+       keyframe.set_time(Time::begin()-1);
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::KeyframeWaypointSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("keyframe",Param::TYPE_KEYFRAME)
+               .set_local_name(_("Keyframe"))
+       );
+
+       ret.push_back(ParamDesc("model",Param::TYPE_WAYPOINTMODEL)
+               .set_local_name(_("Waypoint Model"))
+       );
+
+       return ret;
+}
+
+bool
+Action::KeyframeWaypointSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::KeyframeWaypointSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="keyframe" && param.get_type()==Param::TYPE_KEYFRAME)
+       {
+               keyframe=param.get_keyframe();
+               
+               return true;
+       }
+       if(name=="model" && param.get_type()==Param::TYPE_WAYPOINTMODEL)
+       {
+               waypoint_model=param.get_waypoint_model();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::KeyframeWaypointSet::is_ready()const
+{
+       if(keyframe.get_time()==(Time::begin()-1) || waypoint_model.is_trivial())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::KeyframeWaypointSet::prepare()
+{
+       clear();
+
+       try { get_canvas()->keyframe_list().find(keyframe);}
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find the given keyframe"));
+       }       
+
+       {
+               std::vector<sinfgapp::ValueDesc> value_desc_list;
+               get_canvas_interface()->find_important_value_descs(value_desc_list);
+               while(!value_desc_list.empty())
+               {
+                       process_value_desc(value_desc_list.back());
+                       value_desc_list.pop_back();
+               }
+       }
+}
+
+void
+Action::KeyframeWaypointSet::process_value_desc(const sinfgapp::ValueDesc& value_desc)
+{      
+       if(value_desc.is_value_node())
+       {
+               ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()));
+       
+               if(value_node)
+               {                       
+                       Action::Handle action(WaypointSetSmart::create());
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_node",ValueNode::Handle(value_node));
+                       
+                       Waypoint waypoint;
+                       try
+                       {
+                               waypoint=*value_node->find(keyframe.get_time());
+                       }
+                       catch(...)
+                       {
+                               waypoint.set_time(keyframe.get_time());
+                               waypoint.set_value((*value_node)(keyframe.get_time()));
+                       }
+                       waypoint.apply_model(waypoint_model);
+                       
+                       action->set_param("waypoint",waypoint);
+       
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+               
+                       add_action_front(action);                                               
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.h b/synfig-studio/trunk/src/sinfgapp/actions/keyframewaypointset.h
new file mode 100644 (file)
index 0000000..697a081
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file keyframewaypointset.h
+**     \brief Template File
+**
+**     $Id: keyframewaypointset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_KEYFRAMEWAYPOINTSET_H
+#define __SINFG_APP_ACTION_KEYFRAMESET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/keyframe.h>
+#include <sinfg/waypoint.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class KeyframeWaypointSet :
+       public Super
+{
+private:
+
+       sinfg::Keyframe keyframe;
+       sinfg::Waypoint::Model waypoint_model;
+
+
+       void process_value_desc(const sinfgapp::ValueDesc& value_desc);
+
+public:
+
+       KeyframeWaypointSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layeractivate.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layeractivate.cpp
new file mode 100644 (file)
index 0000000..fe0cefa
--- /dev/null
@@ -0,0 +1,198 @@
+/* === S I N F G =========================================================== */
+/*!    \file layeractivate.cpp
+**     \brief Template File
+**
+**     $Id: layeractivate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layeractivate.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+#define ACTION_INIT2(class) \
+       Action::Base* class::create() { return new class(); }   \
+       sinfg::String class::get_name()const { return name__; } 
+
+ACTION_INIT2(Action::LayerActivate);
+ACTION_SET_NAME(Action::LayerActivate,"layer_activate");
+ACTION_SET_LOCAL_NAME(Action::LayerActivate,_("Activate Layer"));
+ACTION_SET_TASK(Action::LayerActivate,"activate");
+ACTION_SET_CATEGORY(Action::LayerActivate,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerActivate,0);
+ACTION_SET_VERSION(Action::LayerActivate,"0.0");
+ACTION_SET_CVS_ID(Action::LayerActivate,"$Id: layeractivate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerActivate::LayerActivate()
+{
+}
+
+sinfg::String
+Action::LayerActivate::get_local_name()const
+{
+       if(!layer)
+               return _("Activate Layer");
+       String name;
+       if(layer->get_description().empty())
+               name=layer->get_local_name();
+       else
+               name=layer->get_description();
+
+       return (new_status?_("Activate "):_("Deactivate "))+name;
+}
+
+Action::ParamVocab
+Action::LayerActivate::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+       );
+
+       ret.push_back(ParamDesc("new_status",Param::TYPE_BOOL)
+               .set_local_name(_("New Status"))
+               .set_desc(_("The new status of the layer"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerActivate::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerActivate::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="new_status" && param.get_type()==Param::TYPE_BOOL)
+       {
+               new_status=param.get_bool();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerActivate::is_ready()const
+{
+       if(!layer)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerActivate::perform()
+{
+       Canvas::Handle subcanvas(layer->get_canvas());
+       
+       // Find the iterator for the layer
+       Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
+       
+       // If we couldn't find the layer in the canvas, then bail
+       if(*iter!=layer)
+               throw Error(_("This layer doesn't exist anymore."));
+
+       // If the subcanvas isn't the same as the canvas,
+       // then it had better be an inline canvas. If not,
+       // bail
+       //if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+       //if(get_canvas()->get_root()!=subcanvas->get_root())
+       //      throw Error(_("This layer doesn't belong to this composition"));
+       
+       old_status=layer->active();
+       
+       // If we are changing the status to what it already is,
+       // the go ahead and return
+       if(new_status==old_status)
+       {
+               set_dirty(false);
+               return;
+       }
+       else
+               set_dirty();
+       
+       if(new_status)
+               layer->enable();
+       else
+               layer->disable();
+
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_status_changed()(layer,new_status);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::LayerActivate::undo()
+{
+       // If we are changing the status to what it already is,
+       // the go ahead and return
+       if(new_status==old_status)
+       {
+               set_dirty(false);
+               return;
+       }
+       else
+               set_dirty();
+
+       // restore the old status
+       if(old_status)
+               layer->enable();
+       else
+               layer->disable();
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_status_changed()(layer,old_status);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layeractivate.h b/synfig-studio/trunk/src/sinfgapp/actions/layeractivate.h
new file mode 100644 (file)
index 0000000..57330ca
--- /dev/null
@@ -0,0 +1,75 @@
+/* === S I N F G =========================================================== */
+/*!    \file layeractivate.h
+**     \brief Template File
+**
+**     $Id: layeractivate.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERACTIVATE_H
+#define __SINFG_APP_ACTION_LAYERACTIVATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerActivate :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       bool old_status;
+       bool new_status;
+
+public:
+
+       LayerActivate();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layeradd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layeradd.cpp
new file mode 100644 (file)
index 0000000..d22ccc6
--- /dev/null
@@ -0,0 +1,145 @@
+/* === S I N F G =========================================================== */
+/*!    \file layeradd.cpp
+**     \brief Template File
+**
+**     $Id: layeradd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layeradd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerAdd);
+ACTION_SET_NAME(Action::LayerAdd,"layer_add");
+ACTION_SET_LOCAL_NAME(Action::LayerAdd,"Add Layer");
+ACTION_SET_TASK(Action::LayerAdd,"add");
+ACTION_SET_CATEGORY(Action::LayerAdd,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerAdd,0);
+ACTION_SET_VERSION(Action::LayerAdd,"0.0");
+ACTION_SET_CVS_ID(Action::LayerAdd,"$Id: layeradd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerAdd::LayerAdd()
+{
+}
+
+Action::ParamVocab
+Action::LayerAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("new",Param::TYPE_LAYER)
+               .set_local_name(_("New Layer"))
+               .set_desc(_("Layer to be added"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerAdd::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="new" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerAdd::is_ready()const
+{
+       if(!layer)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerAdd::perform()
+{
+       // Set the layer's canvas
+       layer->set_canvas(get_canvas());
+               
+       // Push the layer onto the front of the canvas
+       get_canvas()->push_front(layer);        
+
+       // Mark ourselves as dirty if necessary
+       //set_dirty(layer->active());
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_inserted()(layer,0);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::LayerAdd::undo()
+{
+       // Find the iterator for the layer
+       Canvas::iterator iter=find(get_canvas()->begin(),get_canvas()->end(),layer);
+               
+       // If we couldn't find the layer in the canvas, then bail
+       if(*iter!=layer)
+               throw Error(_("This layer doesn't exist anymore."));
+       
+       // Remove the layer from the canvas
+       get_canvas()->erase(iter);
+
+       // Mark ourselves as dirty if necessary
+       //set_dirty(layer->active());
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_removed()(layer);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layeradd.h b/synfig-studio/trunk/src/sinfgapp/actions/layeradd.h
new file mode 100644 (file)
index 0000000..48c3132
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file layeradd.h
+**     \brief Template File
+**
+**     $Id: layeradd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERADD_H
+#define __SINFG_APP_ACTION_LAYERADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+
+public:
+
+       LayerAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.cpp
new file mode 100644 (file)
index 0000000..d59217f
--- /dev/null
@@ -0,0 +1,154 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerduplicate.cpp
+**     \brief Template File
+**
+**     $Id: layerduplicate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerduplicate.h"
+#include "layeradd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerDuplicate);
+ACTION_SET_NAME(Action::LayerDuplicate,"layer_duplicate");
+ACTION_SET_LOCAL_NAME(Action::LayerDuplicate,"Duplicate Layer");
+ACTION_SET_TASK(Action::LayerDuplicate,"duplicate");
+ACTION_SET_CATEGORY(Action::LayerDuplicate,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerDuplicate,0);
+ACTION_SET_VERSION(Action::LayerDuplicate,"0.0");
+ACTION_SET_CVS_ID(Action::LayerDuplicate,"$Id: layerduplicate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerDuplicate::LayerDuplicate()
+{
+}
+
+Action::ParamVocab
+Action::LayerDuplicate::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be duplicated"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerDuplicate::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerDuplicate::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layers.push_back(param.get_layer());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerDuplicate::is_ready()const
+{
+       if(layers.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerDuplicate::prepare()
+{
+       if(!first_time())
+               return;
+       
+       std::list<sinfg::Layer::Handle>::const_iterator iter;
+       
+       for(iter=layers.begin();iter!=layers.end();++iter)
+       {
+               Layer::Handle layer(*iter);
+               
+               Canvas::Handle subcanvas(layer->get_canvas());
+               
+               // Find the iterator for the layer
+               Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
+               
+               // If we couldn't find the layer in the canvas, then bail
+               if(*iter!=layer)
+                       throw Error(_("This layer doesn't exist anymore."));
+       
+               // If the subcanvas isn't the same as the canvas,
+               // then it had better be an inline canvas. If not,
+               // bail
+               if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+                       throw Error(_("This layer doesn't belong to this canvas anymore"));
+               
+               Layer::Handle new_layer(layer->clone(guid));
+               
+               {
+                       Action::Handle action(Action::create("layer_move"));
+                       
+                       action->set_param("canvas",subcanvas);
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("layer",new_layer);
+                       action->set_param("new_index",layers.front()->get_depth());
+                       
+                       add_action_front(action);
+               }
+               {
+                       Action::Handle action(Action::create("layer_add"));
+               
+                       action->set_param("canvas",subcanvas);
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("new",new_layer);
+                       
+                       add_action_front(action);
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.h b/synfig-studio/trunk/src/sinfgapp/actions/layerduplicate.h
new file mode 100644 (file)
index 0000000..041e769
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerduplicate.h
+**     \brief Template File
+**
+**     $Id: layerduplicate.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERDUPLICATE_H
+#define __SINFG_APP_ACTION_LAYERDUPLICATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+#include <sinfg/guid.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class LayerDuplicate :
+       public Super
+{
+private:
+
+       sinfg::GUID guid;
+       std::list<sinfg::Layer::Handle> layers;
+
+public:
+
+       LayerDuplicate();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.cpp
new file mode 100644 (file)
index 0000000..fd08d03
--- /dev/null
@@ -0,0 +1,216 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerraise.cpp
+**     \brief Template File
+**
+**     $Id: layerencapsulate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerencapsulate.h"
+#include "layeradd.h"
+#include "layerremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerEncapsulate);
+ACTION_SET_NAME(Action::LayerEncapsulate,"layer_encapsulate");
+ACTION_SET_LOCAL_NAME(Action::LayerEncapsulate,"Encapsulate");
+ACTION_SET_TASK(Action::LayerEncapsulate,"encapsulate");
+ACTION_SET_CATEGORY(Action::LayerEncapsulate,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerEncapsulate,0);
+ACTION_SET_VERSION(Action::LayerEncapsulate,"0.0");
+ACTION_SET_CVS_ID(Action::LayerEncapsulate,"$Id: layerencapsulate.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerEncapsulate::LayerEncapsulate()
+{
+}
+
+Action::ParamVocab
+Action::LayerEncapsulate::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be encapsulated"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerEncapsulate::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerEncapsulate::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layers.push_back(param.get_layer());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerEncapsulate::is_ready()const
+{
+       if(layers.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+int
+Action::LayerEncapsulate::lowest_depth()const
+{
+       std::list<sinfg::Layer::Handle>::const_iterator iter;
+       int lowest_depth(0x7fffffff);
+       
+       for(iter=layers.begin();iter!=layers.end();++iter)
+       {
+               int depth((*iter)->get_depth());
+               if(depth<lowest_depth)
+                       lowest_depth=depth;
+       }
+       if(lowest_depth==0x7fffffff)
+               return 0;
+       return lowest_depth;
+}
+
+void
+Action::LayerEncapsulate::prepare()
+{
+
+       if(!first_time())
+               return;
+
+       if(layers.empty())
+               throw Error("No layers to encapsulate");
+               
+       // First create the new canvas and layer
+       if(!child_canvas)
+               child_canvas=Canvas::create_inline(get_canvas());
+       
+       Layer::Handle new_layer(Layer::create("PasteCanvas"));
+       
+       new_layer->set_param("canvas",child_canvas);
+       
+       int target_depth(lowest_depth());
+       
+       // Add the layer
+       {
+               Action::Handle action(LayerAdd::create());
+       
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("new",new_layer);
+               
+               add_action(action);
+       }       
+       
+       // Move the layer
+       {
+               Action::Handle action(Action::create("layer_move"));
+               
+               assert(action);
+       
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("layer",new_layer);
+               action->set_param("new_index",target_depth);
+               
+               add_action(action);
+       }               
+               
+       std::list<sinfg::Layer::Handle>::reverse_iterator iter;
+       
+       for(iter=layers.rbegin();iter!=layers.rend();++iter)
+       {
+               Layer::Handle layer(*iter);
+               
+               Canvas::Handle subcanvas(layer->get_canvas());
+               
+               // Find the iterator for the layer
+               Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
+               
+               // If we couldn't find the layer in the canvas, then bail
+               if(*iter!=layer)
+                       throw Error(_("This layer doesn't exist anymore."));
+       
+               if(!subcanvas)
+                       throw Error(_("This layer doesn't have a parent canvas"));
+
+               // If the subcanvas isn't the same as the canvas,
+               // then it had better be an inline canvas. If not,
+               // bail
+               if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+                       throw Error(_("This layer doesn't belong to this canvas anymore"));
+
+               if(get_canvas()!=subcanvas)
+                       throw Error(_("get_canvas()!=subcanvas"));
+               
+               // Remove the layer from the old canvas
+               {
+                       Action::Handle action(LayerRemove::create());
+                       
+                       action->set_param("canvas",subcanvas);
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("layer",layer);
+                       
+                       add_action(action);
+               }
+               // Add the layer to the new canvas
+               {
+                       Action::Handle action(LayerAdd::create());
+                       
+                       action->set_param("canvas",child_canvas);
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("new",layer);
+                       
+                       add_action(action);
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.h b/synfig-studio/trunk/src/sinfgapp/actions/layerencapsulate.h
new file mode 100644 (file)
index 0000000..6573aae
--- /dev/null
@@ -0,0 +1,73 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerencapsulate.h
+**     \brief Template File
+**
+**     $Id: layerencapsulate.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERENCAPSULATE_H
+#define __SINFG_APP_ACTION_LAYERENCAPSULATE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+#include <sinfg/canvas.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class LayerEncapsulate :
+       public Super
+{
+private:
+       sinfg::Canvas::Handle child_canvas;
+       std::list<sinfg::Layer::Handle> layers;
+
+       int lowest_depth()const;
+
+public:
+
+       LayerEncapsulate();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerlower.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerlower.cpp
new file mode 100644 (file)
index 0000000..d08ff40
--- /dev/null
@@ -0,0 +1,155 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerlower.cpp
+**     \brief Template File
+**
+**     $Id: layerlower.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerlower.h"
+#include "layermove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerLower);
+ACTION_SET_NAME(Action::LayerLower,"layer_lower");
+ACTION_SET_LOCAL_NAME(Action::LayerLower,"Lower Layer");
+ACTION_SET_TASK(Action::LayerLower,"lower");
+ACTION_SET_CATEGORY(Action::LayerLower,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerLower,10);
+ACTION_SET_VERSION(Action::LayerLower,"0.0");
+ACTION_SET_CVS_ID(Action::LayerLower,"$Id: layerlower.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerLower::LayerLower()
+{
+}
+
+Action::ParamVocab
+Action::LayerLower::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be lowered"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerLower::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x))
+               return false;
+       
+       Layer::Handle layer(x.find("layer")->second.get_layer());
+       //sinfg::info("layer->get_depth()= %d ; layer->get_canvas()->size()=%d ;",layer->get_depth(),layer->get_canvas()->size());
+       if(layer->get_depth()+1>=layer->get_canvas()->size())
+               return false;
+       return true;
+}
+
+bool
+Action::LayerLower::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layers.push_back(param.get_layer());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerLower::is_ready()const
+{
+       if(layers.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerLower::prepare()
+{
+       std::list<sinfg::Layer::Handle>::const_iterator iter;
+
+       clear();
+       
+       for(iter=layers.begin();iter!=layers.end();++iter)
+       {
+               Layer::Handle layer(*iter);
+               
+               Canvas::Handle subcanvas(layer->get_canvas());
+               
+               // Find the iterator for the layer
+               Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
+               
+               // If we couldn't find the layer in the canvas, then bail
+               if(*iter!=layer)
+                       throw Error(_("This layer doesn't exist anymore."));
+       
+               // If the subcanvas isn't the same as the canvas,
+               // then it had better be an inline canvas. If not,
+               // bail
+               //if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+               //      throw Error(_("This layer doesn't belong to this canvas anymore"));
+               
+               int new_index=iter-subcanvas->begin();
+                               
+               new_index++;
+               
+               // If this lowers the layer past the bottom then don't bother
+               if(new_index==subcanvas->size())
+                       continue;
+               
+               Action::Handle layer_move(LayerMove::create());
+               
+               layer_move->set_param("canvas",get_canvas());
+               layer_move->set_param("canvas_interface",get_canvas_interface());
+               layer_move->set_param("layer",layer);
+               layer_move->set_param("new_index",new_index);
+               
+               add_action_front(layer_move);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerlower.h b/synfig-studio/trunk/src/sinfgapp/actions/layerlower.h
new file mode 100644 (file)
index 0000000..5ae1886
--- /dev/null
@@ -0,0 +1,70 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerlower.h
+**     \brief Template File
+**
+**     $Id: layerlower.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERLOWER_H
+#define __SINFG_APP_ACTION_LAYERLOWER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class LayerLower :
+       public Super
+{
+private:
+
+       std::list<sinfg::Layer::Handle> layers;
+
+public:
+
+       LayerLower();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layermove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layermove.cpp
new file mode 100644 (file)
index 0000000..bd47fcd
--- /dev/null
@@ -0,0 +1,260 @@
+/* === S I N F G =========================================================== */
+/*!    \file layermove.cpp
+**     \brief Template File
+**
+**     $Id: layermove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layermove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerMove);
+ACTION_SET_NAME(Action::LayerMove,"layer_move");
+ACTION_SET_LOCAL_NAME(Action::LayerMove,_("Move Layer"));
+ACTION_SET_TASK(Action::LayerMove,"move");
+ACTION_SET_CATEGORY(Action::LayerMove,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerMove,0);
+ACTION_SET_VERSION(Action::LayerMove,"0.0");
+ACTION_SET_CVS_ID(Action::LayerMove,"$Id: layermove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+static const int nindex=-1;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerMove::LayerMove():
+       new_index(0xdeadbeef)
+{
+}
+
+Action::ParamVocab
+Action::LayerMove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be moved"))
+       );
+
+       ret.push_back(ParamDesc("new_index",Param::TYPE_INTEGER)
+               .set_local_name(_("New Index"))
+               .set_desc(_("Where the layer is to be moved to"))
+       );
+
+       ret.push_back(ParamDesc("dest_canvas",Param::TYPE_CANVAS)
+               .set_local_name(_("Destination Canvas"))
+               .set_desc(_("The canvas the layer is to be moved to"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerMove::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerMove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="new_index" && param.get_type()==Param::TYPE_INTEGER)
+       {
+               new_index=param.get_integer();
+               
+               return true;
+       }
+
+       if(name=="dest_canvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               dest_canvas=param.get_canvas();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerMove::is_ready()const
+{
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+       if(!layer || (unsigned)new_index==0xdeadbeef)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerMove::perform()
+{              
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+
+       Canvas::Handle subcanvas(layer->get_canvas());
+       src_canvas=subcanvas;
+       if(!dest_canvas)
+               dest_canvas=subcanvas;
+               
+       // Find the iterator for the layer
+       Canvas::iterator iter=find(src_canvas->begin(),src_canvas->end(),layer);
+       
+       // If we couldn't find the layer in the canvas, then bail
+       if(*iter!=layer)
+               throw Error(_("This layer doesn't exist anymore."));
+
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+
+       // If the subcanvas isn't the same as the canvas,
+       // then it had better be an inline canvas. If not,
+       // bail
+       //if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+       if(get_canvas()->get_root()!=dest_canvas->get_root() || get_canvas()->get_root()!=src_canvas->get_root())
+               throw Error(_("You cannot directly move layers across compositions"));
+       
+       old_index=iter-src_canvas->begin();
+       int depth;
+       
+       if(new_index<0)
+               depth=dest_canvas->size()+new_index+1;
+       else
+               depth=new_index;
+       
+       set_dirty(layer->active());
+
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+
+       // If we were to move it to where it is
+       if(old_index==depth && src_canvas==dest_canvas)
+               return;
+       
+       if(depth>dest_canvas->size())
+               depth=dest_canvas->size();
+       if(depth<0)
+               depth=0;
+               
+       src_canvas->erase(iter);
+       
+       dest_canvas->insert(dest_canvas->begin()+depth,layer);          
+       layer->set_canvas(dest_canvas);
+       
+       layer->changed();
+       dest_canvas->changed(); if(dest_canvas!=src_canvas) src_canvas->changed();
+       
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+       
+       if(get_canvas_interface())
+       {
+               if(src_canvas==dest_canvas)
+               {
+                       if(new_index==old_index-1)      // Raise
+                               get_canvas_interface()->signal_layer_raised()(layer);
+                       else if(new_index==old_index+1) // Lower
+                               get_canvas_interface()->signal_layer_lowered()(layer);
+                       else            // Moved
+                       {
+                               get_canvas_interface()->signal_layer_moved()(layer,depth,dest_canvas);
+                       }
+               }
+               else
+               {
+                       get_canvas_interface()->signal_layer_moved()(layer,depth,dest_canvas);
+               }
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+
+       sinfg::info(__FILE__":%d: layer->count()=%d",__LINE__,layer.count());
+}
+
+void
+Action::LayerMove::undo()
+{
+       // Find the iterator for the layer
+       Canvas::iterator iter=find(dest_canvas->begin(),dest_canvas->end(),layer);
+       
+       // If we couldn't find the layer in the canvas, then bail
+       if(*iter!=layer || (get_canvas()!=dest_canvas && !dest_canvas->is_inline()))
+               throw Error(_("This layer doesn't exist anymore."));
+       
+       // If we were to move it to where it is
+       if(old_index==new_index && src_canvas==dest_canvas)
+               return;
+
+       // Mark ourselves as dirty if necessary
+       set_dirty(layer->active());
+
+       dest_canvas->erase(iter);
+       
+       src_canvas->insert(src_canvas->begin()+old_index,layer);
+       layer->set_canvas(src_canvas);
+
+       layer->changed();
+       dest_canvas->changed(); if(dest_canvas!=src_canvas) src_canvas->changed();
+       
+       // Execute any signals
+       if(get_canvas_interface())
+       {
+               if(src_canvas==dest_canvas)
+               {
+                       if(new_index==old_index+1)      // Raise
+                               get_canvas_interface()->signal_layer_raised()(layer);
+                       else if(new_index==old_index-1) // Lower
+                               get_canvas_interface()->signal_layer_lowered()(layer);
+                       else            // Moved
+                       {
+                       get_canvas_interface()->signal_layer_moved()(layer,old_index,src_canvas);
+                       }
+               }
+               else
+               {
+                       get_canvas_interface()->signal_layer_moved()(layer,old_index,src_canvas);
+                       //get_canvas_interface()->signal_layer_removed()(layer);        
+                       //get_canvas_interface()->signal_layer_inserted()(layer,old_index);
+               }
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layermove.h b/synfig-studio/trunk/src/sinfgapp/actions/layermove.h
new file mode 100644 (file)
index 0000000..a6dc5ea
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file layermove.h
+**     \brief Template File
+**
+**     $Id: layermove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERMOVE_H
+#define __SINFG_APP_ACTION_LAYERMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerMove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       int old_index;
+       int new_index;
+
+       sinfg::Canvas::Handle src_canvas;
+       sinfg::Canvas::Handle dest_canvas;
+
+public:
+
+       LayerMove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.cpp
new file mode 100644 (file)
index 0000000..241c662
--- /dev/null
@@ -0,0 +1,187 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamconnect.cpp
+**     \brief Template File
+**
+**     $Id: layerparamconnect.cpp,v 1.2 2005/01/16 19:55:57 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerParamConnect);
+ACTION_SET_NAME(Action::LayerParamConnect,"layer_param_connect");
+ACTION_SET_LOCAL_NAME(Action::LayerParamConnect,_("Connect Layer Parameter"));
+ACTION_SET_TASK(Action::LayerParamConnect,"connect");
+ACTION_SET_CATEGORY(Action::LayerParamConnect,Action::CATEGORY_LAYER|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::LayerParamConnect,0);
+ACTION_SET_VERSION(Action::LayerParamConnect,"0.0");
+ACTION_SET_CVS_ID(Action::LayerParamConnect,"$Id: layerparamconnect.cpp,v 1.2 2005/01/16 19:55:57 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerParamConnect::LayerParamConnect()
+{
+}
+
+Action::ParamVocab
+Action::LayerParamConnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+       );
+
+       ret.push_back(ParamDesc("param",Param::TYPE_STRING)
+               .set_local_name(_("Param"))
+       );
+
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerParamConnect::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerParamConnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       if(name=="param" && param.get_type()==Param::TYPE_STRING)
+       {
+               param_name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerParamConnect::is_ready()const
+{
+       if(!layer)
+               sinfg::warning("Action::LayerParamConnect: Missing \"layer\"");
+       if(!value_node)
+               sinfg::warning("Action::LayerParamConnect: Missing \"value_node\"");
+       if(param_name.empty())
+               sinfg::warning("Action::LayerParamConnect: Missing \"param\"");
+       
+       if(!layer || !value_node || param_name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerParamConnect::perform()
+{
+       // See if the parameter is dynamic
+       if(layer->dynamic_param_list().count(param_name))
+               old_value_node=layer->dynamic_param_list().find(param_name)->second;
+       else
+       {
+               old_value_node=0;
+       }
+
+       old_value=layer->get_param(param_name);
+       if(!old_value.is_valid())
+               throw Error(_("Layer did not recognise parameter name"));               
+
+       if(!layer->set_param(param_name,(*value_node)(0)))
+               throw Error(_("Bad connection"));
+       
+       layer->connect_dynamic_param(param_name,value_node);
+
+       layer->changed();
+       value_node->changed();
+/*     if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+               //get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+*/
+}
+
+void
+Action::LayerParamConnect::undo()
+{
+       if(old_value_node)
+               layer->connect_dynamic_param(param_name,old_value_node);
+       else
+       {
+               layer->disconnect_dynamic_param(param_name);
+               layer->set_param(param_name,old_value);
+       }
+       
+       layer->changed();
+       if(old_value_node)
+               old_value_node->changed();
+       /*
+       if(layer->active())
+               set_dirty(true);
+       else
+               set_dirty(false);
+       */
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+               //if(old_value_node)get_canvas_interface()->signal_value_node_changed()(old_value_node);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/layerparamconnect.h
new file mode 100644 (file)
index 0000000..080c478
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamconnect.h
+**     \brief Template File
+**
+**     $Id: layerparamconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERPARAMCONNECT_H
+#define __SINFG_APP_ACTION_LAYERPARAMCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerParamConnect :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       sinfg::String   param_name;
+       sinfg::ValueNode::Handle        value_node;
+       sinfg::ValueNode::Handle        old_value_node;
+       sinfg::ValueBase old_value;
+
+
+public:
+
+       LayerParamConnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.cpp
new file mode 100644 (file)
index 0000000..72cd3c5
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamdisconnect.cpp
+**     \brief Template File
+**
+**     $Id: layerparamdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamdisconnect.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerParamDisconnect);
+ACTION_SET_NAME(Action::LayerParamDisconnect,"layer_param_disconnect");
+ACTION_SET_LOCAL_NAME(Action::LayerParamDisconnect,_("Disconnect Layer Parameter"));
+ACTION_SET_TASK(Action::LayerParamDisconnect,"disconnect");
+ACTION_SET_CATEGORY(Action::LayerParamDisconnect,Action::CATEGORY_LAYER|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::LayerParamDisconnect,0);
+ACTION_SET_VERSION(Action::LayerParamDisconnect,"0.0");
+ACTION_SET_CVS_ID(Action::LayerParamDisconnect,"$Id: layerparamdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerParamDisconnect::LayerParamDisconnect():
+       time(0)
+{
+       
+}
+
+Action::ParamVocab
+Action::LayerParamDisconnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+       );
+
+       ret.push_back(ParamDesc("param",Param::TYPE_STRING)
+               .set_local_name(_("Param"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_STRING)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerParamDisconnect::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerParamDisconnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="param" && param.get_type()==Param::TYPE_STRING)
+       {
+               param_name=param.get_string();
+               
+               return true;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerParamDisconnect::is_ready()const
+{
+       if(!layer || param_name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerParamDisconnect::perform()
+{
+       if(!layer->dynamic_param_list().count(param_name))
+               throw Error(_("Layer Parameter is not connected to anything"));
+
+       old_value_node=layer->dynamic_param_list().find(param_name)->second;
+       layer->disconnect_dynamic_param(param_name);
+       
+       if(new_value_node || ValueNode_DynamicList::Handle::cast_dynamic(old_value_node))
+       {
+               if(!new_value_node)
+                       new_value_node=old_value_node.clone();
+               layer->connect_dynamic_param(param_name,new_value_node);
+       }
+       else
+               layer->set_param(param_name,(*old_value_node)(time));
+       
+       layer->changed();
+       old_value_node->changed();
+
+       set_dirty(false);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+       }
+}
+
+void
+Action::LayerParamDisconnect::undo()
+{
+       layer->connect_dynamic_param(param_name,old_value_node);
+       
+/*     if(layer->active() && get_canvas()->get_time()!=time)
+               set_dirty(true);
+       else
+               set_dirty(false);
+*/
+       layer->changed();
+       old_value_node->changed();
+
+       set_dirty(false);
+
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/layerparamdisconnect.h
new file mode 100644 (file)
index 0000000..1a0f63f
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamdisconnect.h
+**     \brief Template File
+**
+**     $Id: layerparamdisconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERPARAMDISCONNECT_H
+#define __SINFG_APP_ACTION_LAYERPARAMDISCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerParamDisconnect :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       sinfg::String   param_name;
+       sinfg::ValueNode::Handle        old_value_node;
+       sinfg::ValueNode::Handle        new_value_node;
+       sinfg::Time time;
+
+public:
+
+       LayerParamDisconnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerparamset.cpp
new file mode 100644 (file)
index 0000000..681b25c
--- /dev/null
@@ -0,0 +1,170 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamset.cpp
+**     \brief Template File
+**
+**     $Id: layerparamset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerParamSet);
+ACTION_SET_NAME(Action::LayerParamSet,"layer_param_set");
+ACTION_SET_LOCAL_NAME(Action::LayerParamSet,_("Set Layer Parameter"));
+ACTION_SET_TASK(Action::LayerParamSet,"set");
+ACTION_SET_CATEGORY(Action::LayerParamSet,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerParamSet,0);
+ACTION_SET_VERSION(Action::LayerParamSet,"0.0");
+ACTION_SET_CVS_ID(Action::LayerParamSet,"$Id: layerparamset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerParamSet::LayerParamSet()
+{
+}
+
+Action::ParamVocab
+Action::LayerParamSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+       );
+
+       ret.push_back(ParamDesc("param",Param::TYPE_STRING)
+               .set_local_name(_("Param"))
+       );
+
+       ret.push_back(ParamDesc("new_value",Param::TYPE_VALUE)
+               .set_local_name(_("ValueBase"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerParamSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerParamSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="new_value" && param.get_type()==Param::TYPE_VALUE)
+       {
+               new_value=param.get_value();
+               
+               return true;
+       }
+
+       if(name=="param" && param.get_type()==Param::TYPE_STRING)
+       {
+               param_name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerParamSet::is_ready()const
+{
+       if(!layer || !new_value.is_valid() || param_name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerParamSet::perform()
+{
+       // See if the parameter is dynamic
+       if(layer->dynamic_param_list().count(param_name))
+               throw Error(_("ValueNode attached to Parameter."));
+
+       old_value=layer->get_param(param_name);
+       
+       if(!layer->set_param(param_name,new_value))
+               throw Error(_("Layer did not accept parameter."));
+
+       /*if(layer->active())
+               set_dirty(true);
+       else
+               set_dirty(false);
+       */
+       layer->changed();
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+       }
+}
+
+void
+Action::LayerParamSet::undo()
+{
+       if(!layer->set_param(param_name,old_value))
+               throw Error(_("Layer did not accept parameter."));
+
+       /*
+       if(layer->active())
+               set_dirty(true);
+       else
+               set_dirty(false);
+       */
+       
+       layer->changed();
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_param_changed()(layer,param_name);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerparamset.h b/synfig-studio/trunk/src/sinfgapp/actions/layerparamset.h
new file mode 100644 (file)
index 0000000..39cbd62
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerparamset.h
+**     \brief Template File
+**
+**     $Id: layerparamset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERPARAMSET_H
+#define __SINFG_APP_ACTION_LAYERPARAMSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerParamSet :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       sinfg::String   param_name;
+       sinfg::ValueBase        new_value;
+       sinfg::ValueBase        old_value;
+
+
+public:
+
+       LayerParamSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerraise.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerraise.cpp
new file mode 100644 (file)
index 0000000..30b717f
--- /dev/null
@@ -0,0 +1,151 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerraise.cpp
+**     \brief Template File
+**
+**     $Id: layerraise.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerraise.h"
+#include "layermove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerRaise);
+ACTION_SET_NAME(Action::LayerRaise,"layer_raise");
+ACTION_SET_LOCAL_NAME(Action::LayerRaise,"Raise Layer");
+ACTION_SET_TASK(Action::LayerRaise,"raise");
+ACTION_SET_CATEGORY(Action::LayerRaise,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerRaise,9);
+ACTION_SET_VERSION(Action::LayerRaise,"0.0");
+ACTION_SET_CVS_ID(Action::LayerRaise,"$Id: layerraise.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerRaise::LayerRaise()
+{
+}
+
+Action::ParamVocab
+Action::LayerRaise::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be raised"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerRaise::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x))
+               return false;
+       if(x.find("layer")->second.get_layer()->get_depth()==0)
+               return false;
+       return true;
+}
+
+bool
+Action::LayerRaise::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layers.push_back(param.get_layer());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerRaise::is_ready()const
+{
+       if(layers.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerRaise::prepare()
+{
+       std::list<sinfg::Layer::Handle>::reverse_iterator iter;
+
+       clear();
+       
+       for(iter=layers.rbegin();!(iter==layers.rend());++iter)
+       {
+               Layer::Handle layer(*iter);
+               
+               Canvas::Handle subcanvas(layer->get_canvas());
+               
+               // Find the iterator for the layer
+               Canvas::iterator iter=find(subcanvas->begin(),subcanvas->end(),layer);
+               
+               // If we couldn't find the layer in the canvas, then bail
+               if(*iter!=layer)
+                       throw Error(_("This layer doesn't exist anymore."));
+       
+               // If the subcanvas isn't the same as the canvas,
+               // then it had better be an inline canvas. If not,
+               // bail
+               //if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+               //      throw Error(_("This layer doesn't belong to this canvas anymore"));
+               
+               int new_index=iter-subcanvas->begin();
+               
+               if(new_index==0)
+                       continue;
+               
+               new_index--;
+               
+               Action::Handle layer_move(LayerMove::create());
+               
+               layer_move->set_param("canvas",get_canvas());
+               layer_move->set_param("canvas_interface",get_canvas_interface());
+               layer_move->set_param("layer",layer);
+               layer_move->set_param("new_index",new_index);
+               
+               add_action_front(layer_move);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerraise.h b/synfig-studio/trunk/src/sinfgapp/actions/layerraise.h
new file mode 100644 (file)
index 0000000..bb01316
--- /dev/null
@@ -0,0 +1,70 @@
+/* === S I N F G =========================================================== */
+/*!    \file layerraise.h
+**     \brief Template File
+**
+**     $Id: layerraise.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERRAISE_H
+#define __SINFG_APP_ACTION_LAYERRAISE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class LayerRaise :
+       public Super
+{
+private:
+
+       std::list<sinfg::Layer::Handle> layers;
+
+public:
+
+       LayerRaise();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layerremove.cpp
new file mode 100644 (file)
index 0000000..a37a876
--- /dev/null
@@ -0,0 +1,180 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.cpp
+**     \brief Template File
+**
+**     $Id: layerremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerRemove);
+ACTION_SET_NAME(Action::LayerRemove,"layer_remove");
+ACTION_SET_LOCAL_NAME(Action::LayerRemove,"Remove Layer");
+ACTION_SET_TASK(Action::LayerRemove,"remove");
+ACTION_SET_CATEGORY(Action::LayerRemove,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerRemove,0);
+ACTION_SET_VERSION(Action::LayerRemove,"0.0");
+ACTION_SET_CVS_ID(Action::LayerRemove,"$Id: layerremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerRemove::LayerRemove()
+{
+}
+
+Action::ParamVocab
+Action::LayerRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be deleted"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerRemove::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               std::pair<sinfg::Layer::Handle,int> layer_pair;
+               layer_pair.first=param.get_layer();
+               layer_list.push_back(layer_pair);
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerRemove::is_ready()const
+{
+       if(layer_list.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerRemove::perform()
+{
+       std::list<std::pair<sinfg::Layer::Handle,int> >::iterator iter;
+       for(iter=layer_list.begin();iter!=layer_list.end();++iter)
+       {
+               Layer::Handle layer(iter->first);
+//             int& depth(iter->second);
+               Canvas::Handle subcanvas(layer->get_canvas());
+
+               // Find the iterator for the layer
+               Canvas::iterator iter2=find(subcanvas->begin(),subcanvas->end(),layer);
+               
+               // If we couldn't find the layer in the canvas, then bail
+               if(*iter2!=layer)
+               {
+                       /*!     \fixme We should really undo all prior removals
+                       **      before we go throwing shit around */
+                       throw Error(_("This layer doesn't exist anymore."));
+               }
+               
+               // If the subcanvas isn't the same as the canvas,
+               // then it had better be an inline canvas. If not,
+               // bail
+               if(get_canvas()!=subcanvas && !subcanvas->is_inline())
+               {
+                       /*!     \fixme We should really undo all prior removals
+                       **      before we go throwing shit around */
+                       throw Error(_("This layer doesn't belong to this canvas anymore"));
+               }
+               
+               set_canvas(subcanvas);
+               
+               // Calculate the depth that the layer was at (For the undo)
+               iter->second=layer->get_depth();
+       
+               // Mark ourselves as dirty if necessary
+               set_dirty(layer->active());
+                       
+               // Remove the layer from the canvas
+               subcanvas->erase(iter2);
+               
+               // Signal that a layer has been removed
+               if(get_canvas_interface())
+                       get_canvas_interface()->signal_layer_removed()(layer);
+       }
+}
+
+void
+Action::LayerRemove::undo()
+{
+       std::list<std::pair<sinfg::Layer::Handle,int> >::reverse_iterator iter;
+       for(iter=layer_list.rbegin();iter!=layer_list.rend();++iter)
+       {       
+               Layer::Handle layer(iter->first);
+               int& depth(iter->second);
+               
+               // Set the layer's canvas
+               layer->set_canvas(get_canvas());
+       
+               // Make sure that the depth is valid
+               if(get_canvas()->size()<depth)
+                       depth=get_canvas()->size();
+               
+               // Mark ourselves as dirty if necessary
+               set_dirty(layer->active());
+       
+               // Insert the layer into the canvas at the desired depth
+               get_canvas()->insert(get_canvas()->begin()+depth,layer);        
+               
+               // Signal that a layer has been inserted
+               if(get_canvas_interface())
+                       get_canvas_interface()->signal_layer_inserted()(layer,depth);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layerremove.h b/synfig-studio/trunk/src/sinfgapp/actions/layerremove.h
new file mode 100644 (file)
index 0000000..fb12d51
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file action_layerremove.h
+**     \brief Template File
+**
+**     $Id: layerremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERREMOVE_H
+#define __SINFG_APP_ACTION_LAYERREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       std::list<std::pair<sinfg::Layer::Handle,int> > layer_list;
+       
+       //sinfg::Layer::Handle layer;
+       //int depth;
+
+public:
+
+       LayerRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.cpp b/synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.cpp
new file mode 100644 (file)
index 0000000..717c3b5
--- /dev/null
@@ -0,0 +1,141 @@
+/* === S I N F G =========================================================== */
+/*!    \file layersetdesc.cpp
+**     \brief Template File
+**
+**     $Id: layersetdesc.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layersetdesc.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::LayerSetDesc);
+ACTION_SET_NAME(Action::LayerSetDesc,"layer_set_desc");
+ACTION_SET_LOCAL_NAME(Action::LayerSetDesc,_("Set Layer Description"));
+ACTION_SET_TASK(Action::LayerSetDesc,"set_desc");
+ACTION_SET_CATEGORY(Action::LayerSetDesc,Action::CATEGORY_LAYER);
+ACTION_SET_PRIORITY(Action::LayerSetDesc,0);
+ACTION_SET_VERSION(Action::LayerSetDesc,"0.0");
+ACTION_SET_CVS_ID(Action::LayerSetDesc,"$Id: layersetdesc.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+static const int nindex=-1;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::LayerSetDesc::LayerSetDesc()
+{
+}
+
+Action::ParamVocab
+Action::LayerSetDesc::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("layer",Param::TYPE_LAYER)
+               .set_local_name(_("Layer"))
+               .set_desc(_("Layer to be moved"))
+       );
+
+       ret.push_back(ParamDesc("new_description",Param::TYPE_STRING)
+               .set_local_name(_("New Description"))
+               .set_local_name(_("Enter a new description for this layer"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::LayerSetDesc::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::LayerSetDesc::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="layer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               layer=param.get_layer();
+               
+               return true;
+       }
+
+       if(name=="new_description" && param.get_type()==Param::TYPE_STRING)
+       {
+               new_description=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::LayerSetDesc::is_ready()const
+{
+       if(!layer)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::LayerSetDesc::perform()
+{
+       old_description=layer->get_description();
+       layer->set_description(new_description);
+       set_dirty(false);
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_new_description()(layer,new_description);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::LayerSetDesc::undo()
+{
+       layer->set_description(old_description);
+       set_dirty(false);
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_layer_new_description()(layer,old_description);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.h b/synfig-studio/trunk/src/sinfgapp/actions/layersetdesc.h
new file mode 100644 (file)
index 0000000..d4c011c
--- /dev/null
@@ -0,0 +1,75 @@
+/* === S I N F G =========================================================== */
+/*!    \file layersetdesc.h
+**     \brief Template File
+**
+**     $Id: layersetdesc.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_LAYERSETDSEC_H
+#define __SINFG_APP_ACTION_LAYERSETDSEC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class LayerSetDesc :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Layer::Handle layer;
+       sinfg::String old_description;
+       sinfg::String new_description;
+
+public:
+
+       LayerSetDesc();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.cpp b/synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.cpp
new file mode 100644 (file)
index 0000000..9a868a6
--- /dev/null
@@ -0,0 +1,322 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointscopy.cpp
+**     \brief Copy the Time Points File
+**
+**     $Id: timepointscopy.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "timepointscopy.h"
+#include <sinfg/layer_pastecanvas.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+
+#include "activepointsimpleadd.h"
+#include "waypointsimpleadd.h"
+#include <sinfgapp/timegather.h>
+
+#include <typeinfo>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::TimepointsCopy);
+ACTION_SET_NAME(Action::TimepointsCopy,"timepoint_copy");
+ACTION_SET_LOCAL_NAME(Action::TimepointsCopy,"Copy Time Points");
+ACTION_SET_TASK(Action::TimepointsCopy,"copy");
+ACTION_SET_CATEGORY(Action::TimepointsCopy,Action::CATEGORY_WAYPOINT|Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::TimepointsCopy,0);
+ACTION_SET_VERSION(Action::TimepointsCopy,"0.0");
+ACTION_SET_CVS_ID(Action::TimepointsCopy,"$Id: timepointscopy.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::TimepointsCopy::TimepointsCopy()
+{
+       timedelta = 0;
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::TimepointsCopy::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("addlayer",Param::TYPE_VALUE)
+               .set_local_name(_("New Selected Layer"))
+               .set_desc(_("A layer to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addcanvas",Param::TYPE_CANVAS)
+               .set_local_name(_("New Selected Canvas"))
+               .set_desc(_("A canvas to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addvaluedesc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("New Selected ValueBase"))
+               .set_desc(_("A valuenode's description to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addtime",Param::TYPE_TIME)
+               .set_local_name(_("New Selected Time Point"))
+               .set_desc(_("A time point to add to our selected list"))
+               .set_supports_multiple()
+       );
+       
+       ret.push_back(ParamDesc("deltatime",Param::TYPE_TIME)
+               .set_local_name(_("Time adjustment"))
+               .set_desc(_("The amount of time to adjust all the selected points"))
+       );
+
+       return ret;
+}
+
+bool
+Action::TimepointsCopy::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x)) 
+               return false;
+       
+       if(     x.find("addlayer") == x.end() && 
+               x.find("addcanvas") == x.end() && 
+               x.find("addvaluedesc") == x.end())
+               return false;
+       return true;
+}
+
+bool
+Action::TimepointsCopy::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="addlayer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               //add a layer to the list
+               sel_layers.push_back(param.get_layer());
+               //sinfg::info("action got layer");
+               
+               return true;
+       }
+       
+       if(name=="addcanvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               //add a layer to the list
+               sel_canvases.push_back(param.get_canvas());
+               //sinfg::info("action got canvas");
+               
+               return true;
+       }
+       
+       if(name=="addvaluedesc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               //add a layer to the list
+               sel_values.push_back(param.get_value_desc());
+               //sinfg::info("action got valuedesc");
+               
+               return true;
+       }
+       
+       if(name=="addtime" && param.get_type()==Param::TYPE_TIME)
+       {
+               //add a layer to the list
+               sel_times.insert(param.get_time());
+               //sinfg::info("action got time");
+               
+               return true;
+       }
+       
+       if(name=="deltatime" && param.get_type()==Param::TYPE_TIME)
+       {
+               timedelta = param.get_time();
+               //sinfg::info("action got time to move");
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::TimepointsCopy::is_ready()const
+{
+       if((sel_layers.empty() && sel_canvases.empty() && sel_values.empty()) || sel_times.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::TimepointsCopy::prepare()
+{
+       clear();
+       
+       //sinfg::info("Preparing TimepointsCopy by %f secs",(float)timemove);
+       
+       if(sel_times.empty()) return;
+       
+       //all our lists should be set correctly...
+
+       //build our sub-action list
+       //      and yes we do need to store it temporarily so we don't duplicate 
+       //              an operation on a specific valuenode, etc....
+       timepoints_ref  match;
+       
+       Time fps = get_canvas()->rend_desc().get_frame_rate();
+       
+       //std::vector<sinfg::Layer::Handle>
+       //sinfg::info("Layers %d", sel_layers.size());
+       {
+               std::vector<sinfg::Layer::Handle>::iterator i = sel_layers.begin(),
+                                                                                                       end = sel_layers.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a layer");
+                       recurse_layer(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfg::Canvas::Handle>    sel_canvases;
+       //sinfg::info("Canvases %d", sel_canvases.size());
+       {
+               std::vector<sinfg::Canvas::Handle>::iterator    i = sel_canvases.begin(),
+                                                                                                               end = sel_canvases.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a canvas");
+                       recurse_canvas(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfgapp::ValueDesc>
+       //sinfg::info("ValueBasedescs %d", sel_values.size());
+       {
+               std::vector<sinfgapp::ValueDesc>::iterator      i = sel_values.begin(),
+                                                                                                       end = sel_values.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a valuedesc");
+                       recurse_valuedesc(*i,sel_times,match);
+               }
+       }
+       
+       //sinfg::info("built list of waypoints/activepoints to modify");
+       //sinfg::info("\t There are %d waypoint sets and %d activepointsets", 
+       //                              match.waypointbiglist.size(), match.actpointbiglist.size());
+       //process the hell out of em...
+       {
+               //must build from both lists
+               timepoints_ref::waytracker::const_iterator      i = match.waypointbiglist.begin(),
+                                                                                                       end = match.waypointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       //iterate through each waypoint for this specific valuenode
+                       std::set<sinfg::Waypoint>::const_iterator       j = i->waypoints.begin(),
+                                                                                                               end = i->waypoints.end();                       
+                       for(; j != end; ++j)
+                       {
+                               Action::Handle action(WaypointSimpleAdd::create());
+               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle(i->val));
+                               
+                               //sinfg::info("add waypoint mod...");
+                               //NOTE: We may want to store the old time for undoing the action...
+                               Waypoint neww;
+                               Waypoint w = *j;
+                               w.set_time((w.get_time() + timedelta).round(fps));
+                               w.mimic(neww); //make sure the new waypoint has a new id
+                               
+                               action->set_param("waypoint",w);
+                               
+                               //run the action now that we've added everything
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                               
+                               add_action_front(action);
+                       }
+               }
+       }
+       {
+               //must build from both lists
+               timepoints_ref::acttracker::const_iterator      i = match.actpointbiglist.begin(),
+                                                                                                       end = match.actpointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       //iterate through each activepoint for this specific valuenode
+                       std::set<sinfg::Activepoint>::const_iterator    j = i->activepoints.begin(),
+                                                                                                                       jend = i->activepoints.end();
+                       for(; j != jend; ++j)
+                       {
+                               Action::Handle action(ActivepointSimpleAdd::create());
+                                       
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_desc",i->val);
+                               
+                               //NOTE: We may want to store the old time for undoing the action...
+                               Activepoint newa;
+                               Activepoint a = *j;
+                               a.set_time((a.get_time() + timedelta).round(fps));
+                               a.mimic(newa); //make sure the new activepoint has a new id
+                               
+                               action->set_param("activepoint",a);
+                               
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                               {
+                                       throw Error(Error::TYPE_NOTREADY);
+                               }
+                       
+                               add_action_front(action);
+                       }
+               }
+       }
+}
+
+void
+Action::TimepointsCopy::perform()
+{
+       Action::Super::perform();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.h b/synfig-studio/trunk/src/sinfgapp/actions/timepointscopy.h
new file mode 100644 (file)
index 0000000..4ee4026
--- /dev/null
@@ -0,0 +1,81 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointscopy.h
+**     \brief Copy the Time Points Header
+**
+**     $Id: timepointscopy.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_TIMEPOINTSCOPY_H
+#define __SINFG_APP_ACTION_TIMEPOINTSCOPY_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/time.h>
+#include <sinfg/layer.h>
+#include <sinfg/canvas.h>
+#include <sinfgapp/value_desc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class TimepointsCopy :
+       public Super
+{
+private:
+       
+       //process all the value descriptions that are selected (or are in subselections)
+       std::vector<sinfg::Layer::Handle>       sel_layers;
+       std::vector<sinfg::Canvas::Handle>      sel_canvases;
+       std::vector<sinfgapp::ValueDesc>        sel_values;
+       std::set<sinfg::Time>                           sel_times;
+       
+       sinfg::Time                                                     timedelta;
+
+public:
+
+       TimepointsCopy();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.cpp b/synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.cpp
new file mode 100644 (file)
index 0000000..6d88419
--- /dev/null
@@ -0,0 +1,285 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointsdelete.cpp
+**     \brief Delete the Time Points File
+**
+**     $Id: timepointsdelete.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "timepointsdelete.h"
+#include <sinfg/layer_pastecanvas.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+
+#include "activepointremove.h"
+#include "waypointremove.h"
+#include <sinfgapp/timegather.h>
+
+#include <typeinfo>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::TimepointsDelete);
+ACTION_SET_NAME(Action::TimepointsDelete,"timepoint_delete");
+ACTION_SET_LOCAL_NAME(Action::TimepointsDelete,"Delete Time Points");
+ACTION_SET_TASK(Action::TimepointsDelete,"delete");
+ACTION_SET_CATEGORY(Action::TimepointsDelete,Action::CATEGORY_WAYPOINT|Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::TimepointsDelete,0);
+ACTION_SET_VERSION(Action::TimepointsDelete,"0.0");
+ACTION_SET_CVS_ID(Action::TimepointsDelete,"$Id: timepointsdelete.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::TimepointsDelete::TimepointsDelete()
+{
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::TimepointsDelete::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("addlayer",Param::TYPE_VALUE)
+               .set_local_name(_("New Selected Layer"))
+               .set_desc(_("A layer to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addcanvas",Param::TYPE_CANVAS)
+               .set_local_name(_("New Selected Canvas"))
+               .set_desc(_("A canvas to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addvaluedesc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("New Selected ValueBase"))
+               .set_desc(_("A valuenode's description to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addtime",Param::TYPE_TIME)
+               .set_local_name(_("New Selected Time Point"))
+               .set_desc(_("A time point to add to our selected list"))
+               .set_supports_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::TimepointsDelete::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x)) 
+               return false;
+       
+       if(     x.find("addlayer") == x.end() && 
+               x.find("addcanvas") == x.end() && 
+               x.find("addvaluedesc") == x.end())
+               return false;
+       return true;
+}
+
+bool
+Action::TimepointsDelete::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="addlayer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               //add a layer to the list
+               sel_layers.push_back(param.get_layer());
+               
+               return true;
+       }
+       
+       if(name=="addcanvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               //add a layer to the list
+               sel_canvases.push_back(param.get_canvas());
+               
+               return true;
+       }
+       
+       if(name=="addvaluedesc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               //add a layer to the list
+               sel_values.push_back(param.get_value_desc());
+               
+               return true;
+       }
+       
+       if(name=="addtime" && param.get_type()==Param::TYPE_TIME)
+       {
+               //add a layer to the list
+               sel_times.insert(param.get_time());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::TimepointsDelete::is_ready()const
+{
+       if((sel_layers.empty() && sel_canvases.empty() && sel_values.empty()) || sel_times.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::TimepointsDelete::prepare()
+{
+       clear();
+       
+       if(sel_times.empty()) return;
+       
+       //all our lists should be set correctly...
+
+       //build our sub-action list
+       //      and yes we do need to store it temporarily so we don't duplicate 
+       //              an operation on a specific valuenode, etc....
+       timepoints_ref  match;
+       
+       Time fps = get_canvas()->rend_desc().get_frame_rate();
+       
+       //std::vector<sinfg::Layer::Handle>
+       //sinfg::info("Layers %d", sel_layers.size());
+       {
+               std::vector<sinfg::Layer::Handle>::iterator i = sel_layers.begin(),
+                                                                                                       end = sel_layers.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a layer");
+                       recurse_layer(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfg::Canvas::Handle>    sel_canvases;
+       //sinfg::info("Canvases %d", sel_canvases.size());
+       {
+               std::vector<sinfg::Canvas::Handle>::iterator    i = sel_canvases.begin(),
+                                                                                                               end = sel_canvases.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a canvas");
+                       recurse_canvas(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfgapp::ValueDesc>
+       //sinfg::info("ValueBasedescs %d", sel_values.size());
+       {
+               std::vector<sinfgapp::ValueDesc>::iterator      i = sel_values.begin(),
+                                                                                                       end = sel_values.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a valuedesc");
+                       recurse_valuedesc(*i,sel_times,match);
+               }
+       }
+       
+       //process the hell out of em...
+       {
+               //must build from both lists
+               timepoints_ref::waytracker::const_iterator      i = match.waypointbiglist.begin(),
+                                                                                                       end = match.waypointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       //iterate through each waypoint for this specific valuenode
+                       std::set<sinfg::Waypoint>::const_iterator       j = i->waypoints.begin(),
+                                                                                                               end = i->waypoints.end();                       
+                       for(; j != end; ++j)
+                       {
+                               Action::Handle action(WaypointRemove::create());
+               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle(i->val));
+                               action->set_param("waypoint",*j);
+                               
+                               //run the action now that we've added everything
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                               
+                               add_action_front(action);
+                       }
+               }
+       }
+       {
+               //must build from both lists
+               timepoints_ref::acttracker::const_iterator      i = match.actpointbiglist.begin(),
+                                                                                                       end = match.actpointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       //iterate through each activepoint for this specific valuenode
+                       std::set<sinfg::Activepoint>::const_iterator    j = i->activepoints.begin(),
+                                                                                                                       jend = i->activepoints.end();
+                       for(; j != jend; ++j)
+                       {
+                               Action::Handle action(ActivepointRemove::create());
+                                       
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_desc",i->val);
+                               action->set_param("activepoint",*j);
+                               
+                               //run the action now that everything should be in order
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                               {
+                                       throw Error(Error::TYPE_NOTREADY);
+                               }
+                       
+                               add_action_front(action);
+                       }
+               }
+       }
+}
+
+void
+Action::TimepointsDelete::perform()
+{
+       Action::Super::perform();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.h b/synfig-studio/trunk/src/sinfgapp/actions/timepointsdelete.h
new file mode 100644 (file)
index 0000000..e6d1cce
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointsdelete.h
+**     \brief Delete the Time Points Header
+**
+**     $Id: timepointsdelete.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_TIMEPOINTSDELETE_H
+#define __SINFG_APP_ACTION_TIMEPOINTSDELETE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/time.h>
+#include <sinfg/layer.h>
+#include <sinfg/canvas.h>
+#include <sinfgapp/value_desc.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class TimepointsDelete :
+       public Super
+{
+private:
+       
+       //process all the value descriptions that are selected (or are in subselections)
+       std::vector<sinfg::Layer::Handle>       sel_layers;
+       std::vector<sinfg::Canvas::Handle>      sel_canvases;
+       std::vector<sinfgapp::ValueDesc>        sel_values;
+       std::set<sinfg::Time>                           sel_times;
+
+public:
+
+       TimepointsDelete();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.cpp
new file mode 100644 (file)
index 0000000..27ae969
--- /dev/null
@@ -0,0 +1,327 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointsmove.cpp
+**     \brief Move the Time Points File
+**
+**     $Id: timepointsmove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "timepointsmove.h"
+#include <sinfg/layer_pastecanvas.h>
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_animated.h>
+
+#include "activepointset.h"
+#include "waypointset.h"
+#include <sinfgapp/timegather.h>
+
+#include <typeinfo>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::TimepointsMove);
+ACTION_SET_NAME(Action::TimepointsMove,"timepoint_move");
+ACTION_SET_LOCAL_NAME(Action::TimepointsMove,"Move Time Points");
+ACTION_SET_TASK(Action::TimepointsMove,"move");
+ACTION_SET_CATEGORY(Action::TimepointsMove,Action::CATEGORY_WAYPOINT|Action::CATEGORY_ACTIVEPOINT);
+ACTION_SET_PRIORITY(Action::TimepointsMove,0);
+ACTION_SET_VERSION(Action::TimepointsMove,"0.0");
+ACTION_SET_CVS_ID(Action::TimepointsMove,"$Id: timepointsmove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::TimepointsMove::TimepointsMove()
+{
+       timemove = 0;
+       set_dirty(false);
+}
+
+Action::ParamVocab
+Action::TimepointsMove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("addlayer",Param::TYPE_VALUE)
+               .set_local_name(_("New Selected Layer"))
+               .set_desc(_("A layer to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addcanvas",Param::TYPE_CANVAS)
+               .set_local_name(_("New Selected Canvas"))
+               .set_desc(_("A canvas to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addvaluedesc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("New Selected ValueBase"))
+               .set_desc(_("A valuenode's description to add to our selected list"))
+               .set_supports_multiple()
+               .set_optional()
+       );
+       
+       ret.push_back(ParamDesc("addtime",Param::TYPE_TIME)
+               .set_local_name(_("New Selected Time Point"))
+               .set_desc(_("A time point to add to our selected list"))
+               .set_supports_multiple()
+       );
+       
+       ret.push_back(ParamDesc("deltatime",Param::TYPE_TIME)
+               .set_local_name(_("Time adjustment"))
+               .set_desc(_("The amount of time to adjust all the selected points"))
+       );
+
+       return ret;
+}
+
+bool
+Action::TimepointsMove::is_canidate(const ParamList &x)
+{
+       if(!canidate_check(get_param_vocab(),x)) 
+               return false;
+       
+       if(     x.find("addlayer") == x.end() && 
+               x.find("addcanvas") == x.end() && 
+               x.find("addvaluedesc") == x.end())
+               return false;
+       return true;
+}
+
+bool
+Action::TimepointsMove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="addlayer" && param.get_type()==Param::TYPE_LAYER)
+       {
+               //add a layer to the list
+               sel_layers.push_back(param.get_layer());
+               //sinfg::info("action got layer");
+               
+               return true;
+       }
+       
+       if(name=="addcanvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               //add a layer to the list
+               sel_canvases.push_back(param.get_canvas());
+               //sinfg::info("action got canvas");
+               
+               return true;
+       }
+       
+       if(name=="addvaluedesc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               //add a layer to the list
+               sel_values.push_back(param.get_value_desc());
+               //sinfg::info("action got valuedesc");
+               
+               return true;
+       }
+       
+       if(name=="addtime" && param.get_type()==Param::TYPE_TIME)
+       {
+               //add a layer to the list
+               sel_times.insert(param.get_time());
+               //sinfg::info("action got time");
+               
+               return true;
+       }
+       
+       if(name=="deltatime" && param.get_type()==Param::TYPE_TIME)
+       {
+               timemove = param.get_time();
+               //sinfg::info("action got time to move");
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::TimepointsMove::is_ready()const
+{
+       if((sel_layers.empty() && sel_canvases.empty() && sel_values.empty()) || sel_times.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::TimepointsMove::prepare()
+{
+       clear();
+       
+       //sinfg::info("Preparing TimepointsMove by %f secs",(float)timemove);
+       
+       if(sel_times.empty()) return;
+       
+       //all our lists should be set correctly...
+       
+       /*{
+               std::set<sinfg::Time>::iterator i = sel_times.begin(), end = sel_times.end();
+               
+               for(; i != end; ++i)
+               {
+                       sinfg::info("Time %f", (float)*i);
+               }               
+       }*/
+
+       //build our sub-action list
+       //      and yes we do need to store it temporarily so we don't duplicate 
+       //              an operation on a specific valuenode, etc....
+       timepoints_ref  match;
+       
+       Time fps = get_canvas()->rend_desc().get_frame_rate();
+       
+       //std::vector<sinfg::Layer::Handle>
+       //sinfg::info("Layers %d", sel_layers.size());
+       {
+               std::vector<sinfg::Layer::Handle>::iterator i = sel_layers.begin(),
+                                                                                                       end = sel_layers.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a layer");
+                       recurse_layer(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfg::Canvas::Handle>    sel_canvases;
+       //sinfg::info("Canvases %d", sel_canvases.size());
+       {
+               std::vector<sinfg::Canvas::Handle>::iterator    i = sel_canvases.begin(),
+                                                                                                               end = sel_canvases.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a canvas");
+                       recurse_canvas(*i,sel_times,match);
+               }
+       }
+       
+       //std::vector<sinfgapp::ValueDesc>
+       //sinfg::info("ValueBasedescs %d", sel_values.size());
+       {
+               std::vector<sinfgapp::ValueDesc>::iterator      i = sel_values.begin(),
+                                                                                                       end = sel_values.end();
+               
+               for(; i != end; ++i)
+               {
+                       //sinfg::info("Recurse through a valuedesc");
+                       recurse_valuedesc(*i,sel_times,match);
+               }
+       }
+       
+       //sinfg::info("built list of waypoints/activepoints to modify");
+       //sinfg::info("\t There are %d waypoint sets and %d activepointsets", 
+       //                              match.waypointbiglist.size(), match.actpointbiglist.size());
+       //process the hell out of em...
+       {
+               //must build from both lists
+               timepoints_ref::waytracker::const_iterator      i = match.waypointbiglist.begin(),
+                                                                                                       end = match.waypointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       Action::Handle action(WaypointSet::create());
+               
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_node",ValueNode::Handle(i->val));
+                       
+                       //iterate through each waypoint for this specific valuenode
+                       std::set<sinfg::Waypoint>::const_iterator       j = i->waypoints.begin(),
+                                                                                                               end = i->waypoints.end();                       
+                       for(; j != end; ++j)
+                       {                               
+                               //sinfg::info("add waypoint mod...");
+                               //NOTE: We may want to store the old time for undoing the action...
+                               Waypoint w = *j;
+                               w.set_time((w.get_time() + timemove).round(fps));
+                               action->set_param("waypoint",w);
+                       }
+                       
+                       //run the action now that we've added everything
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+                       
+                       add_action_front(action);
+               }
+       }
+       {
+               //must build from both lists
+               timepoints_ref::acttracker::const_iterator      i = match.actpointbiglist.begin(),
+                                                                                                       end = match.actpointbiglist.end();
+               for(; i != end; ++i)
+               {
+                       Action::Handle action(ActivepointSet::create());
+                                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("value_desc",i->val);
+                       
+                       //iterate through each activepoint for this specific valuenode
+                       std::set<sinfg::Activepoint>::const_iterator    j = i->activepoints.begin(),
+                                                                                                                       jend = i->activepoints.end();
+                       for(; j != jend; ++j)
+                       {
+                               //sinfg::info("add activepoint mod...");
+                               
+                               //NOTE: We may want to store the old time for undoing the action...
+                               Activepoint a = *j;
+                               a.set_time((a.get_time() + timemove).round(fps));
+                               action->set_param("activepoint",a);
+                       }
+                       
+                       assert(action->is_ready());
+                       if(!action->is_ready())
+                       {
+                               throw Error(Error::TYPE_NOTREADY);
+                       }
+               
+                       add_action_front(action);
+               }
+       }
+}
+
+void
+Action::TimepointsMove::perform()
+{
+       Action::Super::perform();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.h b/synfig-studio/trunk/src/sinfgapp/actions/timepointsmove.h
new file mode 100644 (file)
index 0000000..90d1468
--- /dev/null
@@ -0,0 +1,84 @@
+/* === S I N F G =========================================================== */
+/*!    \file timepointsmove.h
+**     \brief Move the Time Points Header
+**
+**     $Id: timepointsmove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_TIMEPOINTSMOVE_H
+#define __SINFG_APP_ACTION_TIMEPOINTSMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/time.h>
+#include <sinfg/layer.h>
+#include <sinfg/canvas.h>
+#include <sinfgapp/value_desc.h>
+
+#include <vector>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class TimepointsMove :
+       public Super
+{
+private:
+       
+       //process all the value descriptions that are selected (or are in subselections)
+       std::vector<sinfg::Layer::Handle>       sel_layers;
+       std::vector<sinfg::Canvas::Handle>      sel_canvases;
+       std::vector<sinfgapp::ValueDesc>        sel_values;
+       std::set<sinfg::Time>                           sel_times;
+       
+       sinfg::Time                                                     timemove;
+
+public:
+
+       TimepointsMove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+       virtual void perform();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.cpp
new file mode 100644 (file)
index 0000000..b11b1d5
--- /dev/null
@@ -0,0 +1,216 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescconnect.cpp
+**     \brief Template File
+**
+**     $Id: valuedescconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamconnect.h"
+#include "valuenodelinkconnect.h"
+#include "valuenodereplace.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueDescConnect);
+ACTION_SET_NAME(Action::ValueDescConnect,"value_desc_connect");
+ACTION_SET_LOCAL_NAME(Action::ValueDescConnect,"Connect");
+ACTION_SET_TASK(Action::ValueDescConnect,"connect");
+ACTION_SET_CATEGORY(Action::ValueDescConnect,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueDescConnect,0);
+ACTION_SET_VERSION(Action::ValueDescConnect,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescConnect,"$Id: valuedescconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescConnect::ValueDescConnect()
+{
+}
+
+Action::ParamVocab
+Action::ValueDescConnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("dest",Param::TYPE_VALUEDESC)
+               .set_local_name(_("Destination ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("src",Param::TYPE_VALUENODE)
+               .set_local_name(_("Source ValueNode"))
+               .set_mutual_exclusion("src_name")
+       );
+
+       ret.push_back(ParamDesc("src_name",Param::TYPE_STRING)
+               .set_local_name(_("Source ValueNode Name"))
+               .set_mutual_exclusion("src")
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescConnect::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               if(x.count("src"))
+               {
+                       ValueDesc value_desc=x.find("dest")->second.get_value_desc();
+                       ValueNode::Handle value_node=x.find("src")->second.get_value_node();
+                       if(value_desc.get_value_type()==value_node->get_type()) 
+                               return true;
+               }
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueDescConnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="dest" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               return true;
+       }
+
+       if(name=="src" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       if(!value_node_name.empty() && !value_node && name=="canvas" && param.get_type()==Param::TYPE_CANVAS)
+       {
+               value_node=param.get_canvas()->find_value_node(value_node_name);
+       }
+       
+       if(name=="src_name" && param.get_type()==Param::TYPE_STRING)
+       {
+               value_node_name=param.get_string();
+               
+               if(get_canvas())
+               {
+                       value_node=get_canvas()->find_value_node(value_node_name);
+                       if(!value_node)
+                               return false;
+               }
+               
+               return true;
+       }
+       
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueDescConnect::is_ready()const
+{
+       if(!value_desc || !value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescConnect::prepare()
+{
+       clear();
+
+       if(value_desc.parent_is_canvas())
+       {                               
+               ValueNode::Handle dest_value_node;
+               dest_value_node=value_desc.get_value_node();
+
+               Action::Handle action(ValueNodeReplace::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",value_node);
+               action->set_param("dest",value_desc.get_value_node());
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_linkable_value_node())
+       {
+               Action::Handle action(ValueNodeLinkConnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("parent_value_node",value_desc.get_parent_value_node());
+               action->set_param("value_node", value_node);
+               action->set_param("index",value_desc.get_index());
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_layer_param())
+       {
+               Action::Handle action(LayerParamConnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("layer",value_desc.get_layer());
+               action->set_param("param",value_desc.get_param_name());
+               action->set_param("value_node",value_node);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       
+       throw Error(_("ValueDesc is not recognised or supported."));    
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedescconnect.h
new file mode 100644 (file)
index 0000000..c05e38d
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescconnect.h
+**     \brief Template File
+**
+**     $Id: valuedescconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCCONNECT_H
+#define __SINFG_APP_ACTION_VALUEDESCCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescConnect :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::ValueNode::Handle value_node;
+       sinfg::String value_node_name;
+
+public:
+
+       ValueDescConnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.cpp
new file mode 100644 (file)
index 0000000..5163bb5
--- /dev/null
@@ -0,0 +1,224 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescconvert.cpp
+**     \brief Template File
+**
+**     $Id: valuedescconvert.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+/*
+#include "valuenodereplace.h"
+#include "layerparamconnect.h"
+#include "valuenodelinkconnect.h"
+*/
+
+#include "valuedescconnect.h"
+
+#include "valuedescconvert.h"
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_const.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueDescConvert);
+ACTION_SET_NAME(Action::ValueDescConvert,"value_desc_convert");
+ACTION_SET_LOCAL_NAME(Action::ValueDescConvert,"Convert");
+ACTION_SET_TASK(Action::ValueDescConvert,"convert");
+ACTION_SET_CATEGORY(Action::ValueDescConvert,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ValueDescConvert,0);
+ACTION_SET_VERSION(Action::ValueDescConvert,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescConvert,"$Id: valuedescconvert.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescConvert::ValueDescConvert()
+{
+}
+
+Action::ParamVocab
+Action::ValueDescConvert::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("type",Param::TYPE_STRING)
+               .set_local_name(_("Type"))
+               .set_desc(_("The type of ValueNode that you want to be converted to"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescConvert::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueDescConvert::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               return true;
+       }
+
+       if(name=="type" && param.get_type()==Param::TYPE_STRING)
+       {
+               type=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueDescConvert::is_ready()const
+{
+       if(!value_desc || type.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescConvert::prepare()
+{
+       clear();
+
+       ValueBase value;
+       
+       if(value_desc.is_const())
+               value=value_desc.get_value();
+       else if(value_desc.is_value_node())
+               value=(*value_desc.get_value_node())(0);
+       else
+               throw Error(_("Unable to decipher ValueDesc (Bug?)"));
+       
+       ValueNode::Handle src_value_node(LinkableValueNode::create(type,value));
+
+       if(!src_value_node)
+               throw Error(_("Unable to create new value node"));
+
+       
+       ValueNode::Handle dest_value_node;
+       dest_value_node=value_desc.get_value_node();
+
+       Action::Handle action(ValueDescConnect::create());
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("src",src_value_node);
+       action->set_param("dest",value_desc);
+
+       assert(action->is_ready());
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+
+/*
+       return;         
+
+               
+       if(value_desc.parent_is_canvas())
+       {                               
+               ValueNode::Handle dest_value_node;
+               dest_value_node=value_desc.get_value_node();
+
+               Action::Handle action(ValueNodeReplace::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",src_value_node);
+               action->set_param("dest",dest_value_node);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_linkable_value_node())
+       {
+               Action::Handle action(ValueNodeLinkConnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("parent_value_node",value_desc.get_parent_value_node());
+               action->set_param("value_node", src_value_node);
+               action->set_param("index",value_desc.get_index());
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_layer_param())
+       {
+               Action::Handle action(LayerParamConnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("layer",value_desc.get_layer());
+               action->set_param("param",value_desc.get_param_name());
+               action->set_param("value_node",src_value_node);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       
+       
+       
+       throw Error(_("ValueDesc is not recognised or supported."));    
+*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedescconvert.h
new file mode 100644 (file)
index 0000000..bc18a3c
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescconvert.h
+**     \brief Template File
+**
+**     $Id: valuedescconvert.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCCONVERT_H
+#define __SINFG_APP_ACTION_VALUEDESCCONVERT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescConvert :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::String type;
+
+public:
+
+       ValueDescConvert();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.cpp
new file mode 100644 (file)
index 0000000..6227ed6
--- /dev/null
@@ -0,0 +1,193 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescdisconnect.cpp
+**     \brief Template File
+**
+**     $Id: valuedescdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamdisconnect.h"
+#include "valuenodelinkdisconnect.h"
+#include "valuenodereplace.h"
+
+#include "valuedescdisconnect.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_const.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueDescDisconnect);
+ACTION_SET_NAME(Action::ValueDescDisconnect,"value_desc_disconnect");
+ACTION_SET_LOCAL_NAME(Action::ValueDescDisconnect,"Disconnect");
+ACTION_SET_TASK(Action::ValueDescDisconnect,"disconnect");
+ACTION_SET_CATEGORY(Action::ValueDescDisconnect,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ValueDescDisconnect,-100);
+ACTION_SET_VERSION(Action::ValueDescDisconnect,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescDisconnect,"$Id: valuedescdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescDisconnect::ValueDescDisconnect():
+       time(0)
+{
+}
+
+Action::ParamVocab
+Action::ValueDescDisconnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescDisconnect::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_canvas() && value_desc.is_value_node() && value_desc.get_value_node()->rcount()>1)
+                       return true;
+               if(value_desc.is_const())
+                       return false;
+               if(value_desc.is_value_node() && ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+                       return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueDescDisconnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               return true;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueDescDisconnect::is_ready()const
+{
+       if(!value_desc)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescDisconnect::prepare()
+{
+       clear();
+
+       if(value_desc.parent_is_canvas())
+       {                               
+               ValueNode::Handle src_value_node;
+               src_value_node=ValueNode_Const::create((*value_desc.get_value_node())(time));
+
+               Action::Handle action(ValueNodeReplace::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",src_value_node);
+               action->set_param("dest",value_desc.get_value_node());
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_linkable_value_node())
+       {
+               Action::Handle action(ValueNodeLinkDisconnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("parent_value_node",value_desc.get_parent_value_node());
+               action->set_param("index",value_desc.get_index());
+               action->set_param("time",time);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       else
+       if(value_desc.parent_is_layer_param())
+       {
+               Action::Handle action(LayerParamDisconnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("layer",value_desc.get_layer());
+               action->set_param("param",value_desc.get_param_name());
+               action->set_param("time",time);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+               return;         
+       }
+       
+       throw Error(_("ValueDesc is not recognised or supported."));    
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedescdisconnect.h
new file mode 100644 (file)
index 0000000..c388cc3
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescdisconnect.h
+**     \brief Template File
+**
+**     $Id: valuedescdisconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCDISCONNECT_H
+#define __SINFG_APP_ACTION_VALUEDESCDISCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescDisconnect :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::Time time;
+
+public:
+
+       ValueDescDisconnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.cpp
new file mode 100644 (file)
index 0000000..a5fc143
--- /dev/null
@@ -0,0 +1,199 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescset.cpp
+**     \brief Template File
+**
+**     $Id: valuedescexport.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodeadd.h"
+
+#include "canvasadd.h"
+#include "valuedescexport.h"
+#include "layerparamconnect.h"
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_const.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueDescExport);
+ACTION_SET_NAME(Action::ValueDescExport,"value_desc_export");
+ACTION_SET_LOCAL_NAME(Action::ValueDescExport,"Export");
+ACTION_SET_TASK(Action::ValueDescExport,"export");
+ACTION_SET_CATEGORY(Action::ValueDescExport,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ValueDescExport,0);
+ACTION_SET_VERSION(Action::ValueDescExport,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescExport,"$Id: valuedescexport.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescExport::ValueDescExport()
+{
+}
+
+Action::ParamVocab
+Action::ValueDescExport::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("name",Param::TYPE_STRING)
+               .set_local_name(_("Name"))
+               .set_desc(_("The name that you want this value to be exported as"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescExport::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc=x.find("value_desc")->second.get_value_desc();
+               if(!value_desc || value_desc.parent_is_canvas() || (value_desc.is_value_node() && value_desc.get_value_node()->is_exported()))
+                       return false;
+               return true;
+       }
+       return false;           
+}
+
+bool
+Action::ValueDescExport::set_param(const sinfg::String& param_name, const Action::Param &param)
+{
+       if(param_name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               return true;
+       }
+
+       if(param_name=="name" && param.get_type()==Param::TYPE_STRING)
+       {
+               name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(param_name,param);
+}
+
+bool
+Action::ValueDescExport::is_ready()const
+{
+       if(!value_desc || name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescExport::prepare()
+{
+       clear();
+
+       ValueNode::Handle value_node;
+
+       if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
+       {
+               if(!value_desc.is_const())
+                       throw Error(_("Can only export Canvas when used as constant parameter"));
+               Canvas::Handle canvas(value_desc.get_value().get(Canvas::Handle()));
+               
+               Action::Handle action(CanvasAdd::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",canvas);
+               action->set_param("id",name);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);               
+               
+               return;
+       }
+
+       
+       if(value_desc.is_value_node())
+       {
+               if(value_desc.get_value_node()->is_exported())
+                       throw Error(_("ValueBase is already exported"));
+
+               value_node=value_desc.get_value_node();
+       }
+       else
+       {
+               if(!value_desc.parent_is_layer_param())
+                       throw Error(_("Unable to export parameter. (Bug?)"));
+                       
+               value_node=ValueNode_Const::create(value_desc.get_value());
+               
+               Action::Handle action(LayerParamConnect::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("layer",value_desc.get_layer());
+               action->set_param("param",value_desc.get_param_name());
+               action->set_param("value_node",value_node);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);               
+       }
+       
+       Action::Handle action(ValueNodeAdd::create());
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",get_canvas_interface());
+       action->set_param("new",value_node);
+       action->set_param("name",name);
+
+       assert(action->is_ready());             
+       if(!action->is_ready())
+               throw Error(Error::TYPE_NOTREADY);
+
+       add_action_front(action);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedescexport.h
new file mode 100644 (file)
index 0000000..d367104
--- /dev/null
@@ -0,0 +1,71 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescexport.h
+**     \brief Template File
+**
+**     $Id: valuedescexport.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCEXPORT_H
+#define __SINFG_APP_ACTION_VALUEDESCEXPORT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescExport :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::String name;
+
+public:
+
+       ValueDescExport();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.cpp
new file mode 100644 (file)
index 0000000..307d79f
--- /dev/null
@@ -0,0 +1,244 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedesclink.cpp
+**     \brief Template File
+**
+**     $Id: valuedesclink.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuedesclink.h"
+
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_const.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueDescLink);
+ACTION_SET_NAME(Action::ValueDescLink,"value_desc_link");
+ACTION_SET_LOCAL_NAME(Action::ValueDescLink,"Link");
+ACTION_SET_TASK(Action::ValueDescLink,"connect");
+ACTION_SET_CATEGORY(Action::ValueDescLink,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ValueDescLink,0);
+ACTION_SET_VERSION(Action::ValueDescLink,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescLink,"$Id: valuedesclink.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescLink::ValueDescLink()
+{
+       poison=false;
+}
+
+Action::ParamVocab
+Action::ValueDescLink::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc to link"))
+               .set_requires_multiple()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescLink::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueDescLink::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               return true;
+       }
+       
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+                               
+               if(value_desc.is_value_node() && value_desc.get_value_node()->is_exported())
+               {
+                       if(link_value_node==value_desc.get_value_node())
+                               return true;
+                       
+                       if(link_value_node && link_value_node->is_exported())
+                       {
+                               poison=true;
+                               return false;
+                       }
+                                               
+                       link_value_node=value_desc.get_value_node();
+               }
+               else if(value_desc.is_value_node())
+               {
+                       if(!link_value_node)
+                       {
+                               link_value_node=value_desc.get_value_node();
+                       }
+
+                       // Use the one that is referenced more
+                       else if(link_value_node->rcount()<value_desc.get_value_node()->rcount())
+                       {
+                               link_value_node=value_desc.get_value_node();
+                       }
+
+                       // If the current link value node is a constant and
+                       // this one isn't, then give preference to the exotic
+                       else if(ValueNode_Const::Handle::cast_dynamic(link_value_node) && !ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+                       {
+                               link_value_node=value_desc.get_value_node();
+                       }
+
+                       // If both are animated, and this one has more waypoints,
+                       // then use the one with more waypoints
+                       else if(
+                                       ValueNode_Animated::Handle::cast_dynamic(link_value_node)
+                               &&      ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())
+                               && (
+                                       ValueNode_Animated::Handle::cast_dynamic(link_value_node)->waypoint_list().size()
+                               <       ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())->waypoint_list().size()
+                               )
+                       )
+                       {
+                               link_value_node=value_desc.get_value_node();
+                       }
+                       
+                       /*
+                       // Use the one that was most recently changed
+                       else if(link_value_node->get_time_last_changed()<value_desc.get_value_node()->get_time_last_changed())
+                       {
+                               link_value_node=value_desc.get_value_node();
+                       }
+                       */
+               }
+
+               
+               if(value_desc_list.size() && value_desc.get_value_type()!=value_desc_list.front().get_value_type())
+               {
+                       // Everything must be of the same type
+                       poison=true;
+                       return false;
+               }
+               value_desc_list.push_back(value_desc);
+
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueDescLink::is_ready()const
+{
+       if(poison || value_desc_list.size()<=1)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescLink::prepare()
+{
+       if(poison || value_desc_list.empty())
+               throw Error(Error::TYPE_NOTREADY);
+               
+       clear();
+
+       if(!link_value_node)
+       {
+               ValueDesc& value_desc(value_desc_list.front());
+               
+               link_value_node=ValueNode_Const::create(value_desc.get_value(time));
+               
+               Action::Handle action(Action::create("value_desc_connect"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",link_value_node);
+               action->set_param("dest",value_desc);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);               
+       }
+
+       /*
+       if(!link_value_node->is_exported())
+       {
+               Action::Handle action(Action::create("value_node_add"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("new",link_value_node);
+               action->set_param("name",strprintf(_("Unnamed%08d"),sinfg::UniqueID().get_uid()));
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);
+       }
+       */
+       
+       std::list<ValueDesc>::iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               ValueDesc& value_desc(*iter);
+               
+               if(value_desc.is_value_node() && value_desc.get_value_node()==link_value_node)
+                       continue;
+
+               Action::Handle action(Action::create("value_desc_connect"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("src",link_value_node);
+               action->set_param("dest",value_desc);
+       
+               assert(action->is_ready());             
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action_front(action);               
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedesclink.h
new file mode 100644 (file)
index 0000000..76e3369
--- /dev/null
@@ -0,0 +1,72 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedesclink.h
+**     \brief Template File
+**
+**     $Id: valuedesclink.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCLINK_H
+#define __SINFG_APP_ACTION_VALUEDESCLINK_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescLink :
+       public Super
+{
+private:
+
+       std::list<ValueDesc> value_desc_list;
+       sinfg::ValueNode::Handle link_value_node;
+       bool poison;
+       sinfg::Time time;
+public:
+
+       ValueDescLink();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuedescset.cpp
new file mode 100644 (file)
index 0000000..9531d58
--- /dev/null
@@ -0,0 +1,532 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescset.cpp
+**     \brief Template File
+**
+**     $Id: valuedescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "layerparamset.h"
+#include "valuenodeconstset.h"
+#include "valuedescconnect.h"
+#include "waypointsetsmart.h"
+
+#include "valuedescset.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_composite.h>
+#include <sinfg/valuenode_radialcomposite.h>
+#include <sinfg/valuenode_reference.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+#define ACTION_INIT2(class) \
+       Action::Base* class::create() { return new class(); }   \
+       sinfg::String class::get_name()const { return name__; } 
+
+ACTION_INIT2(Action::ValueDescSet);
+ACTION_SET_NAME(Action::ValueDescSet,"value_desc_set");
+ACTION_SET_LOCAL_NAME(Action::ValueDescSet,"Set ValueDesc");
+ACTION_SET_TASK(Action::ValueDescSet,"set");
+ACTION_SET_CATEGORY(Action::ValueDescSet,Action::CATEGORY_VALUEDESC);
+ACTION_SET_PRIORITY(Action::ValueDescSet,0);
+ACTION_SET_VERSION(Action::ValueDescSet,"0.0");
+ACTION_SET_CVS_ID(Action::ValueDescSet,"$Id: valuedescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueDescSet::ValueDescSet():
+       time(0)
+{
+}
+
+sinfg::String
+Action::ValueDescSet::get_local_name()const
+{
+       String name("ValueDesc");
+       
+       if(!value_desc)
+       {
+       }
+       else if(value_desc.parent_is_layer_param())
+       {
+               if(value_desc.get_layer()->get_description().empty())
+                       name=value_desc.get_layer()->get_local_name();
+               else
+                       name=value_desc.get_layer()->get_description();
+               name+="->"+value_desc.get_param_name();
+       }
+       else if(value_desc.parent_is_value_node())
+       {
+               sinfg::LinkableValueNode::Handle value_node(sinfg::LinkableValueNode::Handle::cast_reinterpret(value_desc.get_parent_value_node()));
+               name=value_node->link_local_name(value_desc.get_index());
+               
+               sinfg::Node* node;
+               for(node=value_node.get();!node->parent_set.empty() && !dynamic_cast<Layer*>(node);node=*node->parent_set.begin());
+               Layer::Handle parent_layer(dynamic_cast<Layer*>(node));
+               if(parent_layer)
+               {
+                       if(parent_layer->get_description().empty())
+                               name=parent_layer->get_local_name()+"=>"+name;
+                       else
+                               name=parent_layer->get_description()+"=>"+name;
+               }
+       }
+
+       return strprintf(_("Set %s"),name.c_str());
+}
+
+Action::ParamVocab
+Action::ValueDescSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       ret.push_back(ParamDesc("new_value",Param::TYPE_VALUE)
+               .set_local_name(_("ValueBase"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueDescSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueDescSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               value_desc=param.get_value_desc();
+               
+               return true;
+       }
+
+       if(name=="new_value" && param.get_type()==Param::TYPE_VALUE)
+       {
+               value=param.get_value();
+               
+               return true;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueDescSet::is_ready()const
+{
+       if(!value_desc || !value.is_valid())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueDescSet::prepare()
+{
+       clear();
+
+       // If our tangents are merged, and
+       // our first tangent is being manipulated,
+       // then we also need to adjust the other
+       // tangent.
+       if(     value_desc.parent_is_value_node()
+       &&      value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT
+       &&      value_desc.get_index()==4
+       &&      (*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false
+       )
+       {
+               DEBUGPOINT();
+               ValueNode_Composite::Handle parent_value_node;
+               parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node());
+               
+               assert(parent_value_node);
+               
+               Action::Handle action(Action::create("value_desc_set"));
+       
+               if(!action)
+                       throw Error(_("Unable to find action value_desc_set (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("new_value",value);
+               action->set_param("value_desc",ValueDesc(parent_value_node,5));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);                     
+       }
+
+       // If we are a reference value node, then
+       // we need to distribute the changes to the
+       // referenced value node
+       if(value_desc.is_value_node() && ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               ValueDesc reference_value_desc(ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node()),0);
+
+               Action::Handle action(Action::create("value_desc_set"));
+
+               if(!action)
+                       throw Error(_("Unable to find action value_desc_set (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("new_value",value);
+               action->set_param("value_desc",reference_value_desc);
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+               add_action(action);                     
+       
+               return;
+       }
+       
+       // If we are a composite value node, then
+       // we need to distribute the changes to the
+       // individual parts
+       if(value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               ValueBase components[6];
+               int n_components(0);
+               switch(value.get_type())
+               {
+               case ValueBase::TYPE_VECTOR:
+                       components[0]=value.get(Vector())[0];
+                       components[1]=value.get(Vector())[1];
+                       n_components=2;
+                       break;
+               case ValueBase::TYPE_COLOR:
+                       components[0]=value.get(Color()).get_r();
+                       components[1]=value.get(Color()).get_g();
+                       components[2]=value.get(Color()).get_b();
+                       components[3]=value.get(Color()).get_a();
+                       n_components=4;
+                       break;
+               case ValueBase::TYPE_SEGMENT:
+                       components[0]=value.get(Segment()).p1;
+                       components[1]=value.get(Segment()).t1;
+                       components[2]=value.get(Segment()).p2;
+                       components[3]=value.get(Segment()).t2;
+                       n_components=4;
+                       break;
+               case ValueBase::TYPE_BLINEPOINT:
+               {
+                       BLinePoint bline_point(value);
+                       components[0]=bline_point.get_vertex();
+                       components[1]=bline_point.get_width();
+                       components[2]=bline_point.get_origin();
+                       components[3]=bline_point.get_split_tangent_flag();
+                       components[4]=bline_point.get_tangent1();
+                       components[5]=bline_point.get_tangent2();
+                       n_components=6;
+                       break;
+               }
+               default:
+                       throw Error("Bad type for composite (%s)",ValueBase::type_name(value.get_type()).c_str());                      
+                       break;
+               }
+               
+               for(int i=0;i<n_components;i++)
+               {
+                       ValueDesc component_value_desc(ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()),i);
+
+                       Action::Handle action(Action::create("value_desc_set"));
+       
+                       if(!action)
+                               throw Error(_("Unable to find action value_desc_set (bug)"));
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("time",time);
+                       action->set_param("new_value",components[i]);
+                       action->set_param("value_desc",component_value_desc);
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                       add_action(action);                     
+               }
+               
+               return;
+       }
+
+       
+       // If we are a RADIAL composite value node, then
+       // we need to distribute the changes to the
+       // individual parts
+       if(value_desc.is_value_node() && ValueNode_RadialComposite::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               ValueBase components[6];
+               int n_components(0);
+               switch(value.get_type())
+               {
+               case ValueBase::TYPE_VECTOR:
+               {
+                       Vector vect(value.get(Vector()));
+                       components[0]=vect.mag();
+                       components[1]=Angle(Angle::tan(vect[1],vect[0]));
+                       n_components=2;
+               }
+                       break;
+               case ValueBase::TYPE_COLOR:
+                       components[0]=value.get(Color()).get_y();
+                       components[1]=value.get(Color()).get_s();
+                       components[2]=value.get(Color()).get_hue();
+                       components[3]=value.get(Color()).get_a();
+                       n_components=4;
+                       break;
+               default:
+                       throw Error("Bad type for radial composite (%s)",ValueBase::type_name(value.get_type()).c_str());                       
+                       break;
+               }
+               for(int i=0;i<n_components;i++)
+               {
+                       ValueDesc component_value_desc(ValueNode_RadialComposite::Handle::cast_dynamic(value_desc.get_value_node()),i);
+
+                       Action::Handle action(Action::create("value_desc_set"));
+       
+                       if(!action)
+                               throw Error(_("Unable to find action value_desc_set (bug)"));
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("time",time);
+                       action->set_param("new_value",components[i]);
+                       action->set_param("value_desc",component_value_desc);
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                       add_action(action);                     
+               }
+               
+               return;
+       }
+
+       // If we are merging the tangents of a BLinePoint,
+       // we must also set the second tangent for things
+       // to interpolate properly
+       if(     value_desc.parent_is_value_node()
+       &&      value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT
+       &&      value_desc.get_index()==3
+//     &&      value.get(bool())==false        // Actually, we want to do this any time the split flag is tweaked with
+       )
+       {
+               ValueNode_Composite::Handle parent_value_node;
+               parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node());
+               
+               assert(parent_value_node);
+               
+               Action::Handle action(Action::create("value_desc_set"));
+       
+               if(!action)
+                       throw Error(_("Unable to find action value_desc_set (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("new_value",(*parent_value_node->get_link(4))(time));
+               action->set_param("value_desc",ValueDesc(parent_value_node,5));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);                     
+       }
+
+/*     DEBUGPOINT();
+       if(     value_desc.parent_is_value_node())
+       {
+               DEBUGPOINT();
+               if(value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT)
+               {
+                       DEBUGPOINT();
+                       if(value_desc.get_index()==4)
+                       {
+                               DEBUGPOINT();
+                               if((*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false)
+                               {
+                                       DEBUGPOINT();
+                               }
+                       }
+               }
+       }
+*/     
+
+       
+       // If we are in animate editing mode
+       if(get_edit_mode()&MODE_ANIMATE)
+       {
+
+               ValueNode_Animated::Handle& value_node(value_node_animated);
+
+               // If this value isn't a ValueNode_Animated, but
+               // it is somewhat constant, then go ahead and convert
+               // it to a ValueNode_Animated.
+               if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+               {
+                       ValueBase value;
+                       if(value_desc.is_value_node())
+                               value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
+                       else
+                               value=value_desc.get_value();
+                       
+                       if(!value_node)value_node=ValueNode_Animated::create(value,time);
+                       //if(!value_node)value_node=ValueNode_Animated::create(value.get_type());
+                       
+                       Action::Handle action;
+                       
+                       if(!value_desc.is_value_node())
+                       {
+                               action=(ValueDescConnect::create());
+                               action->set_param("dest",value_desc);
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       else
+                       {
+                               action=Action::create("value_node_replace");
+                               action->set_param("dest",value_desc.get_value_node());
+                               action->set_param("src",ValueNode::Handle(value_node));
+                       }
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                               DEBUGPOINT();
+                       add_action_front(action);
+               }
+               else
+               {
+                       value_node=value_node.cast_dynamic(value_desc.get_value_node());
+               }
+               
+                               DEBUGPOINT();
+               if(!value_node)
+                       throw Error(_("Direct manipulation of this ValueNode type is not yet supported"));              
+               
+               Action::Handle action(WaypointSetSmart::create());
+               
+               //Waypoint waypoint(value,time);
+               
+               Waypoint waypoint(value_node->new_waypoint_at_time(time));
+               waypoint.set_value(value);
+               
+               waypoint.set_before(sinfgapp::Main::get_interpolation());
+               waypoint.set_after(sinfgapp::Main::get_interpolation());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_node",ValueNode::Handle(value_node));
+               action->set_param("waypoint",waypoint);
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+                               DEBUGPOINT();
+               add_action(action);
+               
+               return;
+       }
+       else
+       {
+               if(value_desc.is_value_node())
+               {
+                       if(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
+                       {
+                               Action::Handle action(ValueNodeConstSet::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",value_desc.get_value_node());
+                               action->set_param("new_value",value);
+                               
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+               
+                               add_action_front(action);
+                               return;
+                       }
+                       else
+                       if(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()))
+                               throw Error(_("You must be in Animate-Editing-Mode to directly manipulate this value"));                
+                       else
+                               throw Error(_("Direct manipulation of this ValueNode type is not yet supported"));              
+               }
+               else
+               if(value_desc.parent_is_layer_param() && !value_desc.is_value_node())
+               {
+                       Action::Handle layer_param_set(LayerParamSet::create());
+                       
+                       layer_param_set->set_param("canvas",get_canvas());
+                       layer_param_set->set_param("canvas_interface",get_canvas_interface());
+                       layer_param_set->set_param("layer",value_desc.get_layer());
+                       layer_param_set->set_param("param",value_desc.get_param_name());
+                       layer_param_set->set_param("new_value",value);
+       
+                       if(!layer_param_set->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+                       
+                       add_action_front(layer_param_set);
+                       return;
+               }
+
+               throw Error(_("Unsupported ValueDesc type"));
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuedescset.h b/synfig-studio/trunk/src/sinfgapp/actions/valuedescset.h
new file mode 100644 (file)
index 0000000..dfba6fc
--- /dev/null
@@ -0,0 +1,74 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuedescset.h
+**     \brief Template File
+**
+**     $Id: valuedescset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUEDESCSET_H
+#define __SINFG_APP_ACTION_VALUEDESCSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_animated.h>
+#include <list>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class ValueDescSet :
+       public Super
+{
+private:
+
+       ValueDesc value_desc;
+       sinfg::ValueBase value;
+       sinfg::Time time;
+       sinfg::ValueNode_Animated::Handle value_node_animated;
+
+public:
+
+       ValueDescSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.cpp
new file mode 100644 (file)
index 0000000..5639633
--- /dev/null
@@ -0,0 +1,162 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodeadd.cpp
+**     \brief Template File
+**
+**     $Id: valuenodeadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodeadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeAdd);
+ACTION_SET_NAME(Action::ValueNodeAdd,"value_node_add");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeAdd,"Add ValueNode");
+ACTION_SET_TASK(Action::ValueNodeAdd,"add");
+ACTION_SET_CATEGORY(Action::ValueNodeAdd,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeAdd,0);
+ACTION_SET_VERSION(Action::ValueNodeAdd,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeAdd,"$Id: valuenodeadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeAdd::ValueNodeAdd()
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("new",Param::TYPE_VALUENODE)
+               .set_local_name(_("New ValueNode"))
+               .set_desc(_("ValueNode to be added"))
+       );
+
+       ret.push_back(ParamDesc("name",Param::TYPE_STRING)
+               .set_local_name(_("Name"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueNodeAdd::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueNodeAdd::set_param(const sinfg::String& param_name, const Action::Param &param)
+{
+       if(param_name=="new" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       if(param_name=="name" && param.get_type()==Param::TYPE_STRING)
+       {
+               name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(param_name,param);
+}
+
+bool
+Action::ValueNodeAdd::is_ready()const
+{
+       if(!value_node || name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeAdd::perform()
+{
+       if(value_node->is_exported())
+       {
+               throw Error(_("Parameter appears to already be exported"));
+       }
+       
+       try
+       {
+               get_canvas()->add_value_node(value_node,name);
+       }
+       catch(Exception::IDAlreadyExists)
+       {
+               throw Error(_("Another exported ValueBase with this name already exists"));
+       }
+       catch(...)
+       {
+               throw Error(_("Exception caught on Add ValueNode."));
+       }
+
+       set_dirty(false);
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_added()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
+
+void
+Action::ValueNodeAdd::undo()
+{
+       try { get_canvas()->remove_value_node(value_node); }
+       catch(...)
+       {
+               throw Error(_("Exception caught on Remove ValueNode."));
+       }
+
+       set_dirty(false);
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_deleted()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodeadd.h
new file mode 100644 (file)
index 0000000..3536f23
--- /dev/null
@@ -0,0 +1,74 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodeadd.h
+**     \brief Template File
+**
+**     $Id: valuenodeadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEADD_H
+#define __SINFG_APP_ACTION_VALUENODEADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode::Handle value_node;
+       sinfg::String name;
+
+public:
+
+       ValueNodeAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.cpp
new file mode 100644 (file)
index 0000000..c83f6a6
--- /dev/null
@@ -0,0 +1,147 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodeconstset.cpp
+**     \brief Template File
+**
+**     $Id: valuenodeconstset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodeconstset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeConstSet);
+ACTION_SET_NAME(Action::ValueNodeConstSet,"value_node_const_set");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeConstSet,_("Set ValueNode_Const"));
+ACTION_SET_TASK(Action::ValueNodeConstSet,"set");
+ACTION_SET_CATEGORY(Action::ValueNodeConstSet,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeConstSet,0);
+ACTION_SET_VERSION(Action::ValueNodeConstSet,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeConstSet,"$Id: valuenodeconstset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeConstSet::ValueNodeConstSet()
+{
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeConstSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode_Const"))
+       );
+
+       ret.push_back(ParamDesc("new_value",Param::TYPE_VALUE)
+               .set_local_name(_("ValueBase"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueNodeConstSet::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               if(ValueNode_Const::Handle::cast_dynamic(x.find("value_node")->second.get_value_node()))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeConstSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Const::Handle::cast_dynamic(param.get_value_node());
+               
+               return (bool)value_node;
+       }
+
+       if(name=="new_value" && param.get_type()==Param::TYPE_VALUE)
+       {
+               new_value=param.get_value();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeConstSet::is_ready()const
+{
+       if(!value_node || !new_value.is_valid())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeConstSet::perform()
+{
+       //set_dirty(true);
+       
+       old_value=value_node->get_value();
+
+       value_node->set_value(new_value);       
+       
+       // Signal that a layer has been inserted
+       /*if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }*/
+}
+
+void
+Action::ValueNodeConstSet::undo()
+{
+       //set_dirty(true);
+
+       value_node->set_value(old_value);       
+       
+       // Signal that a layer has been inserted
+       /*if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodeconstset.h
new file mode 100644 (file)
index 0000000..df57a60
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodeconstset.h
+**     \brief Template File
+**
+**     $Id: valuenodeconstset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODECONSTSET_H
+#define __SINFG_APP_ACTION_VALUENODECONSTSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode_const.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeConstSet :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_Const::Handle value_node;
+       sinfg::ValueBase        new_value;
+       sinfg::ValueBase        old_value;
+
+
+public:
+
+       ValueNodeConstSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.cpp
new file mode 100644 (file)
index 0000000..97a12e9
--- /dev/null
@@ -0,0 +1,196 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistinsert.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistinsert.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistinsert.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListInsert);
+ACTION_SET_NAME(Action::ValueNodeDynamicListInsert,"value_node_dynamic_list_insert");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListInsert,"Insert Item");
+ACTION_SET_TASK(Action::ValueNodeDynamicListInsert,"insert");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListInsert,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE|Action::CATEGORY_HIDDEN);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListInsert,-20);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListInsert,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListInsert,"$Id: valuenodedynamiclistinsert.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListInsert::ValueNodeDynamicListInsert()
+{
+       index=0;
+       time=0;
+       origin=0.5f;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListInsert::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       ret.push_back(ParamDesc("origin",Param::TYPE_REAL)
+               .set_local_name(_("Origin"))
+               .set_optional()
+       );
+       ret.push_back(ParamDesc("item",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode to insert"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListInsert::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListInsert::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               index=value_desc.get_index();
+
+               value_node_bline=ValueNode_BLine::Handle::cast_dynamic(value_desc.get_parent_value_node());
+
+               list_entry=value_node->create_list_entry(index,time,origin);
+               if(item)
+                       list_entry.value_node=item;
+               
+               assert(list_entry.value_node.rcount()==1);
+                               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+       if(name=="item" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               item=param.get_value_node();
+               if(item)
+                       list_entry.value_node=item;
+               
+               return true;
+       }
+       if(name=="origin" && param.get_type()==Param::TYPE_REAL)
+       {
+               origin=param.get_real();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListInsert::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListInsert::perform()
+{      
+       if(index>value_node->link_count())
+               index=value_node->link_count();
+       
+       value_node->add(list_entry,index);
+       assert(list_entry.value_node.rcount()>=2);
+       
+       // Signal that a layer has been inserted
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
+
+void
+Action::ValueNodeDynamicListInsert::undo()
+{
+       assert(list_entry.value_node.rcount()>=2);
+       value_node->erase((value_node->list.begin()+index)->value_node);
+       assert(list_entry.value_node.rcount()>=1);
+       
+       // Signal that a layer has been inserted
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsert.h
new file mode 100644 (file)
index 0000000..17b4482
--- /dev/null
@@ -0,0 +1,82 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistinsert.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistinsert.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTINSERT_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTINSERT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListInsert :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       sinfg::ValueNode_BLine::Handle value_node_bline;
+       sinfg::ValueNode_DynamicList::ListEntry list_entry;
+       sinfg::ValueNode::Handle item;
+       sinfg::Time time;
+       sinfg::Real origin;
+       int index;
+
+
+public:
+
+       ValueNodeDynamicListInsert();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.cpp
new file mode 100644 (file)
index 0000000..1351e85
--- /dev/null
@@ -0,0 +1,269 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistinsertsmart.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistinsertsmart.cpp,v 1.3 2005/01/17 05:20:08 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistinsertsmart.h"
+#include "valuenodedynamiclistinsert.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListInsertSmart);
+ACTION_SET_NAME(Action::ValueNodeDynamicListInsertSmart,"value_node_dynamic_list_insert_smart");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListInsertSmart,"Insert Item (Smart)");
+ACTION_SET_TASK(Action::ValueNodeDynamicListInsertSmart,"insert");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListInsertSmart,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListInsertSmart,-20);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListInsertSmart,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListInsertSmart,"$Id: valuenodedynamiclistinsertsmart.cpp,v 1.3 2005/01/17 05:20:08 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListInsertSmart::ValueNodeDynamicListInsertSmart()
+{
+       index=0;
+       time=0;
+       origin=0.5f;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListInsertSmart::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       ret.push_back(ParamDesc("origin",Param::TYPE_REAL)
+               .set_local_name(_("Origin"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListInsertSmart::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListInsertSmart::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               index=value_desc.get_index();
+                               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+       if(name=="origin" && param.get_type()==Param::TYPE_REAL)
+       {
+               origin=param.get_real();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListInsertSmart::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListInsertSmart::prepare()
+{      
+       //clear();
+       // HACK
+       if(!first_time())
+               return;
+       
+       // If we are in animate editing mode
+       if(get_edit_mode()&MODE_ANIMATE)
+       {
+               int index(ValueNodeDynamicListInsertSmart::index);
+
+               // In this case we need to first determine if there is
+               // a currently disabled item in the list that we can
+               // turn on. If not, then we need to go ahead and create one.
+               sinfg::info("ValueNodeDynamicListInsertSmart: index=%d",index);
+               sinfg::info("ValueNodeDynamicListInsertSmart: value_node->list.size()=%d",value_node->list.size());
+               if(value_node->list.size()<=index && index>0)
+                       sinfg::info("ValueNodeDynamicListInsertSmart: value_node->list[index-1].status_at_time(time)=%d",value_node->list[index-1].status_at_time(time));
+               
+               if(value_node->list.size()>=index && index>0 && !value_node->list[index-1].status_at_time(time))
+               {
+                       // Ok, we do not have to create a new
+                       // entry in the dynamic list after all.                 
+                       // However, we do need to set the
+                       // position and tangent of this point.
+                       ValueNode_DynamicList::ListEntry list_entry(value_node->create_list_entry(index,time,origin));
+                       ValueBase value((*list_entry.value_node)(time));
+                       index--;
+                       
+                       ValueDesc item_value_desc(value_node,index);
+
+                       Action::Handle action(Action::create("value_desc_set"));
+       
+                       if(!action)
+                               throw Error(_("Unable to find action value_desc_set (bug)"));
+                       
+                       action->set_param("edit_mode",get_edit_mode());
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("time",time);
+                       action->set_param("new_value",value);
+                       action->set_param("value_desc",ValueDesc(value_node,index));
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                       add_action(action);                     
+               }
+               else
+               {
+                       // Ok, not a big deal, we just need to
+                       // add a new item
+                       Action::Handle action(Action::create("value_node_dynamic_list_insert"));
+       
+                       if(!action)
+                               throw Error(_("Unable to find action (bug)"));
+                       
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("time",time);
+                       action->set_param("origin",origin);
+                       action->set_param("value_desc",ValueDesc(value_node,index));
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                       add_action(action);
+                       
+                       action=Action::create("activepoint_set_off");
+       
+                       if(!action)
+                               throw Error(_("Unable to find action \"activepoint_set_off\""));
+                       
+                       action->set_param("edit_mode",MODE_ANIMATE);
+                       action->set_param("canvas",get_canvas());
+                       action->set_param("canvas_interface",get_canvas_interface());
+                       action->set_param("time",Time::begin());
+                       action->set_param("origin",origin);
+                       action->set_param("value_desc",ValueDesc(value_node,index));
+                       
+                       if(!action->is_ready())
+                               throw Error(Error::TYPE_NOTREADY);
+       
+                       add_action(action);
+               }
+                       
+               // Now we set the activepoint up and then we'll be done
+               Action::Handle action(Action::create("activepoint_set_on"));
+
+               if(!action)
+                       throw Error(_("Unable to find action \"activepoint_set_on\""));
+               
+               action->set_param("edit_mode",get_edit_mode());
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("origin",origin);
+               action->set_param("value_desc",ValueDesc(value_node,index));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+               add_action(action);
+       }
+       else
+       {
+               Action::Handle action(Action::create("value_node_dynamic_list_insert"));
+
+               if(!action)
+                       throw Error(_("Unable to find action (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("origin",origin);
+               action->set_param("value_desc",ValueDesc(value_node,index));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+               add_action(action);     
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistinsertsmart.h
new file mode 100644 (file)
index 0000000..9d65b57
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistinsertsmart.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistinsertsmart.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTINSERTSMART_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTINSERTSMART_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListInsertSmart :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       sinfg::Time time;
+       sinfg::Real origin;
+       int index;
+
+
+public:
+
+       ValueNodeDynamicListInsertSmart();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.cpp
new file mode 100644 (file)
index 0000000..efedbec
--- /dev/null
@@ -0,0 +1,152 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistloop.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistloop.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistloop.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListLoop);
+ACTION_SET_NAME(Action::ValueNodeDynamicListLoop,"value_node_dynamic_list_loop");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListLoop,"Loop");
+ACTION_SET_TASK(Action::ValueNodeDynamicListLoop,"loop");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListLoop,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListLoop,0);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListLoop,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListLoop,"$Id: valuenodedynamiclistloop.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListLoop::ValueNodeDynamicListLoop()
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListLoop::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListLoop::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueNode::Handle value_node(x.find("value_node")->second.get_value_node());
+               if(!ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+                       return false;
+               if(ValueNode_DynamicList::Handle::cast_dynamic(value_node)->get_loop()==true)
+                       return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListLoop::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(param.get_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListLoop::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListLoop::perform()
+{      
+       old_loop_value=value_node->get_loop();
+       
+       if(old_loop_value==true)
+       {
+               set_dirty(false);
+               return;
+       }
+       set_dirty(true);
+       value_node->set_loop(true);
+               
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
+
+void
+Action::ValueNodeDynamicListLoop::undo()
+{
+       if(old_loop_value==value_node->get_loop())
+       {
+               set_dirty(false);
+               return;
+       }
+       set_dirty(true);
+       value_node->set_loop(old_loop_value);
+               
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistloop.h
new file mode 100644 (file)
index 0000000..3cc2a93
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistloop.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistloop.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTLOOP_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTLOOP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListLoop :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       bool old_loop_value;
+
+
+public:
+
+       ValueNodeDynamicListLoop();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.cpp
new file mode 100644 (file)
index 0000000..ed562dc
--- /dev/null
@@ -0,0 +1,152 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistremove.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListRemove);
+ACTION_SET_NAME(Action::ValueNodeDynamicListRemove,"value_node_dynamic_list_remove");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListRemove,"Remove Item");
+ACTION_SET_TASK(Action::ValueNodeDynamicListRemove,"remove");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListRemove,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE|Action::CATEGORY_HIDDEN);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListRemove,-19);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListRemove,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListRemove,"$Id: valuenodedynamiclistremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListRemove::ValueNodeDynamicListRemove()
+{
+       index=0;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListRemove::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+               
+               index=value_desc.get_index();
+               
+               return true;
+       }
+       
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListRemove::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListRemove::perform()
+{      
+       if(index>=value_node->link_count())
+               index=value_node->link_count()-1;
+
+       list_entry=value_node->list[index];
+       value_node->erase((value_node->list.begin()+index)->value_node);
+               
+       // Signal that a layer has been inserted
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
+
+void
+Action::ValueNodeDynamicListRemove::undo()
+{
+       value_node->add(list_entry,index);
+       
+       // Signal that a layer has been inserted
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremove.h
new file mode 100644 (file)
index 0000000..e340417
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistremove.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTREMOVE_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       sinfg::ValueNode_DynamicList::ListEntry list_entry;
+       int index;
+
+
+public:
+
+       ValueNodeDynamicListRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.cpp
new file mode 100644 (file)
index 0000000..ae05e5e
--- /dev/null
@@ -0,0 +1,187 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistremovesmart.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistremovesmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistremovesmart.h"
+#include "valuenodedynamiclistremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListRemoveSmart);
+ACTION_SET_NAME(Action::ValueNodeDynamicListRemoveSmart,"value_node_dynamic_list_remove_smart");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListRemoveSmart,"Remove Item (Smart)");
+ACTION_SET_TASK(Action::ValueNodeDynamicListRemoveSmart,"remove");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListRemoveSmart,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListRemoveSmart,-19);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListRemoveSmart,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListRemoveSmart,"$Id: valuenodedynamiclistremovesmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListRemoveSmart::ValueNodeDynamicListRemoveSmart()
+{
+       index=0;
+       time=0;
+       origin=0.5f;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListRemoveSmart::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+       ret.push_back(ParamDesc("origin",Param::TYPE_REAL)
+               .set_local_name(_("Origin"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListRemoveSmart::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListRemoveSmart::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               index=value_desc.get_index();
+                               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+       if(name=="origin" && param.get_type()==Param::TYPE_REAL)
+       {
+               origin=param.get_real();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListRemoveSmart::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListRemoveSmart::prepare()
+{      
+       clear();
+       
+       // If we are in animate editing mode
+       if(get_edit_mode()&MODE_ANIMATE)
+       {
+               Action::Handle action(Action::create("activepoint_set_off"));
+
+               if(!action)
+                       throw Error(_("Unable to find action (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("origin",origin);
+               action->set_param("value_desc",ValueDesc(value_node,index));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+               add_action(action);
+       }
+       else
+       {
+               Action::Handle action(Action::create("value_node_dynamic_list_remove"));
+
+               if(!action)
+                       throw Error(_("Unable to find action (bug)"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("time",time);
+               action->set_param("origin",origin);
+               action->set_param("value_desc",ValueDesc(value_node,index));
+               
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+
+               add_action(action);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistremovesmart.h
new file mode 100644 (file)
index 0000000..c07a61a
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistremovesmart.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistremovesmart.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTREMOVESMART_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTREMOVESMART_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListRemoveSmart :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       sinfg::Time time;
+       sinfg::Real origin;
+       int index;
+
+
+public:
+
+       ValueNodeDynamicListRemoveSmart();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.cpp
new file mode 100644 (file)
index 0000000..e3651a0
--- /dev/null
@@ -0,0 +1,163 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistinsert.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistrotateorder.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistrotateorder.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListRotateOrder);
+ACTION_SET_NAME(Action::ValueNodeDynamicListRotateOrder,"value_node_dynamic_list_rotate_order");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListRotateOrder,"Rotate Order");
+ACTION_SET_TASK(Action::ValueNodeDynamicListRotateOrder,"rotate");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListRotateOrder,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListRotateOrder,0);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListRotateOrder,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListRotateOrder,"$Id: valuenodedynamiclistrotateorder.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListRotateOrder::ValueNodeDynamicListRotateOrder()
+{
+       index=0;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListRotateOrder::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC)
+               .set_local_name(_("ValueDesc"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListRotateOrder::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueDesc value_desc(x.find("value_desc")->second.get_value_desc());
+               if(!value_desc.parent_is_value_node() || !ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()))
+                       return false;
+
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListRotateOrder::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC)
+       {
+               ValueDesc value_desc(param.get_value_desc());
+               
+               if(!value_desc.parent_is_value_node())
+                       return false;
+               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               index=value_desc.get_index();
+
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListRotateOrder::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListRotateOrder::prepare()
+{
+       clear();
+       
+       for(int i(0);i<(value_node->link_count()-index)%value_node->link_count();++i)
+       {
+               ValueDesc value_desc(value_node,value_node->link_count()-1-i);
+               ValueNode::Handle child(value_desc.get_value_node());
+
+
+               Action::Handle action(Action::create("value_node_dynamic_list_remove"));
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,value_node->link_count()-1));
+               
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+               
+               
+               action=Action::create("value_node_dynamic_list_insert");
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_desc",ValueDesc(value_node,0));
+               action->set_param("item",child);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+
+               
+               
+       
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistrotateorder.h
new file mode 100644 (file)
index 0000000..244542d
--- /dev/null
@@ -0,0 +1,75 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistrotateorder.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistrotateorder.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTROTATEORDER_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTROTATEORDER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListRotateOrder :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       int index;
+
+
+public:
+
+       ValueNodeDynamicListRotateOrder();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.cpp
new file mode 100644 (file)
index 0000000..4ba2ead
--- /dev/null
@@ -0,0 +1,154 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistunloop.cpp
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistunloop.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodedynamiclistunloop.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeDynamicListUnLoop);
+ACTION_SET_NAME(Action::ValueNodeDynamicListUnLoop,"value_node_dynamic_list_unloop");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeDynamicListUnLoop,"Unloop");
+ACTION_SET_TASK(Action::ValueNodeDynamicListUnLoop,"unloop");
+ACTION_SET_CATEGORY(Action::ValueNodeDynamicListUnLoop,Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeDynamicListUnLoop,0);
+ACTION_SET_VERSION(Action::ValueNodeDynamicListUnLoop,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeDynamicListUnLoop,"$Id: valuenodedynamiclistunloop.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeDynamicListUnLoop::ValueNodeDynamicListUnLoop()
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeDynamicListUnLoop::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeDynamicListUnLoop::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueNode::Handle value_node(x.find("value_node")->second.get_value_node());
+               if(!ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+                       return false;
+               if(ValueNode_DynamicList::Handle::cast_dynamic(value_node)->get_loop()==false)
+                       return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeDynamicListUnLoop::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {               
+               value_node=ValueNode_DynamicList::Handle::cast_dynamic(param.get_value_node());
+               
+               if(!value_node)
+                       return false;
+
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeDynamicListUnLoop::is_ready()const
+{
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeDynamicListUnLoop::perform()
+{      
+       old_loop_value=value_node->get_loop();
+       
+       if(old_loop_value==false)
+       {
+               set_dirty(false);
+               return;
+       }
+
+       set_dirty(true);
+       value_node->set_loop(false);
+               
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
+
+void
+Action::ValueNodeDynamicListUnLoop::undo()
+{
+       if(old_loop_value==value_node->get_loop())
+       {
+               set_dirty(false);
+               return;
+       }
+
+       set_dirty(true);
+       value_node->set_loop(old_loop_value);
+               
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodedynamiclistunloop.h
new file mode 100644 (file)
index 0000000..0abc884
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodedynamiclistunloop.h
+**     \brief Template File
+**
+**     $Id: valuenodedynamiclistunloop.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEDYNAMICLISTUNLOOP_H
+#define __SINFG_APP_ACTION_VALUENODEDYNAMICLISTUNLOOP_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/activepoint.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/valuenode_bline.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeDynamicListUnLoop :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_DynamicList::Handle value_node;
+       bool old_loop_value;
+
+
+public:
+
+       ValueNodeDynamicListUnLoop();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.cpp
new file mode 100644 (file)
index 0000000..7502a4e
--- /dev/null
@@ -0,0 +1,159 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodelinkconnect.cpp
+**     \brief Template File
+**
+**     $Id: valuenodelinkconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodelinkconnect.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeLinkConnect);
+ACTION_SET_NAME(Action::ValueNodeLinkConnect,"value_node_link_connect");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeLinkConnect,_("Connect ValueNode Link"));
+ACTION_SET_TASK(Action::ValueNodeLinkConnect,"connect");
+ACTION_SET_CATEGORY(Action::ValueNodeLinkConnect,Action::CATEGORY_LAYER|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeLinkConnect,0);
+ACTION_SET_VERSION(Action::ValueNodeLinkConnect,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeLinkConnect,"$Id: valuenodelinkconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeLinkConnect::ValueNodeLinkConnect():
+       index(-1)       // Initially set it to negative one so that we know when it has changed
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeLinkConnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("parent_value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Parent ValueNode"))
+       );
+
+       ret.push_back(ParamDesc("index",Param::TYPE_INTEGER)
+               .set_local_name(_("Index"))
+       );
+
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode to be connected"))
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeLinkConnect::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueNodeLinkConnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="parent_value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               parent_value_node=LinkableValueNode::Handle::cast_dynamic(param.get_value_node());
+               
+               return static_cast<bool>(parent_value_node);
+       }
+
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               new_value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       if(name=="index" && param.get_type()==Param::TYPE_INTEGER)
+       {
+               index=param.get_integer();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeLinkConnect::is_ready()const
+{
+       if(!new_value_node || !parent_value_node || index==-1)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeLinkConnect::perform()
+{
+       if(parent_value_node->link_count()<=index)
+               throw Error(_("Bad index, too big. LinkCount=%d, Index=%d"),parent_value_node->link_count(),index);             
+               
+       old_value_node=parent_value_node->get_link(index);
+
+       if(!parent_value_node->set_link(index,new_value_node))
+               throw Error(_("Parent would not accept link"));
+       
+       /*set_dirty(true);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(parent_value_node);
+       }*/
+}
+
+void
+Action::ValueNodeLinkConnect::undo()
+{
+       if(parent_value_node->link_count()<=index)
+               throw Error(_("Bad index, too big. LinkCount=%d, Index=%d"),parent_value_node->link_count(),index);             
+               
+       if(!parent_value_node->set_link(index,old_value_node))
+               throw Error(_("Parent would not accept old link"));
+       
+       /*set_dirty(true);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(parent_value_node);
+       }*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkconnect.h
new file mode 100644 (file)
index 0000000..ce7663c
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodelinkconnect.h
+**     \brief Template File
+**
+**     $Id: valuenodelinkconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODELINKCONNECT_H
+#define __SINFG_APP_ACTION_VALUENODELINKCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeLinkConnect :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::LinkableValueNode::Handle        parent_value_node;
+       sinfg::ValueNode::Handle        new_value_node;
+       sinfg::ValueNode::Handle        old_value_node;
+       int index;
+
+
+public:
+
+       ValueNodeLinkConnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.cpp
new file mode 100644 (file)
index 0000000..90e0f1b
--- /dev/null
@@ -0,0 +1,170 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodelinkdisconnect.cpp
+**     \brief Template File
+**
+**     $Id: valuenodelinkdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodelinkdisconnect.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/valuenode_const.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeLinkDisconnect);
+ACTION_SET_NAME(Action::ValueNodeLinkDisconnect,"value_node_link_disconnect");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeLinkDisconnect,_("Disconnect ValueNode Link"));
+ACTION_SET_TASK(Action::ValueNodeLinkDisconnect,"disconnect");
+ACTION_SET_CATEGORY(Action::ValueNodeLinkDisconnect,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeLinkDisconnect,0);
+ACTION_SET_VERSION(Action::ValueNodeLinkDisconnect,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeLinkDisconnect,"$Id: valuenodelinkdisconnect.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeLinkDisconnect::ValueNodeLinkDisconnect():
+       index(-1),      // Initially set it to negative one so that we know when it has changed
+       time(0)
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeLinkDisconnect::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("parent_value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Parent ValueNode"))
+       );
+
+       ret.push_back(ParamDesc("index",Param::TYPE_INTEGER)
+               .set_local_name(_("Index"))
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::ValueNodeLinkDisconnect::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueNodeLinkDisconnect::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="parent_value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               parent_value_node=LinkableValueNode::Handle::cast_dynamic(param.get_value_node());
+               
+               return static_cast<bool>(parent_value_node);
+       }
+
+       if(name=="index" && param.get_type()==Param::TYPE_INTEGER)
+       {
+               index=param.get_integer();
+               
+               return true;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME)
+       {
+               time=param.get_time();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeLinkDisconnect::is_ready()const
+{
+       if(!parent_value_node || index==-1)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeLinkDisconnect::perform()
+{
+       if(parent_value_node->link_count()<=index)
+               throw Error(_("Bad index, too big. LinkCount=%d, Index=%d"),parent_value_node->link_count(),index);             
+               
+       old_value_node=parent_value_node->get_link(index);
+
+       if(!parent_value_node->set_link(index,ValueNode_Const::create((*old_value_node)(time))))
+               throw Error(_("Parent would not accept link"));
+       
+       /*
+       if(get_canvas()->get_time()!=time)
+               set_dirty(true);
+       else
+               set_dirty(false);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(parent_value_node);
+       }
+       */
+}
+
+void
+Action::ValueNodeLinkDisconnect::undo()
+{
+       if(parent_value_node->link_count()<=index)
+               throw Error(_("Bad index, too big. LinkCount=%d, Index=%d"),parent_value_node->link_count(),index);             
+               
+       if(!parent_value_node->set_link(index,old_value_node))
+               throw Error(_("Parent would not accept old link"));
+       
+       /*if(get_canvas()->get_time()!=time)
+               set_dirty(true);
+       else
+               set_dirty(false);
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(parent_value_node);
+       }*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodelinkdisconnect.h
new file mode 100644 (file)
index 0000000..19b2865
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodelinkdisconnect.h
+**     \brief Template File
+**
+**     $Id: valuenodelinkdisconnect.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODELINKDISCONNECT_H
+#define __SINFG_APP_ACTION_VALUENODELINKDISCONNECT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeLinkDisconnect :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::LinkableValueNode::Handle        parent_value_node;
+       int index;
+       sinfg::ValueNode::Handle        old_value_node;
+       sinfg::Time time;
+
+public:
+
+       ValueNodeLinkDisconnect();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.cpp
new file mode 100644 (file)
index 0000000..2dbb176
--- /dev/null
@@ -0,0 +1,176 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenoderemove.cpp
+**     \brief Template File
+**
+**     $Id: valuenoderemove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenoderemove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeRemove);
+ACTION_SET_NAME(Action::ValueNodeRemove,"value_node_remove");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeRemove,_("Unexport"));
+ACTION_SET_TASK(Action::ValueNodeRemove,"remove");
+ACTION_SET_CATEGORY(Action::ValueNodeRemove,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeRemove,0);
+ACTION_SET_VERSION(Action::ValueNodeRemove,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeRemove,"$Id: valuenoderemove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeRemove::ValueNodeRemove()
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueNodeRemove::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               ValueNode::Handle value_node=x.find("value_node")->second.get_value_node();
+               if(!value_node->is_exported())
+                       return false;
+//             if(value_node->rcount()!=1)
+//                     return false;
+               return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=param.get_value_node();
+               
+               if(value_node && !value_node->is_exported())
+               {
+                       sinfg::error("Action::ValueNodeRemove::set_param(): ValueBase node not exported!");
+                       value_node=0;
+               }
+               
+               return (bool)value_node;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeRemove::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Action::ValueNodeRemove::is_ready(): ValueNode not set!");
+
+       if(!value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeRemove::perform()
+{      
+//     if(value_node->rcount()!=1)
+//             throw Error(_("ValueNode is still being used by something"));
+
+       old_name=value_node->get_id();
+       parent_canvas=value_node->get_parent_canvas();
+       parent_canvas->remove_value_node(value_node);
+
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_deleted()(value_node);
+       }
+       
+       //throw Error(_("Not yet implemented"));
+/*
+       assert(value_node->is_exported());
+
+       if(get_canvas()->value_node_list().count(new_name))
+               throw Error(_("A ValueNode with this ID already exists in this canvas"));
+       
+       old_name=value_node->get_id();
+
+       value_node->set_id(new_name);   
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+*/
+}
+
+void
+Action::ValueNodeRemove::undo()
+{
+       parent_canvas->add_value_node(value_node,old_name);
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_added()(value_node);
+       }
+       
+       //throw Error(_("Not yet implemented"));
+/*
+       assert(value_node->is_exported());
+
+       if(get_canvas()->value_node_list().count(old_name))
+               throw Error(_("A ValueNode with the old ID already exists in this canvas (BUG)"));
+       
+       value_node->set_id(old_name);   
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenoderemove.h
new file mode 100644 (file)
index 0000000..94207bd
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenoderemove.h
+**     \brief Template File
+**
+**     $Id: valuenoderemove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEREMOVE_H
+#define __SINFG_APP_ACTION_VALUENODEREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode_const.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode::Handle value_node;
+       sinfg::Canvas::Handle parent_canvas;
+       sinfg::String new_name;
+       sinfg::String old_name;
+
+
+public:
+
+       ValueNodeRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.cpp
new file mode 100644 (file)
index 0000000..1a6bd1a
--- /dev/null
@@ -0,0 +1,164 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenoderename.cpp
+**     \brief Template File
+**
+**     $Id: valuenoderename.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenoderename.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeRename);
+ACTION_SET_NAME(Action::ValueNodeRename,"value_node_rename");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeRename,_("Rename ValueNode"));
+ACTION_SET_TASK(Action::ValueNodeRename,"rename");
+ACTION_SET_CATEGORY(Action::ValueNodeRename,Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::ValueNodeRename,0);
+ACTION_SET_VERSION(Action::ValueNodeRename,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeRename,"$Id: valuenoderename.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeRename::ValueNodeRename()
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeRename::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode_Const"))
+       );
+
+       ret.push_back(ParamDesc("name",Param::TYPE_STRING)
+               .set_local_name(_("Name"))
+               .set_desc(_("The new name of the ValueNode"))
+               .set_user_supplied()
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueNodeRename::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               if(x.find("value_node")->second.get_value_node()->is_exported())
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::ValueNodeRename::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=param.get_value_node();
+               
+               if(value_node && !value_node->is_exported())
+               {
+                       sinfg::error("Action::ValueNodeRename::set_param(): ValueBase node not exported!");
+                       value_node=0;
+               }
+               
+               return (bool)value_node;
+       }
+
+       if(name=="name" && param.get_type()==Param::TYPE_STRING)
+       {
+               new_name=param.get_string();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeRename::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Action::ValueNodeRename::is_ready(): ValueNode not set!");
+
+       if(new_name.empty())
+               sinfg::error("Action::ValueNodeRename::is_ready(): ValueNode not set!");
+
+       if(!value_node || new_name.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeRename::perform()
+{      
+       assert(value_node->is_exported());
+
+       if(get_canvas()->value_node_list().count(new_name))
+               throw Error(_("A ValueNode with this ID already exists in this canvas"));
+       
+       old_name=value_node->get_id();
+
+       value_node->set_id(new_name);   
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+}
+
+void
+Action::ValueNodeRename::undo()
+{
+       assert(value_node->is_exported());
+
+       if(get_canvas()->value_node_list().count(old_name))
+               throw Error(_("A ValueNode with the old ID already exists in this canvas (BUG)"));
+       
+       value_node->set_id(old_name);   
+       
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenoderename.h
new file mode 100644 (file)
index 0000000..026eee7
--- /dev/null
@@ -0,0 +1,76 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenoderename.h
+**     \brief Template File
+**
+**     $Id: valuenoderename.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODERENAME_H
+#define __SINFG_APP_ACTION_VALUENODERENAME_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode_const.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeRename :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode::Handle value_node;
+       sinfg::String new_name;
+       sinfg::String old_name;
+
+
+public:
+
+       ValueNodeRename();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.cpp b/synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.cpp
new file mode 100644 (file)
index 0000000..f9a0e25
--- /dev/null
@@ -0,0 +1,222 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodereplace.cpp
+**     \brief Template File
+**
+**     $Id: valuenodereplace.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "valuenodereplace.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::ValueNodeReplace);
+ACTION_SET_NAME(Action::ValueNodeReplace,"value_node_replace");
+ACTION_SET_LOCAL_NAME(Action::ValueNodeReplace,"Replace ValueNode");
+ACTION_SET_TASK(Action::ValueNodeReplace,"replace");
+ACTION_SET_CATEGORY(Action::ValueNodeReplace,Action::CATEGORY_VALUENODE|Action::CATEGORY_DRAG);
+ACTION_SET_PRIORITY(Action::ValueNodeReplace,0);
+ACTION_SET_VERSION(Action::ValueNodeReplace,"0.0");
+ACTION_SET_CVS_ID(Action::ValueNodeReplace,"$Id: valuenodereplace.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+void swap_guid(const ValueNode::Handle& a,const ValueNode::Handle& b)
+{
+       GUID old_a(a->get_guid());
+       a->set_guid(GUID());
+
+       GUID old_b(b->get_guid());
+       b->set_guid(GUID());
+       
+       a->set_guid(old_b);
+       b->set_guid(old_a);
+}
+
+/* === M E T H O D S ======================================================= */
+
+Action::ValueNodeReplace::ValueNodeReplace():
+       is_undoable(true)
+{
+}
+
+Action::ParamVocab
+Action::ValueNodeReplace::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("dest",Param::TYPE_VALUENODE)
+               .set_local_name(_("Destination ValueNode"))
+               .set_desc(_("ValueNode to replaced"))
+       );
+
+       ret.push_back(ParamDesc("src",Param::TYPE_VALUENODE)
+               .set_local_name(_("Source ValueNode"))
+               .set_desc(_("ValueNode that will replace the destination"))
+       );
+       
+       return ret;
+}
+
+bool
+Action::ValueNodeReplace::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::ValueNodeReplace::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="dest" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               dest_value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       if(name=="src" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               src_value_node=param.get_value_node();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::ValueNodeReplace::is_ready()const
+{
+       if(!dest_value_node || !src_value_node)
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::ValueNodeReplace::perform()
+{
+       set_dirty(true);
+
+       if(dest_value_node == src_value_node)
+               throw Error(_("Attempted to replace valuenode with itself"));
+
+       if(dest_value_node->get_type() != src_value_node->get_type())
+               throw Error(_("You cannot replace ValueNodes with different types!"));
+       
+       is_undoable=true;
+       
+       if(!src_value_node->is_exported())
+       {
+               src_value_node->set_id(dest_value_node->get_id());
+               src_value_node->set_parent_canvas(dest_value_node->get_parent_canvas());
+
+               ValueNode::RHandle value_node(src_value_node);
+               
+               if(!value_node.runique() && value_node.rcount()>1)
+                       is_undoable=false;      // !!!
+       }
+       else
+               is_undoable=false;      // !!!
+       
+       if(!is_undoable)
+               sinfg::warning("ValueNodeReplace: Circumstances make undoing this action impossible at the current time. :(");
+       
+       ValueNode::RHandle value_node(dest_value_node);
+       
+       if(value_node.runique() || value_node.rcount()<=1)
+               throw Error(_("Nothing to replace."));
+       
+       int replacements;
+               
+       replacements=value_node->replace(src_value_node);
+       assert(replacements);
+       if(!replacements)
+               throw Error(_("Action Failure. This is a bug. Please report it."));
+       swap_guid(dest_value_node,src_value_node);
+       
+       //src_value_node->parent_set.swap(dest_value_node->parent_set);
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_replaced()(dest_value_node,src_value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       
+}
+
+void
+Action::ValueNodeReplace::undo()
+{
+       if(!is_undoable)
+               throw Error(_("This action cannot be undone under these circumstances."));
+               
+       set_dirty(true);
+
+       if(dest_value_node == src_value_node)
+               throw Error(_("Attempted to replace valuenode with itself"));
+
+       if(dest_value_node->get_type() != src_value_node->get_type())
+               throw Error(_("You cannot replace ValueNodes with different types!"));
+               
+       ValueNode::RHandle value_node(src_value_node);
+       
+       if(value_node.runique() || value_node.rcount()<=1)
+               throw Error(_("Nothing to replace."));
+       
+       int replacements;
+       
+       replacements=value_node->replace(dest_value_node);
+       assert(replacements);
+       if(!replacements)
+               throw Error(_("Action Failure. This is a bug. Please report it."));
+       swap_guid(dest_value_node,src_value_node);
+
+       //src_value_node->parent_set.swap(dest_value_node->parent_set);
+       
+       sinfg::info(get_name()+_(": (Undo) ")+strprintf("Replaced %d ValueNode instances",replacements));
+
+       src_value_node->set_id(String());
+       src_value_node->set_parent_canvas(0);
+       
+       // Signal that a layer has been inserted
+       if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_replaced()(src_value_node,dest_value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");
+       
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.h b/synfig-studio/trunk/src/sinfgapp/actions/valuenodereplace.h
new file mode 100644 (file)
index 0000000..3395e20
--- /dev/null
@@ -0,0 +1,75 @@
+/* === S I N F G =========================================================== */
+/*!    \file valuenodereplace.h
+**     \brief Template File
+**
+**     $Id: valuenodereplace.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_VALUENODEREPLACE_H
+#define __SINFG_APP_ACTION_VALUENODEREPLACE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/layer.h>
+#include <sinfgapp/action.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class ValueNodeReplace :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode::Handle src_value_node;
+       sinfg::ValueNode::Handle dest_value_node;
+       bool is_undoable;
+
+public:
+
+       ValueNodeReplace();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/waypointadd.cpp
new file mode 100644 (file)
index 0000000..87105fb
--- /dev/null
@@ -0,0 +1,213 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointadd.cpp
+**     \brief Template File
+**
+**     $Id: waypointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "waypointadd.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::WaypointAdd);
+ACTION_SET_NAME(Action::WaypointAdd,"waypoint_add");
+ACTION_SET_LOCAL_NAME(Action::WaypointAdd,"Add Waypoint");
+ACTION_SET_TASK(Action::WaypointAdd,"add");
+ACTION_SET_CATEGORY(Action::WaypointAdd,Action::CATEGORY_WAYPOINT);
+ACTION_SET_PRIORITY(Action::WaypointAdd,0);
+ACTION_SET_VERSION(Action::WaypointAdd,"0.0");
+ACTION_SET_CVS_ID(Action::WaypointAdd,"$Id: waypointadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::WaypointAdd::WaypointAdd()
+{
+       waypoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::WaypointAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Destination ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
+               .set_local_name(_("New Waypoint"))
+               .set_desc(_("Waypoint to be added"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_desc(_("Time where waypoint is to be added"))
+               .set_optional()
+       );
+
+       return ret;
+}
+
+bool
+Action::WaypointAdd::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               if(!ValueNode_Animated::Handle::cast_dynamic(x.find("value_node")->second.get_value_node()))
+                       return false;
+
+               // We need either a waypoint or a time.
+               if(x.count("waypoint") || x.count("time"))
+                       return true;
+       }
+       return false;
+}
+
+bool
+Action::WaypointAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
+               if(time_set)
+                       calc_waypoint();
+               
+               return static_cast<bool>(value_node);
+       }
+       if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT && !time_set)
+       {
+               waypoint=param.get_waypoint();
+               
+               return true;
+       }
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && waypoint.get_time()==Time::begin()-1)
+       {
+               waypoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_waypoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::WaypointAdd::is_ready()const
+{
+       if(!value_node || waypoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a waypoint. In this case, we need to calculate the value
+// of the waypoint
+void
+Action::WaypointAdd::calc_waypoint()
+{      
+       Time time=waypoint.get_time();
+       Waypoint original(waypoint);
+       waypoint=value_node->new_waypoint_at_time(time);        
+       waypoint.mimic(original);
+       waypoint.set_before(sinfgapp::Main::get_interpolation());
+       waypoint.set_after(sinfgapp::Main::get_interpolation());
+
+/*
+       ValueNode_Animated::WaypointList &waypoint_list(value_node->waypoint_list());
+       ValueNode_Animated::WaypointList::iterator iter;
+       
+       if(waypoint_list.empty())
+       {
+               waypoint.set_value((*value_node)(time));
+               return;
+       }
+
+       ValueNode_Animated::WaypointList::iterator closest=waypoint_list.begin();
+               
+       for(iter=waypoint_list.begin();iter!=waypoint_list.end();++iter)
+       {
+               const Real dist(abs(iter->get_time()-time));
+               if(dist<abs(closest->get_time()-time))
+                       closest=iter;
+       }
+       if(!closest->is_static())
+               waypoint.set_value_node(closest->get_value_node());
+       else
+               waypoint.set_value((*value_node)(time));
+       */
+}
+
+void
+Action::WaypointAdd::perform()
+{              
+       try { value_node->find(waypoint.get_time()); throw Error(_("A Waypoint already exists at this point in time (%s)"),waypoint.get_time().get_string().c_str());}
+       catch(sinfg::Exception::NotFound) { }   
+
+       try { if(value_node->find(waypoint)!=value_node->waypoint_list().end()) throw Error(_("This waypoint is already in the ValueNode"));}
+       catch(sinfg::Exception::NotFound) { }   
+       
+       value_node->add(waypoint);
+       
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
+
+void
+Action::WaypointAdd::undo()
+{
+       value_node->erase(waypoint);
+       
+       value_node->changed();
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointadd.h b/synfig-studio/trunk/src/sinfgapp/actions/waypointadd.h
new file mode 100644 (file)
index 0000000..720bf17
--- /dev/null
@@ -0,0 +1,82 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointadd.h
+**     \brief Template File
+**
+**     $Id: waypointadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_WAYPOINTADD_H
+#define __SINFG_APP_ACTION_WAYPOINTADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/waypoint.h>
+#include <sinfg/valuenode_animated.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class WaypointAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::Waypoint waypoint;
+       
+       bool time_overwrite;
+       sinfg::Waypoint overwritten_wp;
+
+       sinfg::ValueNode_Animated::Handle value_node;
+       bool time_set;
+
+       void calc_waypoint();
+
+public:
+
+       WaypointAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointremove.cpp b/synfig-studio/trunk/src/sinfgapp/actions/waypointremove.cpp
new file mode 100644 (file)
index 0000000..fd8154c
--- /dev/null
@@ -0,0 +1,188 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointremove.cpp
+**     \brief Template File
+**
+**     $Id: waypointremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "waypointremove.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::WaypointRemove);
+ACTION_SET_NAME(Action::WaypointRemove,"waypoint_remove");
+ACTION_SET_LOCAL_NAME(Action::WaypointRemove,"Remove Waypoint");
+ACTION_SET_TASK(Action::WaypointRemove,"remove");
+ACTION_SET_CATEGORY(Action::WaypointRemove,Action::CATEGORY_WAYPOINT);
+ACTION_SET_PRIORITY(Action::WaypointRemove,0);
+ACTION_SET_VERSION(Action::WaypointRemove,"0.0");
+ACTION_SET_CVS_ID(Action::WaypointRemove,"$Id: waypointremove.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::WaypointRemove::WaypointRemove()
+{
+       waypoint.set_time(Time::begin()-1);
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::WaypointRemove::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
+               .set_local_name(_("Waypoint"))
+               .set_desc(_("Waypoint to be Removed"))
+       );
+
+       return ret;
+}
+
+bool
+Action::WaypointRemove::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::WaypointRemove::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
+               
+               return static_cast<bool>(value_node);
+       }
+       if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT)
+       {
+               waypoint=param.get_waypoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::WaypointRemove::is_ready()const
+{
+       if(!value_node || waypoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::WaypointRemove::perform()
+{      
+       WaypointList::iterator iter(value_node->find(waypoint));
+
+       if((UniqueID)*iter!=(UniqueID)waypoint)
+               throw Error(_("UniqueID mismatch, iter=%d, waypoint=%d"),iter->get_uid(),waypoint.get_uid());
+
+       if(iter->get_time()!=waypoint.get_time())
+               throw Error(_("Time mismatch iter=%s, waypoint=%s"),iter->get_time().get_string().c_str(),waypoint.get_time().get_string().c_str());
+       
+       waypoint=*iter;
+       
+       value_node->erase(waypoint);
+
+       // In this case, we need to convert this to a
+       // constant value node
+       if(value_node->waypoint_list().size()==0)
+       {
+               if(!value_node_ref)
+               {
+                       value_node_ref=waypoint.get_value_node();
+                       if(!value_node_ref)
+                               throw Error(_("Unable to create ValueNode_Reference"));
+               }
+               
+               value_node->replace(value_node_ref);
+               value_node->waypoint_list().clear();
+               
+               if(get_canvas_interface())
+               {
+                       get_canvas_interface()->signal_value_node_replaced()(value_node,value_node_ref);
+               }
+       }
+
+       value_node->changed();
+}
+
+void
+Action::WaypointRemove::undo()
+{
+       if(value_node_ref)
+       {
+               if(value_node->waypoint_list().size()!=0)
+                       throw Error(_("This animated value node should be empty, but for some reason it isn't. This is a bug. (1)"));
+               
+               value_node_ref->replace(value_node);
+               
+               waypoint.set_value_node(value_node_ref);
+               
+               if(get_canvas_interface())
+                       get_canvas_interface()->signal_value_node_replaced()(value_node_ref,value_node);
+
+               if(value_node->waypoint_list().size()!=0)
+                       throw Error(_("This animated value node should be empty, but for some reason it isn't. This is a bug. (2)"));
+       }
+
+       if(value_node->waypoint_list().size()!=0)
+       {
+               try { value_node->find(waypoint.get_time()); throw Error(_("A Waypoint already exists at this point in time"));}
+               catch(sinfg::Exception::NotFound) { }   
+               
+               try { if(value_node->find(waypoint)!=value_node->waypoint_list().end()) throw Error(_("This waypoint is already in the ValueNode"));}
+               catch(sinfg::Exception::NotFound) { }   
+       }
+       
+       value_node->add(waypoint);
+       
+/*_if(get_canvas_interface())
+       {
+               get_canvas_interface()->signal_value_node_changed()(value_node);
+       }
+       else sinfg::warning("CanvasInterface not set on action");*/
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointremove.h b/synfig-studio/trunk/src/sinfgapp/actions/waypointremove.h
new file mode 100644 (file)
index 0000000..8a161b0
--- /dev/null
@@ -0,0 +1,77 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointremove.h
+**     \brief Template File
+**
+**     $Id: waypointremove.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_WAYPOINTREMOVE_H
+#define __SINFG_APP_ACTION_WAYPOINTREMOVE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/waypoint.h>
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_reference.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class WaypointRemove :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+
+       sinfg::ValueNode_Animated::Handle value_node;
+       sinfg::ValueNode::Handle value_node_ref;
+       sinfg::Waypoint waypoint;
+
+public:
+
+       WaypointRemove();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointset.cpp b/synfig-studio/trunk/src/sinfgapp/actions/waypointset.cpp
new file mode 100644 (file)
index 0000000..4ee92f4
--- /dev/null
@@ -0,0 +1,266 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointset.cpp
+**     \brief Template File
+**
+**     $Id: waypointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "waypointset.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::WaypointSet);
+ACTION_SET_NAME(Action::WaypointSet,"waypoint_set");
+ACTION_SET_LOCAL_NAME(Action::WaypointSet,"Set Waypoint");
+ACTION_SET_TASK(Action::WaypointSet,"set");
+ACTION_SET_CATEGORY(Action::WaypointSet,Action::CATEGORY_WAYPOINT);
+ACTION_SET_PRIORITY(Action::WaypointSet,0);
+ACTION_SET_VERSION(Action::WaypointSet,"0.0");
+ACTION_SET_CVS_ID(Action::WaypointSet,"$Id: waypointset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::WaypointSet::WaypointSet()
+{
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::WaypointSet::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Destination ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
+               .set_local_name(_("Waypoint"))
+               .set_desc(_("Waypoint to be changed"))
+               .set_supports_multiple()
+       );
+
+       return ret;
+}
+
+bool
+Action::WaypointSet::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::WaypointSet::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
+               
+               return static_cast<bool>(value_node);
+       }
+       if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT)
+       {
+               //NOTE: at the moment there is no error checking for multiple sets!!!
+               waypoints.push_back(param.get_waypoint());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::WaypointSet::is_ready()const
+{
+       if(!value_node || waypoints.empty())
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::WaypointSet::perform()
+{      
+       WaypointList::iterator iter;
+
+#if 1  
+       vector<WaypointList::iterator>  iters;
+       vector<Waypoint>::iterator i = waypoints.begin(), end = waypoints.end();        
+       
+       for(; i != end; ++i)
+       {
+               try { iters.push_back(value_node->find(*i)); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       throw Error(_("Unable to find waypoint"));
+               }
+       }
+       
+       //check to see which valuenodes are going to override because of the time...
+       ValueNode_Animated::findresult timeiter;
+       
+       for(i = waypoints.begin(); i != end; ++i)
+       {
+               timeiter = value_node->find_time(i->get_time());
+               
+               bool candelete = timeiter.second;
+       
+               //we only want to track overwrites (not waypoints that are also being modified)
+               if(candelete)
+               {
+                       for(vector<WaypointList::iterator>::iterator ii = iters.begin(); ii != iters.end(); ++ii)
+                       {
+                               if(timeiter.first == *ii)
+                               {
+                                       candelete = false;
+                                       break;
+                               }
+                       }
+               }
+               
+               //if we can still delete it after checking, record it, and then remove them all later
+               if(candelete)
+               {
+                       Waypoint w = *timeiter.first;
+                       overwritten_waypoints.push_back(w);
+               }
+       }
+       
+       //overwrite all the valuenodes we're supposed to set
+       {
+               i = waypoints.begin();
+               for(vector<WaypointList::iterator>::iterator ii = iters.begin(); ii != iters.end() && i != end; ++ii, ++i)
+               {
+                       old_waypoints.push_back(**ii);
+                       **ii = *i; //set the point to the corresponding point in the normal waypoint list
+               }
+       }
+       
+       //remove all the points we're supposed to be overwritting
+       {
+               vector<Waypoint>::iterator      oi = overwritten_waypoints.begin(),
+                                                                       oend = overwritten_waypoints.end();
+               for(; oi != oend; ++oi)
+               {
+                       value_node->erase(*oi);
+               }
+       }
+
+#else
+       try { iter=value_node->find(waypoint); }
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find waypoint"));
+       }
+
+       //find the value at the old time before we replace it
+       ValueNode_Animated::findresult timeiter;
+       timeiter = value_node->find_time(waypoint.get_time());
+       
+       //we only want to track overwrites (not inplace modifications)
+       if(timeiter.second && waypoint.get_uid() == timeiter.first->get_uid())
+       {
+               timeiter.second = false;                        
+       }
+               
+       //copy and overwrite
+       old_waypoint=*iter;
+       *iter=waypoint;
+       
+       //if we've found a unique one then we need to erase it, but store it first
+       if(timeiter.second)
+       {
+               time_overwrite = true;
+               overwritten_wp = *timeiter.first;
+               
+               value_node->erase(overwritten_wp);
+       }
+#endif
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
+
+void
+Action::WaypointSet::undo()
+{
+       WaypointList::iterator iter;
+       
+#if 1
+       vector<Waypoint>::iterator i = old_waypoints.begin(), end = old_waypoints.end();        
+       
+       for(; i != end; ++i)
+       {
+               try { iter = value_node->find(*i); }
+               catch(sinfg::Exception::NotFound)
+               {
+                       throw Error(_("Unable to find waypoint"));
+               }
+               
+               //overwrite with old one
+               *iter = *i;
+       }
+               
+       //add back in all the points that we removed before...
+       {
+               vector<Waypoint>::iterator      oi = overwritten_waypoints.begin(),
+                                                                       oend = overwritten_waypoints.end();
+               for(; oi != oend; ++oi)
+               {
+                       value_node->add(*oi);
+               }
+       }
+
+#else
+       try { iter=value_node->find(old_waypoint); }
+       catch(sinfg::Exception::NotFound)
+       {
+               throw Error(_("Unable to find waypoint"));
+       }       
+
+       *iter=old_waypoint;
+       
+       if(time_overwrite)
+       {
+               value_node->add(overwritten_wp);
+       }
+#endif
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointset.h b/synfig-studio/trunk/src/sinfgapp/actions/waypointset.h
new file mode 100644 (file)
index 0000000..e0e4bda
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointset.h
+**     \brief Template File
+**
+**     $Id: waypointset.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_WAYPOINTSET_H
+#define __SINFG_APP_ACTION_WAYPOINTSET_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/waypoint.h>
+#include <sinfg/valuenode_animated.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class WaypointSet :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+       
+       sinfg::ValueNode_Animated::Handle value_node;
+       
+       std::vector<sinfg::Waypoint> waypoints;
+       std::vector<sinfg::Waypoint> old_waypoints;     
+
+       std::vector<sinfg::Waypoint> overwritten_waypoints;
+
+public:
+
+       WaypointSet();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.cpp b/synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.cpp
new file mode 100644 (file)
index 0000000..a110bb0
--- /dev/null
@@ -0,0 +1,467 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointsetsmart.cpp
+**     \brief Template File
+**
+**     $Id: waypointsetsmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "waypointsetsmart.h"
+#include "valuenodelinkconnect.h"
+#include "valuenodereplace.h"
+
+#include "waypointset.h"
+#include "waypointadd.h"
+
+#include "valuedescconnect.h"
+#include <sinfgapp/canvasinterface.h>
+#include <sinfg/exception.h>
+#include <sinfgapp/main.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::WaypointSetSmart);
+ACTION_SET_NAME(Action::WaypointSetSmart,"waypoint_set_smart");
+ACTION_SET_LOCAL_NAME(Action::WaypointSetSmart,"Connect");
+ACTION_SET_TASK(Action::WaypointSetSmart,"set");
+ACTION_SET_CATEGORY(Action::WaypointSetSmart,Action::CATEGORY_WAYPOINT|Action::CATEGORY_VALUEDESC|Action::CATEGORY_VALUENODE);
+ACTION_SET_PRIORITY(Action::WaypointSetSmart,0);
+ACTION_SET_VERSION(Action::WaypointSetSmart,"0.0");
+ACTION_SET_CVS_ID(Action::WaypointSetSmart,"$Id: waypointsetsmart.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+
+/*#ifdef DEBUGPOINT
+#undef DEBUGPOINT
+#endif
+#define DEBUGPOINT()
+*/
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::WaypointSetSmart::WaypointSetSmart()
+{
+       waypoint.set_time(Time::begin()-1);
+       time_set=false;
+       set_dirty(true);
+}
+
+Action::ParamVocab
+Action::WaypointSetSmart::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Destination ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
+               .set_local_name(_("New Waypoint"))
+               .set_desc(_("Waypoint to be added"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("waypoint_model",Param::TYPE_WAYPOINTMODEL)
+               .set_local_name(_("Waypoint Model"))
+               .set_optional()
+       );
+
+       ret.push_back(ParamDesc("time",Param::TYPE_TIME)
+               .set_local_name(_("Time"))
+               .set_desc(_("Time where waypoint is to be added"))
+               .set_optional()
+       );
+       
+       return ret;
+}
+
+bool
+Action::WaypointSetSmart::is_canidate(const ParamList &x)
+{
+       if(canidate_check(get_param_vocab(),x))
+       {
+               if(!ValueNode_Animated::Handle::cast_dynamic(x.find("value_node")->second.get_value_node()))
+                       return false;
+               // We need either a waypoint or a time.
+               if(x.count("waypoint") || x.count("time"))
+                       return true;
+               return false;
+       }
+       return false;
+}
+
+bool
+Action::WaypointSetSmart::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
+               DEBUGPOINT();
+               if(time_set)
+                       calc_waypoint();
+               
+               return static_cast<bool>(value_node);
+       }
+       if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT && !time_set)
+       {
+               waypoint=param.get_waypoint();
+               DEBUGPOINT();
+               
+               return true;
+       }
+
+       if(name=="time" && param.get_type()==Param::TYPE_TIME && waypoint.get_time()==(Time::begin()-1))
+       {
+               waypoint.set_time(param.get_time());
+               time_set=true;
+
+               if(value_node)
+                       calc_waypoint();
+               DEBUGPOINT();
+               
+               return true;
+       }
+
+       if(name=="model" && param.get_type()==Param::TYPE_WAYPOINTMODEL)
+       {
+               if(value_node)
+                       calc_waypoint();
+
+               waypoint.apply_model(param.get_waypoint_model());
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::WaypointSetSmart::is_ready()const
+{
+       if(!value_node)
+               sinfg::error("Missing value_node");
+
+       if(waypoint.get_time()==(Time::begin()-1))
+               sinfg::error("Missing waypoint");
+       
+       if(!value_node || waypoint.get_time()==(Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+// This function is called if a time is specified, but not 
+// a waypoint. In this case, we need to calculate the value
+// of the waypoint
+void
+Action::WaypointSetSmart::calc_waypoint()
+{
+       DEBUGPOINT();
+       Time time=waypoint.get_time();  
+       try
+       {
+               // Trivial case, we are sitting on a waypoint
+               waypoint=*value_node->find(waypoint.get_time());
+       }
+       catch(...)
+       {
+               waypoint=value_node->new_waypoint_at_time(time);        
+               waypoint.set_before(sinfgapp::Main::get_interpolation());
+               waypoint.set_after(sinfgapp::Main::get_interpolation());
+       }
+/*
+       Time time=waypoint.get_time();
+       ValueNode_Animated::WaypointList &waypoint_list(value_node->waypoint_list());
+       ValueNode_Animated::WaypointList::iterator iter;
+       
+       if(waypoint_list.empty())
+       {
+               waypoint.set_value((*value_node)(time));
+               return;
+       }
+
+       ValueNode_Animated::WaypointList::iterator closest=waypoint_list.begin();
+               
+       for(iter=waypoint_list.begin();iter!=waypoint_list.end();++iter)
+       {
+               const Real dist(abs(iter->get_time()-time));
+               if(dist<abs(closest->get_time()-time))
+                       closest=iter;
+       }
+       if(!closest->is_static())
+               waypoint.set_value_node(closest->get_value_node());
+       else
+               waypoint.set_value((*value_node)(time));
+*/
+}
+
+void
+Action::WaypointSetSmart::enclose_waypoint(const sinfg::Waypoint& waypoint)
+{
+       times.insert(waypoint.get_time());                      
+       
+       try {
+               times.insert(value_node->find(waypoint)->get_time());
+//             sinfg::info(__FILE__":%d: value_node->find(waypoint)->get_time()=%s",__LINE__,value_node->find(waypoint)->get_time().get_string().c_str());
+//             DEBUGPOINT();
+       }catch (...) { }
+       
+//     DEBUGPOINT();
+       // First we need to to add any waypoints necessary to
+       // maintain the integrity of the keyframes.     
+       if(get_edit_mode()&MODE_ANIMATE_PAST) try
+       {
+               Time curr_time(waypoint.get_time());
+               
+               //while(value_node->waypoint_list().front().get_time()<=curr_time)
+               {
+                       // Try to find prev keyframe
+                       Keyframe keyframe(*get_canvas()->keyframe_list().find_prev(curr_time));
+                       curr_time=keyframe.get_time();
+
+//                     sinfg::info(__FILE__":%d: prev_keyframe->time=%s",__LINE__,keyframe.get_time().get_string().c_str());
+//                     sinfg::info(__FILE__":%d: waypoint->time=%s",__LINE__,waypoint.get_time().get_string().c_str());
+                       
+//                     DEBUGPOINT();
+                       if(times.count(keyframe.get_time()))
+                       {
+//                             DEBUGPOINT();
+                               throw int();
+                       }
+                       if(waypoint.get_time().is_equal(keyframe.get_time()))
+                       {
+//                             DEBUGPOINT();
+                               throw int();
+                       }
+
+                       times.insert(keyframe.get_time());                      
+//                     DEBUGPOINT();
+                       try
+                       {
+                               value_node->find(keyframe.get_time());
+//                             sinfg::info(__FILE__":%d: waypointtime=%s",__LINE__,value_node->find(keyframe.get_time())->get_time().get_string().c_str());
+                       }
+                       catch(sinfg::Exception::NotFound)
+                       {
+                               Action::Handle action(WaypointAdd::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle(value_node));
+                       
+                               if(!value_node->waypoint_list().empty())
+                               {       
+                                       action->set_param("time",keyframe.get_time());
+                               }
+                               else
+                               {
+                                       sinfg::Waypoint tmp;
+                                       
+                                       tmp.set_value(waypoint.get_value());
+                                       tmp.set_time(keyframe.get_time());
+                                       action->set_param("waypoint",tmp);
+                               }
+       
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action(action);
+                       }                                               
+               }               
+       }
+       catch(Error x) { throw x; }
+       catch(sinfg::Exception::NotFound) { DEBUGPOINT(); }
+       catch(int) { DEBUGPOINT(); }
+       catch(...) { DEBUGPOINT(); }
+                       //DEBUGPOINT();
+
+               //DEBUGPOINT();
+       if(get_edit_mode()&MODE_ANIMATE_FUTURE)try
+       {
+               Time curr_time(waypoint.get_time());
+               
+               //while(value_node->waypoint_list().back().get_time()>=curr_time)
+               {
+       
+                       //DEBUGPOINT();
+                       // Try to find next keyframe
+                       //sinfg::info("FUTURE waypoint.get_time()=%s",waypoint.get_time().get_string().c_str());
+                       Keyframe keyframe(*get_canvas()->keyframe_list().find_next(curr_time));
+                       //sinfg::info("FUTURE keyframe.get_time()=%s",keyframe.get_time().get_string().c_str());
+                       curr_time=keyframe.get_time();
+                       
+                       //DEBUGPOINT();
+                       if(times.count(keyframe.get_time())|| waypoint.get_time().is_equal(keyframe.get_time()))
+                               throw int();
+                       else
+                               times.insert(keyframe.get_time());                      
+                       //DEBUGPOINT();
+                       
+                       try
+                       {
+                               value_node->find(keyframe.get_time());
+                               sinfg::info(__FILE__":%d: time=%s",__LINE__,keyframe.get_time().get_string().c_str());
+                               sinfg::info(__FILE__":%d: waypointtime=%s",__LINE__,value_node->find(keyframe.get_time())->get_time().get_string().c_str());
+                               
+                       }
+                       catch(sinfg::Exception::NotFound)
+                       {
+                               Action::Handle action(WaypointAdd::create());
+                               
+                               action->set_param("canvas",get_canvas());
+                               action->set_param("canvas_interface",get_canvas_interface());
+                               action->set_param("value_node",ValueNode::Handle(value_node));
+                       
+                               if(!value_node->waypoint_list().empty())
+                               {       
+                                       action->set_param("time",keyframe.get_time());
+                               }
+                               else
+                               {
+                                       sinfg::Waypoint tmp;
+                                       
+                                       tmp.set_value(waypoint.get_value());
+                                       tmp.set_time(keyframe.get_time());
+                                       action->set_param("waypoint",tmp);
+                               }
+       
+                               assert(action->is_ready());
+                               if(!action->is_ready())
+                                       throw Error(Error::TYPE_NOTREADY);
+                       
+                               add_action(action);
+                       }
+               }
+                       //DEBUGPOINT();
+       }
+       catch(Error x) { throw x; }
+       catch(sinfg::Exception::NotFound) { DEBUGPOINT(); }
+       catch(int) { DEBUGPOINT(); }
+       catch(...) { DEBUGPOINT(); }
+               //DEBUGPOINT();
+}
+
+void
+Action::WaypointSetSmart::prepare()
+{
+               //DEBUGPOINT();
+       clear();
+       times.clear();
+       
+       // First we need to to add any waypoints necessary to
+       // maintain the integrity of the keyframes.     
+       enclose_waypoint(waypoint);
+
+       try
+       {
+               //sinfg::info("WaypointSetSmart: Move/Update?");
+               // Lets try to replace the old waypoint, if it exists
+               WaypointList::iterator iter(value_node->find(waypoint));
+               
+               if(iter == value_node->waypoint_list().end())
+                       throw int();
+               
+               enclose_waypoint(*iter);
+
+               Action::Handle action(WaypointSet::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_node",ValueNode::Handle(value_node));
+               action->set_param("waypoint",waypoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+               
+               return;
+       }
+       catch(sinfg::Exception::NotFound){ } catch(int){ }
+
+       try
+       {
+               //sinfg::info("WaypointSetSmart: Replace?");
+               //DEBUGPOINT();
+               // Check to see if a waypoint exists at this point in time
+               WaypointList::iterator iter=value_node->find(waypoint.get_time());
+               
+               waypoint.mimic(*iter);
+
+               enclose_waypoint(*iter);
+               
+               Action::Handle action(WaypointSet::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_node",ValueNode::Handle(value_node));
+               action->set_param("waypoint",waypoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+               
+               return;
+       }
+       catch(sinfg::Exception::NotFound){ } catch(int){ }
+       
+       try
+       {
+               //sinfg::info("WaypointSetSmart: Add?");
+               //DEBUGPOINT();
+               // At this point we know that the old waypoint doesn't exist,
+               // so we need to create it.
+               Action::Handle action(WaypointAdd::create());
+               
+               action->set_param("canvas",get_canvas());
+               action->set_param("canvas_interface",get_canvas_interface());
+               action->set_param("value_node",ValueNode::Handle(value_node));
+               action->set_param("waypoint",waypoint);
+       
+               assert(action->is_ready());
+               if(!action->is_ready())
+                       throw Error(Error::TYPE_NOTREADY);
+       
+               add_action(action);
+               
+               return;
+       }
+       catch(sinfg::Exception::NotFound){ } catch(int){ }
+
+       throw Error(_("Unable to determine how to procede. This is a bug."));   
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.h b/synfig-studio/trunk/src/sinfgapp/actions/waypointsetsmart.h
new file mode 100644 (file)
index 0000000..900fe67
--- /dev/null
@@ -0,0 +1,81 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointsetsmart.h
+**     \brief Template File
+**
+**     $Id: waypointsetsmart.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_ACTION_WAYPOINTSETSMART_H
+#define __SINFG_APP_ACTION_WAYPOINTSETSMART_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfgapp/value_desc.h>
+#include <sinfg/valuenode_animated.h>
+
+#include <list>
+#include <set>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+namespace Action {
+
+class WaypointSetSmart :
+       public Super
+{
+private:
+
+       sinfg::ValueNode_Animated::Handle value_node;
+       sinfg::Waypoint waypoint;
+       //sinfg::WaypointModel waypoint_model;
+       bool time_set;
+
+       void calc_waypoint();
+       void enclose_waypoint(const sinfg::Waypoint& waypoint);
+
+       std::set<sinfg::Time> times;
+
+public:
+
+       WaypointSetSmart();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void prepare();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.cpp b/synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.cpp
new file mode 100644 (file)
index 0000000..766bb6b
--- /dev/null
@@ -0,0 +1,156 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointsimpleadd.cpp
+**     \brief Simple add waypoint File
+**
+**     $Id: waypointsimpleadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "waypointsimpleadd.h"
+#include <sinfgapp/canvasinterface.h>
+
+#endif
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+using namespace Action;
+
+/* === M A C R O S ========================================================= */
+
+ACTION_INIT(Action::WaypointSimpleAdd);
+ACTION_SET_NAME(Action::WaypointSimpleAdd,"waypoint_simpleadd");
+ACTION_SET_LOCAL_NAME(Action::WaypointSimpleAdd,"Simply Add Waypoint");
+ACTION_SET_TASK(Action::WaypointSimpleAdd,"add");
+ACTION_SET_CATEGORY(Action::WaypointSimpleAdd,Action::CATEGORY_WAYPOINT);
+ACTION_SET_PRIORITY(Action::WaypointSimpleAdd,0);
+ACTION_SET_VERSION(Action::WaypointSimpleAdd,"0.0");
+ACTION_SET_CVS_ID(Action::WaypointSimpleAdd,"$Id: waypointsimpleadd.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $");
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Action::WaypointSimpleAdd::WaypointSimpleAdd()
+{
+       set_dirty(true);
+       waypoint.set_time(Time::begin()-1);
+}
+
+Action::ParamVocab
+Action::WaypointSimpleAdd::get_param_vocab()
+{
+       ParamVocab ret(Action::CanvasSpecific::get_param_vocab());
+       
+       ret.push_back(ParamDesc("value_node",Param::TYPE_VALUENODE)
+               .set_local_name(_("Destination ValueNode (Animated)"))
+       );
+
+       ret.push_back(ParamDesc("waypoint",Param::TYPE_WAYPOINT)
+               .set_local_name(_("Waypoint"))
+               .set_desc(_("Waypoint to be added"))
+       );
+
+       return ret;
+}
+
+bool
+Action::WaypointSimpleAdd::is_canidate(const ParamList &x)
+{
+       return canidate_check(get_param_vocab(),x);
+}
+
+bool
+Action::WaypointSimpleAdd::set_param(const sinfg::String& name, const Action::Param &param)
+{
+       if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
+       {
+               value_node=ValueNode_Animated::Handle::cast_dynamic(param.get_value_node());
+               
+               return static_cast<bool>(value_node);
+       }
+       if(name=="waypoint" && param.get_type()==Param::TYPE_WAYPOINT)
+       {
+               waypoint = param.get_waypoint();
+               
+               return true;
+       }
+
+       return Action::CanvasSpecific::set_param(name,param);
+}
+
+bool
+Action::WaypointSimpleAdd::is_ready()const
+{
+       if(!value_node && waypoint.get_time() != (Time::begin()-1))
+               return false;
+       return Action::CanvasSpecific::is_ready();
+}
+
+void
+Action::WaypointSimpleAdd::perform()
+{      
+       //remove any pretenders that lie at our destination
+       ValueNode_Animated::findresult iter = value_node->find_time(waypoint.get_time());
+       
+       time_overwrite = false;
+       if(iter.second)
+       {
+               overwritten_wp = *iter.first;
+               time_overwrite = true;
+       }
+       
+       //add the value node in since it's safe
+       value_node->add(waypoint);
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
+
+void
+Action::WaypointSimpleAdd::undo()
+{
+       //remove our old version...
+       ValueNode_Animated::findresult iter = value_node->find_uid(waypoint);
+       
+       if(!iter.second)
+       {
+               throw Error(_("The waypoint to remove no longer exists"));
+       }
+       
+       //remove the offending value
+       value_node->erase(*iter.first); //could also just use waypoint
+       
+       if(time_overwrite)
+       {
+               value_node->add(overwritten_wp);                                
+       }
+       
+       // Signal that a valuenode has been changed
+       value_node->changed();
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.h b/synfig-studio/trunk/src/sinfgapp/actions/waypointsimpleadd.h
new file mode 100644 (file)
index 0000000..2c044e8
--- /dev/null
@@ -0,0 +1,79 @@
+/* === S I N F G =========================================================== */
+/*!    \file waypointsimpleadd.h
+**     \brief A simple add a waypoint function Header
+**
+**     $Id: waypointsimpleadd.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_WAYPOINTSIMPLEADD_H
+#define __SINFG_WAYPOINTSIMPLEADD_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfgapp/action.h>
+#include <sinfg/waypoint.h>
+#include <sinfg/valuenode_animated.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Instance;
+
+namespace Action {
+
+class WaypointSimpleAdd :
+       public Undoable,
+       public CanvasSpecific
+{
+private:
+       
+       sinfg::ValueNode_Animated::Handle value_node;
+       
+       sinfg::Waypoint waypoint;
+
+       bool time_overwrite;
+       sinfg::Waypoint overwritten_wp;
+
+public:
+
+       WaypointSimpleAdd();
+
+       static ParamVocab get_param_vocab();
+       static bool is_canidate(const ParamList &x);
+
+       virtual bool set_param(const sinfg::String& name, const Param &);
+       virtual bool is_ready()const;
+
+       virtual void perform();
+       virtual void undo();
+
+       ACTION_MODULE_EXT
+};
+
+}; // END of namespace action
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/blineconvert.cpp b/synfig-studio/trunk/src/sinfgapp/blineconvert.cpp
new file mode 100644 (file)
index 0000000..d35496e
--- /dev/null
@@ -0,0 +1,835 @@
+/* === S I N F G =========================================================== */
+/*!    \file blineconvert.cpp
+**     \brief Template File
+**
+**     $Id: blineconvert.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "blineconvert.h"
+#include <vector>
+#include <ETL/gaussian>
+#include <ETL/hermite>
+#include <ETL/clock>
+#include <float.h>
+#include <algorithm>
+#include <sinfg/general.h>
+#include <cassert>
+
+
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+#define EPSILON                (1e-10)
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+
+//Derivative Functions for numerical approximation
+
+//bias == 0 will get F' at f3, bias < 0 will get F' at f1, and bias > 0 will get F' at f5
+template < class T >
+inline void FivePointdt(T &df, const T &f1, const T &f2, const T &f3, const T &f4, const T &f5, int bias)
+{
+       if(bias == 0)
+       {
+               //middle
+               df = (f1 - f2*8 + f4*8 - f5)*(1/12.0f);
+       }else if(bias < 0)
+       {
+               //left
+               df = (-f1*25 + f2*48 - f3*36 + f4*16 - f5*3)*(1/12.0f);
+       }else
+       {
+               //right
+               df = (f1*3 - f2*16 + f3*36 - f4*48 + f5*25)*(1/12.0f);
+       }
+}
+
+template < class T >
+inline void ThreePointdt(T &df, const T &f1, const T &f2, const T &f3, int bias)
+{
+       if(bias == 0)
+       {
+               //middle
+               df = (-f1 + f3)*(1/2.0f);
+       }else if(bias < 0)
+       {
+               //left
+               df = (-f1*3 + f2*4 - f3)*(1/2.0f);
+       }else
+       {
+               //right
+               df = (f1 - f2*4 + f3*3)*(1/2.0f);
+       }
+}
+
+template < class T >
+inline void ThreePointddt(T &df, const T &f1, const T &f2, const T &f3, int bias)
+{
+       //a 3 point approximation pretends to have constant acceleration, so only one algorithm needed for left, middle, or right
+       df = (f1 -f2*2 + f3)*(1/2.0f);
+}
+
+// WARNING -- totaly broken
+template < class T >
+inline void FivePointddt(T &df, const T &f1, const T &f2, const T &f3, int bias)
+{
+       if(bias == 0)
+       {
+               assert(0); // !?
+               //middle
+               //df = (- f1 + f2*16 - f3*30 +  f4*16 - f5)*(1/12.0f);
+       }/*else if(bias < 0)
+       {
+               //left
+               df = (f1*7 - f2*26*4 + f3*19*6 - f4*14*4 + f5*11)*(1/12.0f);
+       }else
+       {
+               //right
+               df = (f1*3 - f2*16 + f3*36 - f4*48 + f5*25)*(1/12.0f);
+       }*/
+       //side ones don't work, use 3 point
+}
+
+//implement an arbitrary derivative
+//dumb algorithm
+template < class T >
+void DerivativeApprox(T &df, const T f[], const Real t[], int npoints, int indexval)
+{
+       /*
+       Lj(x) = PI_i!=j (x - xi) / PI_i!=j (xj - xi)
+       
+       so Lj'(x) = SUM_k PI_i!=j|k (x - xi) / PI_i!=j (xj - xi)
+       */
+       
+       unsigned int i,j,k,i0,i1;
+       
+       Real Lpj,mult,div,tj;
+       Real tval = t[indexval];
+                               
+       //sum k 
+       for(j=0;j<npoints;++j)
+       {
+               Lpj = 0;
+               div = 1;
+               tj = t[j];
+               
+               for(k=0;k<npoints;++k)
+               {
+                       if(k != j) //because there is no summand for k == j, since that term is missing from the original equation
+                       {
+                               //summation for k
+                               for(i=0;i<npoints;++i)
+                               {
+                                       if(i != k)
+                                       {
+                                               mult *= tval - t[i];
+                                       }
+                               }
+                               
+                               Lpj += mult; //add into the summation
+                               
+                               //since the ks follow the exact patern we need for the divisor (use that too)
+                               div *= tj - t[k];
+                       }
+               }
+               
+               //get the actual coefficient
+               Lpj /= div;
+               
+               //add it in to the equation
+               df += f[j]*Lpj;
+       }
+}
+
+//END numerical derivatives
+
+template < class T >
+inline int sign(T f, T tol)
+{
+       if(f < -tol) return -1;
+       if(f > tol) return 1;
+       return 0;
+}
+
+void GetFirstDerivatives(const std::vector<sinfg::Point> &f, unsigned int left, unsigned int right, char *out, unsigned int dfstride)
+{
+       unsigned int current = left;
+
+       if(right - left < 2)
+               return;
+       else if(right - left < 3)
+       {
+               sinfg::Vector v = f[left+1] - f[left];
+               
+               //set both to the one we want
+               *(sinfg::Vector*)out = v;
+               out += dfstride;
+               *(sinfg::Vector*)out = v;
+               out += dfstride;
+       }
+       else if(right - left < 6/*5*/) //should use 3 point
+       {
+               //left then middle then right
+               ThreePointdt(*(sinfg::Vector*)out,f[left+0], f[left+1], f[left+2], -1);
+               current += 1;
+               out += dfstride;
+               
+               for(;current < right-1; current++, out += dfstride)
+               {
+                       ThreePointdt(*(sinfg::Vector*)out,f[current-1], f[current], f[current+1], 0);
+               }
+
+               ThreePointdt(*(sinfg::Vector*)out,f[right-3], f[right-2], f[right-1], 1);
+               current++;
+               out += dfstride;
+               
+       }else //can use 5 point
+       {
+               //left 2 then middle bunch then right two
+               //may want to use 3 point for inner edge ones
+               
+               FivePointdt(*(sinfg::Vector*)out,f[left+0], f[left+1], f[left+2], f[left+3], f[left+4], -2);
+               out += dfstride;
+               FivePointdt(*(sinfg::Vector*)out,f[left+1], f[left+2], f[left+3], f[left+4], f[left+5], -1);
+               out += dfstride;
+               current += 2;
+               
+               for(;current < right-2; current++, out += dfstride)
+               {
+                       FivePointdt(*(sinfg::Vector*)out,f[current-2], f[current-1], f[current], f[current+1], f[current+2], 0);
+               }
+
+               FivePointdt(*(sinfg::Vector*)out,f[right-5], f[right-4], f[right-3], f[right-2], f[right-1], 1);
+               out += dfstride;
+               FivePointdt(*(sinfg::Vector*)out,f[right-6], f[right-5], f[right-4], f[right-3], f[right-2], 2);                
+               out += dfstride;
+               current += 2;
+       }
+}
+
+void GetSimpleDerivatives(const std::vector<sinfg::Point> &f, int left, int right, 
+                                                       std::vector<sinfg::Point> &df, int outleft,
+                                                       const std::vector<sinfg::Real> &di)
+{
+       int i1,i2,i;
+       int offset = 2; //df = 1/2 (f[i+o]-f[i-o])
+       
+       assert((int)df.size() >= right-left+outleft); //must be big enough
+       
+       for(i = left; i < right; ++i)
+       {
+               //right now indices (figure out distance later)
+               i1 = std::max(left,i-offset);
+               i2 = std::max(left,i+offset);
+               
+               df[outleft++] = (f[i2] - f[i1])*0.5f;
+       }
+}
+
+//get the curve error from the double sample list of work points (hopefully that's enough)
+Real CurveError(const sinfg::Point *pts, unsigned int n, std::vector<sinfg::Point> &work, int left, int right)
+{
+       if(right-left < 2) return -1;
+               
+       int i,j;
+       
+       //get distances to each point
+       Real d,dtemp,dsum;
+       //sinfg::Vector v,vt;
+       //sinfg::Point p1,p2;
+       sinfg::Point pi;
+       std::vector<sinfg::Point>::const_iterator it;//,end = work.begin()+right;
+       
+       //unsigned int size = work.size();
+       
+       //for each line, get distance
+       d = 0; //starts at 0
+       for(i = 0; i < (int)n; ++i)
+       {               
+               pi = pts[i];
+               
+               dsum = FLT_MAX;
+               
+               it = work.begin()+left;
+               //p2 = *it++; //put it at left+1
+               for(j = left/*+1*/; j < right; ++j,++it)
+               {
+                       /*p1 = p2;
+                       p2 = *it;
+                       
+                       v = p2 - p1;                    
+                       vt = pi - p1;
+                       
+                       dtemp = v.mag_squared() > 1e-12 ? (vt*v)/v.mag_squared() : 0; //get the projected time value for the current line
+                       
+                       //get distance to line segment with the time value clamped 0-1                  
+                       if(dtemp >= 1)  //use p+v
+                       {
+                               vt += v; //makes it pp - (p+v)  
+                       }else if(dtemp > 0)     //use vt-proj
+                       {
+                               vt -= v*dtemp; // vt - proj_v(vt)       //must normalize the projection vector to work
+                       }
+                       
+                       //else use p
+                       dtemp = vt.mag_squared();*/
+                       
+                       dtemp = (pi - *it).mag_squared();                       
+                       if(dtemp < dsum)
+                               dsum = dtemp;
+               }
+               
+               //accumulate the points' min distance from the curve
+               d += sqrt(dsum);
+       }
+       
+       return d;
+}
+
+typedef sinfgapp::BLineConverter::cpindex cpindex;
+
+//has the index data and the tangent scale data (relevant as it may be)
+int tesselate_curves(const std::vector<cpindex> &inds, const std::vector<Point> &f, const std::vector<sinfg::Vector> &df, std::vector<Point> &work)
+{
+       if(inds.size() < 2)
+               return 0;
+       
+       etl::hermite<Point>     curve;
+       int ntess = 0;
+       
+       std::vector<cpindex>::const_iterator j = inds.begin(),j2, end = inds.end();
+       
+       unsigned int ibase = inds[0].curind;
+               
+       j2 = j++;
+       for(; j != end; j2 = j++)
+       {
+               //if this curve has invalid error (in j) then retesselate it's work points (requires reparametrization, etc.)
+               if(j->error < 0)
+               {
+                       //get the stepsize etc. for the number of points in here
+                       unsigned int n = j->curind - j2->curind + 1; //thats the number of points in the span
+                       unsigned int k, kend, i0, i3;
+                       //so reset the right chunk
+                       
+                       Real t, dt = 1/(Real)(n*2-2); //assuming that they own only n points
+                       
+                       //start at first intermediate
+                       t = 0;
+
+                       i0 = j2->curind; i3 = j->curind;                        
+                       k = (i0-ibase)*2; //start on first intermediary point (2x+1)
+                       kend = (i3-ibase)*2; //last point to set (not intermediary)
+                       
+                       //build hermite curve, it's easier
+                       curve.p1() = f[i0];
+                       curve.p2() = f[i3];
+                       curve.t1() = df[i0]*(df[i0].mag_squared() > 1e-4 ? j2->tangentscale/df[i0].mag() : j2->tangentscale);
+                       curve.t2() = df[i3]*(df[i3].mag_squared() > 1e-4 ? j->tangentscale/df[i3].mag() : j->tangentscale);
+                       curve.sync();
+                                               
+                       //MUST include the end point (since we are ignoring left one)
+                       for(; k < kend; ++k, t += dt)
+                       {
+                               work[k] = curve(t);
+                       }
+                       
+                       work[k] = curve(1); //k == kend, t == 1 -> c(t) == p2
+                       ++ntess;
+               }
+       }
+       
+       return ntess;
+}
+
+sinfgapp::BLineConverter::BLineConverter()
+{
+       pixelwidth = 1;
+       smoothness = 0.70f;
+       width = 0;
+};
+
+void 
+sinfgapp::BLineConverter::clear()
+{
+       f.clear();
+       f_w.clear();
+       ftemp.clear();
+       df.clear();
+       cvt.clear();
+       brk.clear();
+       di.clear();
+       d_i.clear();
+       work.clear();
+       curind.clear();
+}
+
+void
+sinfgapp::BLineConverter::operator () (std::list<sinfg::BLinePoint> &out, const std::list<sinfg::Point> &in,const std::list<sinfg::Real> &in_w)
+{      
+       //Profiling information
+       /*etl::clock::value_type initialprocess=0, curveval=0, breakeval=0, disteval=0;
+       etl::clock::value_type preproceval=0, tesseval=0, erroreval=0, spliteval=0;
+       unsigned int                    numpre=0, numtess=0, numerror=0, numsplit=0;
+       etl::clock_realtime timer,total;*/
+
+       //total.reset();
+       if(in.size()<=1)
+               return;
+
+       clear();
+       
+       //removing digitization error harder than expected
+       
+       //intended to fix little pen errors caused by the way people draw (tiny juts in opposite direction)
+       //Different solutions
+       //      Average at both end points (will probably eliminate many points at each end of the samples)
+       //      Average after the break points are found (weird points would still affect the curve)
+       //      Just always get rid of breaks at the beginning and end if they are a certain distance apart
+       //              This is will be current approach so all we do now is try to remove duplicate points
+       
+       //remove duplicate points - very bad for fitting
+       
+       //timer.reset();
+       
+       {
+               std::list<sinfg::Point>::const_iterator i = in.begin(), end = in.end();
+               std::list<sinfg::Real>::const_iterator  iw = in_w.begin();
+               sinfg::Point    c;
+               
+               if(in.size() == in_w.size())
+               {
+                       for(;i != end; ++i,++iw)
+                       {       
+                               //eliminate duplicate points
+                               if(*i != c)
+                               {
+                                       f.push_back(c = *i);
+                                       f_w.push_back(*iw);
+                               }
+                       }
+               }else
+               {
+                       for(;i != end; ++i)
+                       {       
+                               //eliminate duplicate points
+                               if(*i != c)
+                               {
+                                       f.push_back(c = *i);
+                               }
+                       }
+               }
+       }
+       //initialprocess = timer();
+       
+       if(f.size()<=6)
+               return;
+       
+       //get curvature information
+       //timer.reset();
+       
+       {
+               int i,i0,i1;
+               sinfg::Vector v1,v2;
+               
+               cvt.resize(f.size());
+               
+               cvt.front() = 1;
+               cvt.back() = 1;
+               
+               for(i = 1; i < (int)f.size()-1; ++i)
+               {
+                       i0 = std::max(0,i - 2);
+                       i1 = std::min((int)(f.size()-1),i + 2);
+                       
+                       v1 = f[i] - f[i0];
+                       v2 = f[i1] - f[i];
+       
+                       cvt[i] = (v1*v2)/(v1.mag()*v2.mag());
+               }
+       }
+       
+       //curveval = timer();
+       //sinfg::info("calculated curvature");
+       
+       //find corner points and interpolate inside those
+       //timer.reset();
+       {               
+               //break at sharp derivative points
+               //TODO tolerance should be set based upon digitization resolution (length dependent index selection)
+               Real    tol = 0;                //break tolerance, for the cosine of the change in angle (really high curvature or something)
+               Real    fixdistsq = 4*width*width; //the distance to ignore breaks at the end points (for fixing stuff)
+               unsigned int i = 0;
+               
+               int             maxi = -1, last=0;
+               Real    minc = 1;
+               
+               brk.push_back(0);
+               
+               for(i = 1; i < cvt.size()-1; ++i)
+               {                       
+                       //insert if too sharp (we need to break the tangents to insert onto the break list)
+                       
+                       if(cvt[i] < tol)
+                       {
+                               if(cvt[i] < minc)
+                               {
+                                       minc = cvt[i];
+                                       maxi = i;
+                               }
+                       }else if(maxi >= 0)
+                       {
+                               if(maxi >= last + 8)
+                               {
+                                       //sinfg::info("break: %d-%d",maxi+1,cvt.size());                                                
+                                       brk.push_back(maxi);
+                                       last = maxi;
+                               }
+                               maxi = -1;
+                               minc = 1;
+                       }
+               }
+               
+               brk.push_back(i);
+               
+               //postprocess for breaks too close to eachother
+               Real d = 0;
+               Point p = f[brk.front()];
+               
+               //first set
+               for(i = 1; i < brk.size()-1; ++i) //do not want to include end point...
+               {
+                       d = (f[brk[i]] - p).mag_squared();
+                       if(d > fixdistsq) break; //don't want to group breaks if we ever get over the dist... 
+               }
+               //want to erase all points before...
+               if(i != 1)
+                       brk.erase(brk.begin(),brk.begin()+i-1); 
+               
+               //end set
+               p = f[brk.back()];
+               for(i = brk.size()-2; i > 0; --i) //start at one in from the end
+               {
+                       d = (f[brk[i]] - p).mag_squared();
+                       if(d > fixdistsq) break; //don't want to group breaks if we ever get over the dist
+               }
+               if(i != brk.size()-2)
+                       brk.erase(brk.begin()+i+2,brk.end()); //erase all points that we found... found none if i has not advanced
+               //must not include the one we ended up on
+       }
+       //breakeval = timer();
+       //sinfg::info("found break points: %d",brk.size());
+       
+       //get the distance calculation of the entire curve (for tangent scaling)
+
+       //timer.reset();
+       {
+               sinfg::Point p1,p2;
+               
+               p1=p2=f[0];
+               
+               di.resize(f.size()); d_i.resize(f.size());
+               Real d = 0;
+               for(unsigned int i = 0; i < f.size();)
+               {
+                       d += (d_i[i] = (p2-p1).mag());
+                       di[i] = d;
+                       
+                       p1=p2;
+                       p2=f[++i];
+               }
+       }
+       //disteval = timer();
+       //sinfg::info("calculated distance");
+               
+       //now break at every point - calculate new derivatives each time
+       
+       //TODO
+       //must be sure that the break points are 3 or more apart
+       //then must also store the breaks which are not smooth, etc.
+       //and figure out tangents between there
+       
+       //for each pair of break points (as long as they are far enough apart) recursively subdivide stuff
+       //ignore the detected intermediate points
+       {
+               unsigned int i0=0,i3=0,is=0;
+               int i=0,j=0;
+               
+               bool done = false;
+               
+               Real errortol = smoothness*pixelwidth; //???? what the hell should this value be
+               
+               BLinePoint a;
+               sinfg::Vector v;
+               
+               //intemp = f; //don't want to smooth out the corners
+               
+               bool breaktan = false, setwidth;
+               a.set_split_tangent_flag(false);
+               //a.set_width(width);
+               a.set_width(1.0f);
+               
+               setwidth = (f.size() == f_w.size());
+               
+               for(j = 0; j < (int)brk.size() - 1; ++j)
+               {
+                       //for b[j] to b[j+1] subdivide and stuff
+                       i0 = brk[j];
+                       i3 = brk[j+1];
+                       
+                       unsigned int size = i3-i0+1; //must include the end points
+                       
+                       //new derivatives
+                       //timer.reset();
+                       ftemp.assign(f.begin()+i0, f.begin()+i3+1);
+                       for(i=0;i<20;++i)
+                               gaussian_blur_3(ftemp.begin(),ftemp.end(),false);
+                       
+                       df.resize(size);
+                       GetFirstDerivatives(ftemp,0,size,(char*)&df[0],sizeof(df[0]));
+                       //GetSimpleDerivatives(ftemp,0,size,df,0,di); 
+                       //< don't have to worry about indexing stuff as it is all being taken car of right now
+                       //preproceval += timer();
+                       //numpre++;
+                       
+                       work.resize(size*2-1); //guarantee that all points will be tesselated correctly (one point inbetween every 2 adjacent points)
+                       
+                       //if size of work is size*2-1, the step size should be 1/(size*2 - 2)
+                       //Real step = 1/(Real)(size*2 - 1);
+                       
+                       //start off with break points as indices
+                       curind.clear();
+                       curind.push_back(cpindex(i0,di[i3]-di[i0],0)); //0 error because no curve on the left
+                       curind.push_back(cpindex(i3,di[i3]-di[i0],-1)); //error needs to be reevaluated
+                       done = false; //we want to loop
+                       
+                       unsigned int dcount = 0;
+                       
+                       //while there are still enough points between us, and the error is too high subdivide (and invalidate neighbors that share tangents)            
+                       while(!done)
+                       {                                       
+                               //tesselate all curves with invalid error values
+                               work[0] = f[i0];
+                               
+                               //timer.reset();
+                               /*numtess += */tesselate_curves(curind,f,df,work);
+                               //tesseval += timer();
+                               
+                               //now get all error values
+                               //timer.reset();
+                               for(i = 1; i < (int)curind.size(); ++i)
+                               {
+                                       if(curind[i].error < 0) //must have been retesselated, so now recalculate error value
+                                       {
+                                               //evaluate error from points (starting at current index)
+                                               int size = curind[i].curind - curind[i-1].curind + 1;
+                                               curind[i].error = CurveError(&f[curind[i-1].curind], size,
+                                                                                                        work,(curind[i-1].curind - i0)*2,(curind[i].curind - i0)*2+1);
+                                               
+                                               /*if(curind[i].error > 1.0e5)
+                                               {
+                                                       sinfg::info("Holy crap %d-%d error %f",curind[i-1].curind,curind[i].curind,curind[i].error);
+                                                       curind[i].error = -1;
+                                                       numtess += tesselate_curves(curind,f,df,work);
+                                                       curind[i].error = CurveError(&f[curind[i-1].curind], size,
+                                                                                                        work,0,work.size());//(curind[i-1].curind - i0)*2,(curind[i].curind - i0)*2+1);
+                                               }*/
+                                               //numerror++;
+                                       }
+                               }
+                               //erroreval += timer();
+                               
+                               //assume we're done
+                               done = true;
+                               
+                               //check each error to see if it's too big, if so, then subdivide etc.
+                               int indsize = (int)curind.size();
+                               Real maxrelerror = 0;
+                               int maxi = -1;//, numpoints;
+                               
+                               //timer.reset();
+                               //get the maximum error and split there
+                               for(i = 1; i < indsize; ++i)
+                               {
+                                       //numpoints = curind[i].curind - curind[i-1].curind + 1;
+                                       
+                                       if(curind[i].error > maxrelerror && curind[i].curind - curind[i-1].curind > 2) //only accept if it's valid
+                                       {
+                                               maxrelerror = curind[i].error;
+                                               maxi = i;
+                                       }
+                               }
+                               
+                               //split if error is too great
+                               if(maxrelerror > errortol)
+                               {
+                                       //add one to the left etc
+                                       unsigned int    ibase = curind[maxi-1].curind, itop = curind[maxi].curind,
+                                                                       ibreak = (ibase + itop)/2;
+                                       Real scale, scale2;
+                                       
+                                       assert(ibreak < f.size());
+                                       
+                                       //sinfg::info("Split %d -%d- %d, error: %f", ibase,ibreak,itop,maxrelerror);
+                                       
+                                       if(ibase != itop)
+                                       {
+                                               //invalidate current error of the changed tangents and add an extra segment
+                                               //enforce minimum tangents property
+                                               curind[maxi].error = -1;
+                                               curind[maxi-1].error = -1;
+                                               if(maxi+1 < indsize) curind[maxi+1].error = -1; //if there is a curve segment beyond this it will be effected as well
+                                               
+                                               scale = di[itop] - di[ibreak];
+                                               scale2 = maxi+1 < indsize ? di[curind[maxi+1].curind] - di[itop] : scale; //to the right valid?
+                                               curind[maxi].tangentscale = std::min(scale, scale2);
+                                                                                               
+                                               scale = di[ibreak] - di[ibase];
+                                               scale2 = maxi >= 2 ? di[ibase] - di[curind[maxi-2].curind] : scale; // to the left valid -2 ?
+                                               curind[maxi-1].tangentscale = std::min(scale, scale2);
+                                               
+                                               scale = std::min(di[ibreak] - di[ibase], di[itop] - di[ibreak]);
+                                               
+                                               curind.insert(curind.begin()+maxi,cpindex(ibreak, scale, -1));
+                                               //curind.push_back(cpindex(ibreak, scale, -1));
+                                               //std::sort(curind.begin(), curind.end());
+                                               
+                                               done = false;
+                                               //numsplit++;
+                                       }
+                               }
+                               //spliteval += timer();
+                               
+                               dcount++;
+                       }
+       
+                       //insert the last point too (just set tangent for now                   
+                       is = curind[0].curind;
+                       
+                       //first point inherits current tangent status                   
+                       v = df[is - i0];
+                       if(v.mag_squared() > EPSILON)
+                               v *= (curind[0].tangentscale/v.mag());
+                                                       
+                       if(!breaktan)
+                               a.set_tangent(v);
+                       else a.set_tangent2(v);
+                       
+                       a.set_vertex(f[is]);
+                       if(setwidth)a.set_width(f_w[is]);
+                       
+                       out.push_back(a);
+                       a.set_split_tangent_flag(false); //won't need to break anymore
+                       breaktan = false;
+                       
+                       for(i = 1; i < (int)curind.size()-1; ++i)
+                       {
+                               is = curind[i].curind;
+                               
+                               //first point inherits current tangent status
+                               v = df[is-i0];
+                               if(v.mag_squared() > EPSILON)
+                                       v *= (curind[i].tangentscale/v.mag());
+                                                               
+                               a.set_tangent(v); // always inside, so guaranteed to be smooth
+                               a.set_vertex(f[is]);
+                               if(setwidth)a.set_width(f_w[is]);
+                               
+                               out.push_back(a);
+                       }
+                       
+                       //set the last point's data
+                       is = curind.back().curind; //should already be this
+                       
+                       v = df[is-i0];
+                       if(v.mag_squared() > EPSILON)
+                               v *= (curind.back().tangentscale/v.mag());
+                       
+                       a.set_tangent1(v);
+                       a.set_split_tangent_flag(true);
+                       breaktan = true;
+                       
+                       //will get the vertex and tangent 2 from next round
+               }
+               
+               a.set_vertex(f[i3]);
+               a.set_split_tangent_flag(false);
+               if(setwidth)
+                       a.set_width(f_w[i3]);
+               out.push_back(a);
+               
+               /*etl::clock::value_type totaltime = total(),
+                                                          misctime = totaltime - initialprocess - curveval - breakeval - disteval
+                                                                         - preproceval - tesseval - erroreval - spliteval;
+               
+               sinfg::info(
+                       "Curve Convert Profile:\n"
+                       "\tInitial Preprocess:    %f\n"
+                       "\tCurvature Calculation: %f\n"
+                       "\tBreak Calculation:     %f\n"
+                       "\tDistance Calculation:  %f\n"
+                       "  Algorithm: (numtimes,totaltime)\n"
+                       "\tPreprocess step:      (%d,%f)\n"
+                       "\tTesselation step:     (%d,%f)\n"
+                       "\tError step:           (%d,%f)\n"
+                       "\tSplit step:           (%d,%f)\n"
+                       "  Num Input: %d, Num Output: %d\n"
+                       "  Total time: %f, Misc time: %f\n",
+                       initialprocess, curveval,breakeval,disteval,
+                       numpre,preproceval,numtess,tesseval,numerror,erroreval,numsplit,spliteval,
+                       in.size(),out.size(),
+                       totaltime,misctime);*/
+               
+               return;
+       }
+}
+
+void sinfgapp::BLineConverter::EnforceMinWidth(std::list<sinfg::BLinePoint> &bline, sinfg::Real min_pressure)
+{
+       std::list<sinfg::BLinePoint>::iterator  i = bline.begin(),
+                                                                                       end = bline.end();
+       
+       for(i = bline.begin(); i != end; ++i)
+       {
+               if(i->get_width() < min_pressure)
+               {
+                       i->set_width(min_pressure);
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/blineconvert.h b/synfig-studio/trunk/src/sinfgapp/blineconvert.h
new file mode 100644 (file)
index 0000000..d09108f
--- /dev/null
@@ -0,0 +1,115 @@
+/* === S I N F G =========================================================== */
+/*!    \file blineconvert.h
+**     \brief Template Header
+**
+**     $Id: blineconvert.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_BLINE_CONVERT_H
+#define __SINFG_BLINE_CONVERT_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/general.h>
+#include <sinfg/blinepoint.h>
+#include <list>
+#include <vector>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+       
+class BLineConverter
+{
+public:
+       struct cpindex
+       {
+               int             curind;
+               sinfg::Real     tangentscale;
+               sinfg::Real     error;  //negative error will indicate invalid;
+               
+               cpindex(int ci, sinfg::Real s=0, sinfg::Real e=-1) 
+               :curind(ci), tangentscale(s), error(e) 
+               {}
+               
+               cpindex(const cpindex & o)
+               :curind(o.curind), tangentscale(o.tangentscale), error(o.error) 
+               {}
+               
+               const cpindex & operator = (const cpindex & rhs)
+               {
+                       curind = rhs.curind;
+                       tangentscale = rhs.tangentscale;
+                       error = rhs.error;
+                       return *this;
+               }
+               
+               bool operator < (const cpindex &rhs) const
+               {
+                       return curind < rhs.curind;             
+               }
+               
+               //point is obviously in[curind]
+               //tangent scale will get reset to the smallest (or something else depending on experimentation)
+       };
+
+private:
+       //cached data
+       std::vector<sinfg::Point>       f;      //the preprocessed input cache
+       std::vector<sinfg::Real>        f_w;
+
+       //temporary point storage for vector calc
+       std::vector<sinfg::Point>       ftemp;
+       
+       std::vector<sinfg::Vector>      df; //the derivative cache      
+       std::vector<sinfg::Real>        cvt; //the curvature cache
+       
+       std::vector<int>                        brk; //the break point cache
+       
+       std::vector<sinfg::Real>        di,     //cumulative distance
+                                                               d_i; //distance between adjacent segments
+       
+       std::vector<sinfg::Point>       work; //the working point cache for the entire curve
+       std::vector<cpindex>            curind;
+       
+       //function parameters
+       void clear();
+
+public:
+       sinfg::Real width;
+
+       //Converter properties
+       sinfg::Real pixelwidth;
+       sinfg::Real smoothness; //actual error will be smoothness*pixelwidth (for global set pixelwidth = 1)
+
+       BLineConverter();
+
+       static void EnforceMinWidth(std::list<sinfg::BLinePoint> &bline, sinfg::Real min_pressure);
+       void operator ()(std::list<sinfg::BLinePoint> &out, const std::list<sinfg::Point> &in,const std::list<sinfg::Real> &in_w);
+};
+       
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/canvasinterface.cpp b/synfig-studio/trunk/src/sinfgapp/canvasinterface.cpp
new file mode 100644 (file)
index 0000000..4b97077
--- /dev/null
@@ -0,0 +1,857 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasinterface.cpp
+**     \brief Template File
+**
+**     $Id: canvasinterface.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+//#include <iostream>
+
+#include <ETL/clock>
+#include <sinfg/valuenode_scale.h>
+#include <sinfg/valuenode_timedswap.h>
+#include <sinfg/valuenode_composite.h>
+#include <sinfg/valuenode_subtract.h>
+#include <sinfg/valuenode_linear.h>
+#include <sinfg/valuenode_reference.h>
+#include <sinfg/valuenode_twotone.h>
+#include <sinfg/valuenode_stripes.h>
+
+#include <sinfg/waypoint.h>
+#include <sinfg/loadcanvas.h>
+#include <sinfg/importer.h>
+#include <sinfg/guidset.h>
+
+#include "canvasinterface.h"
+#include "instance.h"
+
+#include "actions/layeradd.h"
+#include "actions/valuedescconvert.h"
+#include "actions/valuenodeadd.h"
+#include "actions/editmodeset.h"
+#include "action_system.h"
+
+#include "main.h"
+
+#include <sinfg/gradient.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CanvasInterface::CanvasInterface(loose_handle<Instance> instance,handle<Canvas> canvas):
+       instance_(instance),
+       canvas_(canvas),
+       cur_time_(canvas->rend_desc().get_frame_start()),
+       mode_(MODE_NORMAL|MODE_ANIMATE_PAST|MODE_ANIMATE_FUTURE)
+{
+       set_selection_manager(get_instance()->get_selection_manager());
+       set_ui_interface(get_instance()->get_ui_interface());
+}
+
+CanvasInterface::~CanvasInterface()
+{
+       sinfg::info("sinfgapp::CanvasInterface::~CanvasInterface(): Deleted");
+}
+
+void
+CanvasInterface::set_time(sinfg::Time x)
+{
+       if(get_canvas()->rend_desc().get_frame_rate())
+       {
+               float fps(get_canvas()->rend_desc().get_frame_rate());
+               Time r(x.round(fps));
+               //sinfg::info("CanvasInterface::set_time(): %s rounded to %s\n",x.get_string(fps).c_str(),r.get_string(fps).c_str());
+               x=r;
+       }
+       if(cur_time_.is_equal(x))
+               return;
+       cur_time_=x;
+       
+       signal_time_changed()();
+       signal_dirty_preview()();
+}
+       
+sinfg::Time
+CanvasInterface::get_time()const
+{
+       return cur_time_;
+}
+
+void 
+CanvasInterface::refresh_current_values()
+{
+       get_canvas()->set_time(cur_time_);
+       signal_time_changed()();
+       signal_dirty_preview()();
+}
+
+etl::handle<CanvasInterface>
+CanvasInterface::create(loose_handle<Instance> instance,handle<Canvas> canvas)
+{
+       etl::handle<CanvasInterface> intrfc;
+       intrfc=new CanvasInterface(instance,canvas);
+       instance->canvas_interface_list().push_front(intrfc);
+       return intrfc;
+}
+
+void
+CanvasInterface::set_mode(Mode x)
+{
+       Action::Handle  action(Action::EditModeSet::create());
+
+       assert(action);
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("edit_mode",x);
+       
+       if(!action->is_ready())
+       {
+               get_ui_interface()->error(_("Action Not Ready, unable to change mode"));
+               assert(0);
+               return;
+       }
+       
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Unable to change mode"));                  
+
+//     mode_=x;
+//     signal_mode_changed_(x);
+}
+
+CanvasInterface::Mode
+CanvasInterface::get_mode()const
+{
+       return mode_;
+}
+
+
+
+Layer::Handle
+CanvasInterface::add_layer_to(String name, Canvas::Handle canvas, int depth)
+{
+       sinfgapp::Action::PassiveGrouper group(get_instance().get(),_("Add Layer To"));
+
+       Layer::Handle   layer(Layer::create(name));
+       
+       assert(layer);
+       
+       if(!layer)
+               return 0;
+
+       if(canvas!=get_canvas() && !canvas->is_inline())
+       {
+               sinfg::error("Bad canvas passed to \"add_layer_to\"");
+               return 0;
+       }
+
+       layer->set_canvas(canvas);
+       
+       // Apply some defaults
+       if(layer->set_param("fg",sinfgapp::Main::get_foreground_color()))
+               layer->set_param("bg",sinfgapp::Main::get_background_color());
+       else
+               layer->set_param("color",sinfgapp::Main::get_foreground_color());
+
+       layer->set_param("width",sinfgapp::Main::get_bline_width().units(get_canvas()->rend_desc()));
+       layer->set_param("gradient",sinfgapp::Main::get_gradient());
+       if(name!="zoom")
+               layer->set_param("amount",sinfgapp::Main::get_opacity());
+       layer->set_param("blend_method",sinfgapp::Main::get_blend_method());
+
+       {
+               // Grab the layer's list pf parameters
+               Layer::ParamList paramlist=layer->get_param_list();
+               Layer::ParamList::iterator iter;
+               for(iter=paramlist.begin();iter!=paramlist.end();++iter)
+               {
+                       ValueNode::Handle value_node;
+                       
+                       if(iter->second.get_type()==ValueBase::TYPE_LIST)
+                               value_node=LinkableValueNode::create("dynamic_list",iter->second);
+                       else if(LinkableValueNode::check_type("composite",iter->second.get_type()) &&
+                               (iter->second.get_type()!=ValueBase::TYPE_COLOR && iter->second.get_type()!=ValueBase::TYPE_VECTOR)
+                       )
+                               value_node=LinkableValueNode::create("composite",iter->second);
+                       
+                       if(value_node)
+                               layer->connect_dynamic_param(iter->first,value_node);
+               }
+       }
+
+       // Action to add the layer
+       Action::Handle  action(Action::LayerAdd::create());
+
+       assert(action);
+       if(!action)
+               return 0;
+       
+       action->set_param("canvas",canvas);
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("new",layer);
+       
+       if(!action->is_ready())
+       {
+               get_ui_interface()->error(_("Action Not Ready"));                       
+               return 0;
+       }
+       
+       if(!get_instance()->perform_action(action))
+       {
+               get_ui_interface()->error(_("Action Failed."));                 
+               return 0;
+       }
+
+       sinfg::info("DEPTH=%d",depth);
+       // Action to move the layer (if necessary)
+       if(depth>0)
+       {
+               Action::Handle  action(Action::create("layer_move"));
+       
+               assert(action);
+               if(!action)
+                       return 0;
+               
+               action->set_param("canvas",canvas);
+               action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+               action->set_param("layer",layer);
+               action->set_param("new_index",depth);
+               
+               if(!action->is_ready())
+               {
+                       get_ui_interface()->error(_("Move Action Not Ready"));                  
+                       return 0;
+               }
+               
+               if(!get_instance()->perform_action(action))
+               {
+                       get_ui_interface()->error(_("Move Action Failed."));                    
+                       return 0;
+               }
+       }       
+       
+       
+       return layer;
+}
+
+
+bool
+CanvasInterface::convert(ValueDesc value_desc, String type)
+{
+       Action::Handle  action(Action::ValueDescConvert::create());
+
+       assert(action);
+       if(!action)
+               return 0;
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("value_desc",value_desc);
+       action->set_param("type",type);
+       
+       if(!action->is_ready())
+       {
+               get_ui_interface()->error(_("Action Not Ready"));                       
+               return 0;
+       }
+       
+       if(get_instance()->perform_action(action))
+               return true;
+       
+       get_ui_interface()->error(_("Action Failed."));                 
+       return false;
+}
+
+bool
+CanvasInterface::add_value_node(sinfg::ValueNode::Handle value_node, sinfg::String name)
+{
+       if(name.empty())
+       {
+               get_ui_interface()->error(_("Empty name!"));
+               return false;
+       }
+       
+       Action::Handle  action(Action::ValueNodeAdd::create());
+
+       assert(action);
+       if(!action)
+               return 0;
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("new",value_node);
+       action->set_param("name",name);
+       
+       if(!action->is_ready())
+       {
+               get_ui_interface()->error(_("Action Not Ready"));                       
+               return 0;
+       }
+       
+       if(get_instance()->perform_action(action))
+               return true;
+       
+       get_ui_interface()->error(_("Action Failed."));                 
+       return false;
+}
+
+Action::ParamList
+CanvasInterface::generate_param_list(const ValueDesc &value_desc)
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",get_time());
+       param_list.add("canvas_interface",etl::handle<CanvasInterface>(this));
+       param_list.add("canvas",get_canvas());
+
+       param_list.add("value_desc",value_desc);
+
+       if(value_desc.parent_is_value_node())
+               param_list.add("parent_value_node",value_desc.get_parent_value_node());
+       
+       if(value_desc.is_value_node())
+               param_list.add("value_node",value_desc.get_value_node());
+       
+       if(value_desc.is_const())
+               param_list.add("value",value_desc.get_value());
+
+       if(value_desc.parent_is_layer_param())
+       {
+               param_list.add("parent_layer",value_desc.get_layer());
+               param_list.add("parent_layer_param",value_desc.get_param_name());
+       }
+
+       {
+               sinfgapp::SelectionManager::ChildrenList children_list;
+               children_list=get_selection_manager()->get_selected_children();
+               if(!value_desc.parent_is_canvas() && children_list.size()==1)
+               {
+                       param_list.add("dest",value_desc);
+                       param_list.add("src",children_list.front().get_value_node());
+               }
+       }       
+       return param_list;
+}
+
+Action::ParamList
+CanvasInterface::generate_param_list(const std::list<sinfgapp::ValueDesc> &value_desc_list)
+{
+       sinfgapp::Action::ParamList param_list;
+       param_list.add("time",get_time());
+       param_list.add("canvas_interface",etl::handle<CanvasInterface>(this));
+       param_list.add("canvas",get_canvas());
+
+       std::list<sinfgapp::ValueDesc>::const_iterator iter;
+       for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
+       {
+               param_list.add("value_desc",*iter);
+               if(iter->is_value_node())
+               {
+                       param_list.add("value_node",iter->get_value_node());                    
+               }
+       }
+
+
+       return param_list;
+}
+
+void
+CanvasInterface::set_rend_desc(const sinfg::RendDesc &rend_desc)
+{
+       Action::Handle  action(Action::create("canvas_rend_desc_set"));
+
+       assert(action);
+       if(!action)
+               return;
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("rend_desc",rend_desc);
+               
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Action Failed."));                 
+}
+
+bool
+CanvasInterface::set_name(const String &x)
+{
+       //! \todo This needs to be converted into an action
+       get_canvas()->set_name(x);
+       signal_id_changed_();
+       return true;
+}
+
+bool
+CanvasInterface::set_description(const String &x)
+{
+       //! \todo This needs to be converted into an action
+       get_canvas()->set_description(x);
+       return true;
+}
+
+bool
+CanvasInterface::set_id(const String &x)
+{
+       //! \todo This needs to be converted into an action
+       get_canvas()->set_id(x);
+       signal_id_changed_();
+       return true;
+}
+
+
+void
+CanvasInterface::jump_to_next_keyframe()
+{
+       sinfg::info("Current time: %s",get_time().get_string().c_str());
+       try
+       {
+               sinfg::Keyframe keyframe(*get_canvas()->keyframe_list().find_next(get_time()));
+               sinfg::info("Jumping to keyframe \"%s\" at %s",keyframe.get_description().c_str(),keyframe.get_time().get_string().c_str());
+               set_time(keyframe.get_time());
+       }
+       catch(...) { sinfg::warning("Unable to find next keyframe"); }
+}
+
+void
+CanvasInterface::jump_to_prev_keyframe()
+{
+       sinfg::info("Current time: %s",get_time().get_string().c_str());
+       try
+       {
+               sinfg::Keyframe keyframe(*get_canvas()->keyframe_list().find_prev(get_time()));
+               sinfg::info("Jumping to keyframe \"%s\" at %s",keyframe.get_description().c_str(),keyframe.get_time().get_string().c_str());
+               set_time(keyframe.get_time());
+       }
+       catch(...) { sinfg::warning("Unable to find prev keyframe"); }
+}
+
+bool
+CanvasInterface::import(const sinfg::String &filename, bool copy)
+{
+       Action::PassiveGrouper group(get_instance().get(),_("Import Image"));
+       
+       sinfg::info("Attempting to import "+filename);
+
+
+       if(find(filename.begin(),filename.end(),'.')==filename.end())
+       {
+               get_ui_interface()->error("Filename must have an extension!");
+               return false;
+       }
+
+       String ext(String(filename.begin()+filename.find_last_of('.')+1,filename.end()));
+       std::transform(ext.begin(),ext.end(),ext.begin(),&::tolower);
+
+       // If this is a SIF file, then we need to do things slightly differently
+       if(ext=="sif" || ext=="sifz")try
+       {
+               
+               Canvas::Handle outside_canvas(sinfg::open_canvas(filename));
+               if(!outside_canvas)
+                       throw String(_("Unable to open this composition"));
+
+               Layer::Handle layer(add_layer_to("PasteCanvas",get_canvas()));
+               if(!layer)
+                       throw String(_("Unable to create \"PasteCanvas\" layer"));
+               if(!layer->set_param("canvas",ValueBase(outside_canvas)))
+                       throw int();
+
+               //layer->set_description(basename(filename));
+               signal_layer_new_description()(layer,filename);
+               return true;
+       }
+       catch(String x)
+       {
+               get_ui_interface()->error(x+" -- "+filename);
+               return false;
+       }
+       catch(...)
+       {
+               get_ui_interface()->error(_("Uncaught exception when attempting\nto open this composition -- ")+filename);
+               return false;
+       }
+       
+       
+       
+       if(!Importer::book().count(ext))
+       {
+               get_ui_interface()->error(_("I don't know how to open images of this type -- ")+ext);
+               return false;
+       }
+
+       try
+       {
+               Layer::Handle layer(add_layer_to("Import",get_canvas()));
+               int w,h;
+               if(!layer)
+                       throw int();
+               if(!layer->set_param("filename",ValueBase(filename)))
+                       throw int();
+               w=layer->get_param("_width").get(int());
+               h=layer->get_param("_height").get(int());
+               if(w&&h)
+               {
+                       Vector size=ValueBase(get_canvas()->rend_desc().get_br()-get_canvas()->rend_desc().get_tl());
+                       Vector x;
+                       if(size[0]<size[1])
+                       {
+                               x[0]=size[0];
+                               x[1]=size[0]/w*h;
+                               if(size[0]<0 ^ size[1]<0)
+                                       x[1]=-x[1];
+                       }
+                       else
+                       {
+                               x[1]=size[1];
+                               x[0]=size[1]/h*w;
+                               if(size[0]<0 ^ size[1]<0)
+                                       x[0]=-x[0];
+                       }
+                       if(!layer->set_param("tl",ValueBase(-x/2)))
+                               throw int();
+                       if(!layer->set_param("br",ValueBase(x/2)))
+                               throw int();
+               }
+               else
+               {
+                       if(!layer->set_param("tl",ValueBase(get_canvas()->rend_desc().get_tl())))
+                               throw int();
+                       if(!layer->set_param("br",ValueBase(get_canvas()->rend_desc().get_br())))
+                               throw int();
+               }
+
+               layer->set_description(basename(filename));
+               signal_layer_new_description()(layer,filename);
+       
+               return true;            
+       }
+       catch(...)
+       {
+               get_ui_interface()->error("Unable to import "+filename);
+               group.cancel();
+               return false;
+       }
+}
+
+
+void
+CanvasInterface::waypoint_duplicate(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint)
+{
+       Action::Handle  action(Action::create("waypoint_set_smart"));
+
+       assert(action);
+       if(!action)
+               return;
+       
+       waypoint.make_unique();
+       waypoint.set_time(get_time());
+
+       ValueNode::Handle value_node(value_desc.get_value_node());
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("waypoint",waypoint);
+       action->set_param("time",get_time());
+       action->set_param("value_node",value_node);
+               
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Action Failed."));                 
+}
+
+void
+CanvasInterface::waypoint_remove(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint)
+{
+       Action::Handle  action(Action::create("waypoint_remove"));
+
+       assert(action);
+       if(!action)
+               return;
+       
+       ValueNode::Handle value_node(value_desc.get_value_node());
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("waypoint",waypoint);
+       action->set_param("value_node",value_node);
+               
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Action Failed."));                 
+}
+
+
+void
+CanvasInterface::auto_export(ValueNode::Handle value_node)
+{
+/*
+       // Check to see if we are already exported.
+       if(value_node->is_exported())
+               return;
+
+       Action::Handle  action(Action::create("value_node_add"));
+
+       assert(action);
+       if(!action)
+               return;
+       
+       String name(strprintf(_("Unnamed%08d"),sinfg::UniqueID().get_uid()));
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("new",value_node);
+       action->set_param("name",name);
+               
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Action Failed."));                 
+*/
+}
+
+void
+CanvasInterface::auto_export(const ValueDesc& value_desc)
+{      
+       // THIS FUNCTION IS DEPRECATED, AND IS NOW A STUB.
+#if 0  
+       // Check to see if we are already exported.
+       if(value_desc.is_exported())
+               return;
+
+       Action::Handle  action(Action::create("value_desc_export"));
+
+       assert(action);
+       if(!action)
+               return;
+       
+       String name(strprintf(_("Unnamed%08d"),sinfg::UniqueID().get_uid()));
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("value_desc",value_desc);
+       action->set_param("name",name);
+               
+       if(!get_instance()->perform_action(action))
+               get_ui_interface()->error(_("Action Failed."));                 
+#endif
+}
+
+bool
+CanvasInterface::change_value(sinfgapp::ValueDesc value_desc,sinfg::ValueBase new_value)
+{
+       // If this isn't really a change, then don't bother
+       if(new_value==value_desc.get_value(get_time()))
+               return true;
+               
+       // If this change needs to take place elsewhere, then so be it.
+       if(value_desc.get_canvas() && value_desc.get_canvas()->get_root()!=get_canvas()->get_root())do
+       {
+               etl::handle<Instance> instance;
+               instance=find_instance(value_desc.get_canvas()->get_root());
+               
+               if(instance)
+                       return instance->find_canvas_interface(value_desc.get_canvas())->change_value(value_desc,new_value);
+               else
+               {
+                       get_ui_interface()->error(_("The value you are trying to edit is in a composition\nwhich doesn't seem to be open. Open that composition and you\nshould be able to edit this value as normal."));                       
+                       return false;
+               }
+       }while(0);
+#ifdef _DEBUG
+       else
+       { sinfg::warning("Can't get canvas from value desc...?"); }
+#endif
+       
+       sinfgapp::Action::Handle action(sinfgapp::Action::create("value_desc_set"));
+       if(!action)
+       {
+               return false;
+       }
+       
+       action->set_param("canvas",get_canvas());
+       action->set_param("canvas_interface",etl::loose_handle<CanvasInterface>(this));
+       action->set_param("time",get_time());
+       action->set_param("value_desc",value_desc);
+       action->set_param("new_value",new_value);
+
+       return get_instance()->perform_action(action);
+}
+
+void
+CanvasInterface::set_meta_data(const sinfg::String& key,const sinfg::String& data)
+{
+       get_canvas()->set_meta_data(key,data);
+}
+
+
+// this function goes with find_important_value_descs()
+static int
+_process_value_desc(const sinfgapp::ValueDesc& value_desc,std::vector<sinfgapp::ValueDesc>& out, sinfg::GUIDSet& guid_set)
+{
+       int ret(0);
+
+       if(value_desc.get_value_type()==ValueBase::TYPE_CANVAS)
+       {
+               Canvas::Handle canvas;
+               canvas=value_desc.get_value().get(canvas);
+               if(!canvas || !canvas->is_inline())
+                       return ret;
+               ret+=CanvasInterface::find_important_value_descs(canvas,out,guid_set);
+       }
+       
+       if(value_desc.is_value_node())
+       {
+               ValueNode::Handle value_node(value_desc.get_value_node());
+
+               if(guid_set.count(value_node->get_guid()))
+                       return ret;
+               guid_set.insert(value_node->get_guid());
+               
+               if(LinkableValueNode::Handle::cast_dynamic(value_node))
+               {
+                       if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
+                       {
+                               out.push_back(value_desc);
+                               ret++;
+                       }
+                       // Process the linkable ValueNode's children
+                       LinkableValueNode::Handle value_node(LinkableValueNode::Handle::cast_dynamic(value_node));
+                       int i;
+                       for(i=0;i<value_node->link_count();i++)
+                       {
+                               ValueNode::Handle link(value_node->get_link(i));
+                               if(!link->is_exported())
+                                       ret+=_process_value_desc(ValueDesc(value_node,i),out,guid_set);
+                       }
+               }
+               else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
+               {
+                       out.push_back(value_desc);
+                       ret++;
+               }
+       }
+       
+       return ret;
+}
+
+int
+CanvasInterface::find_important_value_descs(sinfg::Canvas::Handle canvas,std::vector<sinfgapp::ValueDesc>& out,sinfg::GUIDSet& guid_set)
+{
+       int ret(0);
+       if(!canvas->is_inline())
+       {
+               ValueNodeList::const_iterator iter;
+       
+               for(
+                       iter=canvas->value_node_list().begin();
+                       iter!=canvas->value_node_list().end();
+                       ++iter)
+                       ret+=_process_value_desc(ValueDesc(canvas,(*iter)->get_id()),out,guid_set);
+       }
+
+       Canvas::const_iterator iter;
+       
+       for(iter=canvas->begin();iter!=canvas->end();++iter)
+       {
+               Layer::Handle layer(*iter);
+               
+               Layer::DynamicParamList::const_iterator iter;
+               for(
+                       iter=layer->dynamic_param_list().begin();
+                       iter!=layer->dynamic_param_list().end();
+                       ++iter)
+               {
+                       if(!iter->second->is_exported())
+                               ret+=_process_value_desc(ValueDesc(layer,iter->first),out,guid_set);
+               }
+               ValueBase value(layer->get_param("canvas"));
+               if(value.is_valid())
+                       ret+=_process_value_desc(ValueDesc(layer,"canvas"),out,guid_set);
+       }
+       
+       return ret;
+}
+
+int
+CanvasInterface::find_important_value_descs(std::vector<sinfgapp::ValueDesc>& out)
+{
+       sinfg::GUIDSet tmp;
+       return find_important_value_descs(get_canvas(),out,tmp);
+}
+
+void
+CanvasInterface::seek_frame(int frames)
+{
+       if(!frames)
+               return;
+       float fps(get_canvas()->rend_desc().get_frame_rate());
+       Time newtime(get_time()+(float)frames/fps);
+       newtime=newtime.round(fps);
+
+       if(newtime<=get_canvas()->rend_desc().get_frame_start())
+               newtime=get_canvas()->rend_desc().get_frame_start();
+       if(newtime>=get_canvas()->rend_desc().get_frame_end())
+               newtime=get_canvas()->rend_desc().get_frame_end();
+       set_time(newtime);
+}
+
+void
+CanvasInterface::seek_time(sinfg::Time time)
+{
+       if(!time)
+               return;
+       
+       float fps(get_canvas()->rend_desc().get_frame_rate());
+
+       if(time>=sinfg::Time::end())
+       {
+               set_time(get_canvas()->rend_desc().get_time_end());
+               return;
+       }
+       if(time<=sinfg::Time::begin())
+       {
+               set_time(get_canvas()->rend_desc().get_time_end());
+               return;
+       }
+               
+       Time newtime(get_time()+time);
+       newtime=newtime.round(fps);
+
+       if(newtime<=get_canvas()->rend_desc().get_time_start())
+               newtime=get_canvas()->rend_desc().get_time_start();
+       if(newtime>=get_canvas()->rend_desc().get_time_end())
+               newtime=get_canvas()->rend_desc().get_time_end();
+       set_time(newtime);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/canvasinterface.h b/synfig-studio/trunk/src/sinfgapp/canvasinterface.h
new file mode 100644 (file)
index 0000000..79a548c
--- /dev/null
@@ -0,0 +1,308 @@
+/* === S I N F G =========================================================== */
+/*!    \file canvasinterface.h
+**     \brief Template Header
+**
+**     $Id: canvasinterface.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_CANVASINTERFACE_H
+#define __SINFG_APP_CANVASINTERFACE_H
+
+/* === H E A D E R S ======================================================= */
+
+//#include <sinfg/canvas.h>
+#include <sinfg/value.h>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include <list>
+#include "selectionmanager.h"
+#include "uimanager.h"
+#include "value_desc.h"
+#include "editmode.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg { class ValueNode_DynamicList; class Waypoint; class GUIDSet; class Canvas; };
+
+namespace sinfgapp {
+
+namespace Action { class ParamList; class Param; class EditModeSet; }; 
+
+class Instance;
+class ValueDesc;
+       
+class CanvasInterface : public etl::shared_object, public sigc::trackable
+{
+       friend class Instance;
+       friend class Action::EditModeSet;
+               
+public:
+
+       typedef EditMode Mode;
+
+private:
+       // Constructor is private to force the use of the "create()" constructor.
+       CanvasInterface(etl::loose_handle<Instance> instance,etl::handle<sinfg::Canvas> canvas);
+
+private:
+       etl::loose_handle<Instance> instance_;
+       etl::handle<sinfg::Canvas> canvas_;
+       etl::handle<SelectionManager> selection_manager_;
+       etl::handle<UIInterface> ui_interface_;
+       sinfg::Time cur_time_;
+       Mode mode_;
+
+       sigc::signal<void,sinfg::Layer::Handle> signal_layer_raised_;
+       sigc::signal<void,sinfg::Layer::Handle> signal_layer_lowered_;
+       sigc::signal<void,sinfg::Layer::Handle,int> signal_layer_inserted_;
+       sigc::signal<void,sinfg::Layer::Handle,int,sinfg::Canvas::Handle> signal_layer_moved_;
+       sigc::signal<void,sinfg::Layer::Handle> signal_layer_removed_;
+       sigc::signal<void,sinfg::Layer::Handle,bool> signal_layer_status_changed_;
+       sigc::signal<void,sinfg::Layer::Handle,sinfg::String> signal_layer_new_description_;
+       sigc::signal<void,sinfg::Canvas::Handle> signal_canvas_added_;
+       sigc::signal<void,sinfg::Canvas::Handle> signal_canvas_removed_;
+       
+       sigc::signal<void,sinfg::ValueNode::Handle> signal_value_node_added_;
+       sigc::signal<void,sinfg::ValueNode::Handle> signal_value_node_deleted_;
+       sigc::signal<void,sinfg::ValueNode::Handle> signal_value_node_changed_;
+       sigc::signal<void,sinfg::ValueNode::Handle,sinfg::ValueNode::Handle> signal_value_node_replaced_;
+
+       sigc::signal<void,sinfg::Keyframe> signal_keyframe_added_;
+       sigc::signal<void,sinfg::Keyframe> signal_keyframe_removed_;
+       sigc::signal<void,sinfg::Keyframe> signal_keyframe_changed_;
+
+       sigc::signal<void> signal_id_changed_;
+
+       sigc::signal<void> signal_time_changed_;
+
+       sigc::signal<void> signal_rend_desc_changed_;
+
+       sigc::signal<void,Mode> signal_mode_changed_;
+
+       //sigc::signal<void> signal_dirty_preview_;
+
+       sigc::signal<void,sinfg::Layer::Handle,sinfg::String> signal_layer_param_changed_;
+
+public:        // Signal Interface
+
+       sigc::signal<void,sinfg::Layer::Handle,int,sinfg::Canvas::Handle>& signal_layer_moved() { return signal_layer_moved_; }
+
+       sigc::signal<void,sinfg::Layer::Handle,sinfg::String>& signal_layer_new_description() { return signal_layer_new_description_; }
+
+       //! Signal called when layer is raised.
+       sigc::signal<void,sinfg::Layer::Handle>& signal_layer_raised() { return signal_layer_raised_; }
+       
+       //! Signal called when layer is lowered.
+       sigc::signal<void,sinfg::Layer::Handle>& signal_layer_lowered() { return signal_layer_lowered_; }
+       
+       //! Signal called when layer has been inserted at a given position.
+       sigc::signal<void,sinfg::Layer::Handle,int>& signal_layer_inserted() { return signal_layer_inserted_; }
+
+       //! Signal called when a layer has been removed from the canvas.
+       sigc::signal<void,sinfg::Layer::Handle>& signal_layer_removed() { return signal_layer_removed_; }
+
+       //! Signal called when the layer's active status has changed.
+       sigc::signal<void,sinfg::Layer::Handle,bool>& signal_layer_status_changed() { return signal_layer_status_changed_; }
+
+       //! Signal called when a canvas has been added.
+       sigc::signal<void,etl::handle<sinfg::Canvas> >& signal_canvas_added() { return signal_canvas_added_; }
+
+       //! Signal called when a canvas has been removed.
+       sigc::signal<void,etl::handle<sinfg::Canvas> >& signal_canvas_removed() { return signal_canvas_removed_; }
+
+       //! Signal called when a layer's parameter has been changed
+       sigc::signal<void,sinfg::Layer::Handle,sinfg::String>& signal_layer_param_changed() { return signal_layer_param_changed_; }
+
+       //! Signal called when the canvas's preview needs to be updated
+       //sigc::signal<void>& signal_dirty_preview() { return signal_dirty_preview_; }
+       sigc::signal<void>& signal_dirty_preview() { return get_canvas()->signal_dirty(); }
+
+       sigc::signal<void,etl::handle<sinfg::ValueNode>,etl::handle<sinfg::ValueNode> >&
+               signal_value_node_child_added() { return get_canvas()->signal_value_node_child_added(); }
+       sigc::signal<void,etl::handle<sinfg::ValueNode>,etl::handle<sinfg::ValueNode> >&
+               signal_value_node_child_removed() { return get_canvas()->signal_value_node_child_removed(); }
+
+       //! Signal called when a ValueNode has changed
+       sigc::signal<void,etl::handle<sinfg::ValueNode> >& signal_value_node_added() { return signal_value_node_added_; }
+
+       //! Signal called when a ValueNode has been deleted
+       sigc::signal<void,etl::handle<sinfg::ValueNode> >& signal_value_node_deleted() { return signal_value_node_deleted_; }
+
+       //! Signal called when a ValueNode has been changed
+       sigc::signal<void,etl::handle<sinfg::ValueNode> >& signal_value_node_changed() { return get_canvas()->signal_value_node_changed(); }
+       //sigc::signal<void,etl::handle<sinfg::ValueNode> >& signal_value_node_changed() { return signal_value_node_changed_; }
+
+       //! Signal called when the mode has changed
+       sigc::signal<void,Mode> signal_mode_changed() { return signal_mode_changed_; }
+
+       //! Signal called when a the ID has been changed
+       sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
+
+       //! Signal called whenever the time changes
+       sigc::signal<void> signal_time_changed() { return signal_time_changed_; }
+
+       //! Signal called whenever a data node has been replaced.
+       /*!     Second ValueNode replaces first */
+       sigc::signal<void,sinfg::ValueNode::Handle,sinfg::ValueNode::Handle>& signal_value_node_replaced()
+               { return signal_value_node_replaced_; }
+
+       //! Signal called whenever the RendDesc changes
+       sigc::signal<void>& signal_rend_desc_changed() { return signal_rend_desc_changed_; }
+
+       sigc::signal<void,sinfg::Keyframe>& signal_keyframe_added() { return signal_keyframe_added_; }
+
+       sigc::signal<void,sinfg::Keyframe>& signal_keyframe_removed() { return signal_keyframe_removed_; }
+
+       sigc::signal<void,sinfg::Keyframe>& signal_keyframe_changed() { return signal_keyframe_changed_; }
+
+public:
+
+       void auto_export(const ValueDesc& value_desc);
+
+       void auto_export(sinfg::ValueNode::Handle value_node);
+
+       void set_meta_data(const sinfg::String& key,const sinfg::String& data);
+
+       //! Changes the current SelectionManager object
+       void set_selection_manager(const etl::handle<SelectionManager> &sm) { selection_manager_=sm; }
+       
+       //! Disables the selection manager
+       void unset_selection_manager() { selection_manager_=new NullSelectionManager(); }
+       
+       //! Returns a handle to the current SelectionManager
+       const etl::handle<SelectionManager> &get_selection_manager()const { return selection_manager_; }        
+
+       //! Changes the current UIInterface object
+       void set_ui_interface(const etl::handle<UIInterface> &uim) { ui_interface_=uim; }
+
+       //! Disables the UIInterface
+       void unset_ui_interface() { ui_interface_=new DefaultUIInterface(); }
+       
+       //! Returns a handle to the current UIInterface
+       const etl::handle<UIInterface> &get_ui_interface() { return ui_interface_; }    
+
+       //! Returns the Canvas associated with this interface
+       etl::handle<sinfg::Canvas> get_canvas()const { return canvas_; }
+
+       //! Returns the Instance associated with this interface
+       etl::loose_handle<Instance> get_instance()const { return instance_; }
+
+       //! Changes the name of the canvas. Undoable.
+       bool set_name(const sinfg::String &x);
+
+       //! Changes the description of the canvas. Undoable.
+       bool set_description(const sinfg::String &x);
+
+       //! Changes the ID of the canvas. Undoable.
+       bool set_id(const sinfg::String &x);
+       
+       //! Convience function to retrieve the name of the canvas
+       sinfg::String get_name()const { return get_canvas()->get_name(); }
+
+       //! Convience function to retrieve the description of the canvas
+       sinfg::String get_description()const { return get_canvas()->get_description(); }
+
+       //! Convience function to retrieve the ID of the canvas
+       sinfg::String get_id()const { return get_canvas()->get_id(); }
+
+       //! Sets the current time
+       void set_time(sinfg::Time x);
+       
+       //! Retrieves the current time
+       sinfg::Time get_time()const;
+       
+       //! Changes the current time to the next keyframe
+       void jump_to_next_keyframe();
+
+       //! Changes the current time to the next keyframe
+       void jump_to_prev_keyframe();
+       
+       void seek_frame(int frames);
+
+       void seek_time(sinfg::Time time);
+       
+       //! \writeme
+       void refresh_current_values();
+       
+       //! Sets the current editing mode
+       /*! \see Mode */
+       void set_mode(Mode x);
+
+       //! Retrieves the current editing mode
+       /*! \see Mode */
+       Mode get_mode()const;
+
+       //! Creates a new layer, of type \c id at the top of the layer stack
+       sinfg::Layer::Handle add_layer(sinfg::String id) { return add_layer_to(id,get_canvas()); }
+
+       sinfg::Layer::Handle add_layer_to(sinfg::String id,sinfg::Canvas::Handle canvas, int depth=0);
+
+       bool convert(ValueDesc value_desc, sinfg::String type);
+       //! Adds the given ValueNode to the canvas.
+       bool add_value_node(sinfg::ValueNode::Handle value_node, sinfg::String name);
+
+
+       Action::ParamList generate_param_list(const sinfgapp::ValueDesc &);
+
+       Action::ParamList generate_param_list(const std::list<sinfgapp::ValueDesc> &);
+
+       void set_rend_desc(const sinfg::RendDesc &rend_desc);
+
+       bool import(const sinfg::String &filename, bool copy=false);
+       
+       
+       void waypoint_duplicate(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint);
+
+       void waypoint_remove(sinfgapp::ValueDesc value_desc,sinfg::Waypoint waypoint);
+
+       bool change_value(sinfgapp::ValueDesc value_desc,sinfg::ValueBase new_value);
+
+
+       int find_important_value_descs(std::vector<sinfgapp::ValueDesc>& out);
+       static int find_important_value_descs(sinfg::Canvas::Handle canvas,std::vector<sinfgapp::ValueDesc>& out,sinfg::GUIDSet& guid_set);
+
+       ~CanvasInterface();
+
+       static etl::handle<CanvasInterface> create(etl::loose_handle<Instance> instance,etl::handle<sinfg::Canvas> canvas);
+}; // END of class CanvasInterface
+
+/*!    \class PushMode
+**     \brief Class that changes the mode of a CanvasInterface, and restores it on destruction.
+*/
+class PushMode
+{
+       CanvasInterface* canvas_interface_;
+       CanvasInterface::Mode old_mode_;
+public:
+       PushMode(etl::loose_handle<CanvasInterface> c, CanvasInterface::Mode mode):
+               canvas_interface_(c.get()), old_mode_(canvas_interface_->get_mode())
+       { canvas_interface_->set_mode(mode); }
+       
+       ~PushMode() { canvas_interface_->set_mode(old_mode_); }
+}; // END of class PushMode
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/cvs.cpp b/synfig-studio/trunk/src/sinfgapp/cvs.cpp
new file mode 100644 (file)
index 0000000..65a16a2
--- /dev/null
@@ -0,0 +1,375 @@
+/* === S I N F G =========================================================== */
+/*!    \file cvs.cpp
+**     \brief Template File
+**
+**     $Id: cvs.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "cvs.h"
+#include <ETL/stringf>
+#include <fstream>
+#include <iostream>
+#include <sinfg/general.h>
+#include <stdlib.h>
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+//#include <unistd.h>
+
+#include <cassert>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+#define cvs_command            sinfg::String("cvs -z4")
+
+#ifndef WIN32
+#define HAVE_STRPTIME
+#endif
+
+#ifdef __APPLE__
+time_t _daylight_() { time_t t(time(0)); return localtime(&t)->tm_gmtoff; }
+#define daylight _daylight_()
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CVSInfo::CVSInfo(const sinfg::String& file_name)
+{
+       update_available_=false;
+       set_file_name(file_name);
+}
+
+CVSInfo::CVSInfo()
+{
+       update_available_=false;
+}
+
+CVSInfo::~CVSInfo()
+{
+}
+
+void
+CVSInfo::set_file_name(const sinfg::String& file_name)
+{
+       file_name_=file_name;
+       
+       std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str());
+
+       if(file)
+       {
+               in_sandbox_=true;
+               calc_repository_info();
+       }
+       else
+               in_sandbox_=false;
+}
+
+void
+CVSInfo::calc_repository_info()
+{
+#ifdef _DEBUG
+       sinfg::info("in_sandbox() = %d",in_sandbox());
+#endif
+       
+       if(!in_sandbox_)
+               return;
+       
+       std::ifstream file((dirname(file_name_)+"/CVS/Entries").c_str());
+
+       while(file)
+       {
+               String line;
+               getline(file,line);
+               if(line.find(basename(file_name_))!=String::npos)
+               {
+                       in_repository_=true;
+                       String::size_type s,f;
+                       
+                       // Grab the version
+                       s=line.find('/',1);
+                       assert(s!=String::npos);
+                       s++;
+                       f=line.find('/',s+1);
+                       assert(f!=String::npos);
+                       cvs_version_=String(line,s,f-s);
+                       
+                       // Grab the time
+#ifdef HAVE_STRPTIME
+                       s=f+1;
+                       f=line.find('/',s+1);
+                       assert(f!=String::npos);
+                       tm time_struct;
+                       strptime(String(line,s,f-s).c_str(),"%c",&time_struct);
+                       original_timestamp_=mktime(&time_struct);
+#endif
+                       
+                       if(
+                               system(strprintf(
+                                       "cd '%s' && cvs status '%s' | grep -q -e 'Needs Patch'",
+                                       dirname(file_name_).c_str(),
+                                       basename(file_name_).c_str()
+                               ).c_str())==0
+                       )
+                       {
+                               sinfg::info("UPDATE_AVAILABLE=TRUE");
+                               update_available_=true;
+                       }
+                       else
+                       {
+                               system(strprintf(
+                                       "cd '%s' && cvs status '%s'",
+                                       dirname(file_name_).c_str(),
+                                       basename(file_name_).c_str()
+                               ).c_str());
+                               sinfg::info("UPDATE_AVAILABLE=FALSE");
+                               update_available_=false;
+                       }
+                               
+                       
+#ifdef _DEBUG
+                       sinfg::info("in_repository() = %d",in_repository());
+                       sinfg::info("get_cvs_version() = %s",get_cvs_version().c_str());
+                       sinfg::info("get_original_timestamp() = %s",ctime(&get_original_timestamp()));
+                       time_t t(get_current_timestamp());
+                       sinfg::info("get_current_timestamp() = %s",ctime(&t));
+                       sinfg::info("get_cvs_root() = %s",get_cvs_root().c_str());
+                       sinfg::info("get_cvs_module() = %s",get_cvs_module().c_str());
+#endif                 
+                       return;
+               }
+       }
+
+       in_repository_=false;
+       cvs_version_.clear();
+       original_timestamp_=0;
+
+#ifdef _DEBUG
+       sinfg::info("in_repository() = %d",in_repository());
+#endif
+}
+
+bool
+CVSInfo::in_sandbox()const
+{
+       return in_sandbox_;
+}
+
+bool
+CVSInfo::in_repository()const
+{
+       if(!in_sandbox_)
+               return false;
+       return in_repository_;
+}
+
+bool
+CVSInfo::is_modified()const
+{
+#ifdef _DEBUG
+       sinfg::info("%d-%d=%d",get_current_timestamp(),get_original_timestamp(),get_current_timestamp()-get_original_timestamp());
+#endif
+       if(!in_sandbox() || !in_repository())
+               return false;
+       return get_current_timestamp()!=get_original_timestamp() && abs(get_current_timestamp()-get_original_timestamp())!=3600;
+}
+
+bool
+CVSInfo::is_updated()const
+{
+       return update_available_;
+}
+
+const sinfg::String&
+CVSInfo::get_cvs_version()const
+{
+       return cvs_version_;
+}
+
+const time_t&
+CVSInfo::get_original_timestamp()const
+{
+       return original_timestamp_;
+}
+
+time_t
+CVSInfo::get_current_timestamp()const
+{
+       struct stat st;
+       if(stat(file_name_.c_str(),&st)<0)
+       {
+               sinfg::error("Unable to get file stats");
+               return false;
+       }
+       return st.st_mtime+timezone+(daylight-1)*3600;
+}
+
+sinfg::String
+CVSInfo::get_cvs_root()const
+{
+       if(!in_sandbox_)
+               return sinfg::String();
+       
+       std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str());
+
+       if(file)
+       {
+               String ret;
+               getline(file,ret);
+               return ret;
+       }
+
+       return sinfg::String();
+}
+
+sinfg::String
+CVSInfo::get_cvs_module()const
+{
+       if(!in_sandbox_)
+               return sinfg::String();
+
+       std::ifstream file((dirname(file_name_)+"/CVS/Repository").c_str());
+
+       if(file)
+       {
+               String ret;
+               getline(file,ret);
+               return ret;
+       }
+
+       return sinfg::String();
+}
+
+// This function pre-processes the message so that we
+// don't get any CVS syntax errors.
+inline sinfg::String fix_msg(const sinfg::String& message)
+{
+       sinfg::String ret;
+       int i;
+       for(i=0;i<(int)message.size();i++)
+       {
+               if(message[i]=='\'')
+                       ret+="'\"'\"'";
+               else
+                       ret+=message[i];
+       }
+       return ret;
+}
+
+void
+CVSInfo::cvs_add(const sinfg::String& message)
+{
+       if(!in_sandbox_)
+       {
+               sinfg::error("cvs_add(): Not in a sand box");
+               throw int();
+               return;
+       }
+       
+       sinfg::String command(strprintf("cd '%s' && %s add -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str()));
+       
+       int ret(system(command.c_str()));
+       
+       calc_repository_info();
+
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               sinfg::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               throw(ret);
+               break;
+       }
+}
+       
+void
+CVSInfo::cvs_update()
+{
+       if(!in_sandbox_)
+       {
+               sinfg::error("cvs_update(): Not in a sand box");
+               throw int();
+               return;
+       }
+       
+       sinfg::String command(strprintf("cd '%s' && %s update '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),basename(file_name_).c_str()));
+       
+       int ret(system(command.c_str()));
+
+       calc_repository_info();
+       
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               sinfg::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               throw(ret);
+               break;
+       }
+}
+       
+void
+CVSInfo::cvs_commit(const sinfg::String& message)
+{
+       if(!in_sandbox_)
+       {
+               sinfg::error("cvs_commit(): Not in a sand box");
+               throw int();
+               return;
+       }
+       
+       sinfg::String command(strprintf("cd '%s' && %s commit -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str()));
+       
+       int ret(system(command.c_str()));
+
+       calc_repository_info();
+       
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               sinfg::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               if(is_modified())
+                       throw(ret);
+               break;
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/cvs.h b/synfig-studio/trunk/src/sinfgapp/cvs.h
new file mode 100644 (file)
index 0000000..b25c6e0
--- /dev/null
@@ -0,0 +1,103 @@
+/* === S I N F G =========================================================== */
+/*!    \file cvs.h
+**     \brief Template Header
+**
+**     $Id: cvs.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_CVS_H
+#define __SINFG_CVS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/string.h>
+#include <time.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class CVSInfo
+{
+       sinfg::String file_name_;
+
+       bool in_sandbox_;
+       bool in_repository_;
+       bool update_available_;
+       
+       sinfg::String cvs_version_;
+       time_t original_timestamp_;
+       
+       
+public:
+       void calc_repository_info();
+       
+       CVSInfo(const sinfg::String& file_name);
+       CVSInfo();
+       ~CVSInfo();
+
+       void set_file_name(const sinfg::String& file_name);
+
+//     READ OPERATIONS --------------------------------------------------
+
+       //! Returns TRUE if \a file_name is in a sandbox
+       bool in_sandbox()const;
+       
+       //! Returns TRUE if \a file_name is in the repository
+       bool in_repository()const;
+
+       //! Returns TRUE if \a file_name has modifications not yet on the repository
+       bool is_modified()const;
+
+       //! Returns TRUE if there is a new version of \a file_name on the repository
+       bool is_updated()const;
+
+       //! Returns the CVS version string
+       const sinfg::String& get_cvs_version()const;
+       
+       //! Returns the unix timestamp of the repository file
+       const time_t &get_original_timestamp()const;
+
+       //! Returns the unix timestamp of the checked out file
+       time_t get_current_timestamp()const;
+
+       //! Returns the Root
+       sinfg::String get_cvs_root()const;
+
+       //! Returns the name of the module
+       sinfg::String get_cvs_module()const;
+                       
+//     WRITE OPERATIONS -------------------------------------------------
+       
+       void cvs_add(const sinfg::String& message=sinfg::String());
+       
+       void cvs_update();
+       
+       void cvs_commit(const sinfg::String& message=sinfg::String());
+}; // END of class CVSInfo
+       
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/editmode.h b/synfig-studio/trunk/src/sinfgapp/editmode.h
new file mode 100644 (file)
index 0000000..7bc4874
--- /dev/null
@@ -0,0 +1,83 @@
+/* === S I N F G =========================================================== */
+/*!    \file editmode.h
+**     \brief Template Header
+**
+**     $Id: editmode.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_EDITMODE_H
+#define __SINFG_EDITMODE_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+       
+/*!    \enum EditMode
+**     \brief \writeme
+*/
+enum EditMode
+{
+       MODE_NORMAL                     =0,                     //!< Normal editing mode. Place holder.
+
+       MODE_ANIMATE            =(1<<0),        //!< Animated editing mode.
+       MODE_ANIMATE_FUTURE     =(1<<1),        //!< Respect <i>future</i> keyframes
+       MODE_ANIMATE_PAST       =(1<<2),        //!< Respect <i>past</i> keyframes
+       MODE_ANIMATE_ALL        =(3<<1),        //!< Respect <i>all</i> keyframes
+
+       MODE_UNDEFINED          =(~0)   //!< Undefined Mode
+}; // END of enum EditMode
+
+//! Combine Flags
+inline EditMode
+operator|(const EditMode& lhs, const EditMode& rhs)
+{ return static_cast<EditMode>(int(lhs)|int(rhs)); }
+
+//! Exclude Flags
+inline EditMode
+operator-(const EditMode& lhs, const EditMode& rhs)
+{ return static_cast<EditMode>(int(lhs)&~int(rhs)); }
+
+inline EditMode&
+operator|=(EditMode& lhs, const EditMode& rhs)
+{ *reinterpret_cast<int*>(&lhs)|=int(rhs); return lhs; }
+
+//!    Flag Comparison. THIS IS NOT LESS-THAN-OR-EQUAL-TO.
+/*!    This function will return true of all of the flags
+**     in the \a rhs are set in the \a lhs */
+inline EditMode
+operator&(const EditMode& lhs, const EditMode& rhs)
+{ return static_cast<EditMode>(int(lhs)&int(rhs)); }
+
+//!    Flag Comparison. THIS IS NOT LESS-THAN-OR-EQUAL-TO.
+/*!    This function will return true of all of the flags
+**     in the \a rhs are set in the \a lhs */
+inline bool
+operator<=(const EditMode& lhs, const EditMode& rhs)
+{ return lhs&rhs==int(rhs); }
+
+}; // END if namespace sinfgapp
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/inputdevice.cpp b/synfig-studio/trunk/src/sinfgapp/inputdevice.cpp
new file mode 100644 (file)
index 0000000..a6281c0
--- /dev/null
@@ -0,0 +1,195 @@
+/* === S I N F G =========================================================== */
+/*!    \file inputdevice.cpp
+**     \brief Template File
+**
+**     $Id: inputdevice.cpp,v 1.2 2005/01/12 04:08:32 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "inputdevice.h"
+#include "settings.h"
+#include <cstdio>
+#include <ETL/stringf>
+#include "main.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+class DeviceSettings : public Settings
+{
+       InputDevice* input_device;
+public:
+       DeviceSettings(InputDevice* input_device):
+               input_device(input_device) { }
+               
+
+       virtual bool get_value(const sinfg::String& key, sinfg::String& value)const
+       {
+               if(key=="state")
+               {
+                       value=input_device->get_state();
+                       return true;
+               }
+               if(key=="bline_width")
+               {
+                       value=strprintf("%s",input_device->get_bline_width().get_string().c_str());
+                       return true;
+               }
+               if(key=="opacity")
+               {
+                       value=strprintf("%f",(float)input_device->get_opacity());
+                       return true;
+               }
+               if(key=="blend_method")
+               {
+                       value=strprintf("%i",(int)input_device->get_blend_method());
+                       return true;
+               }
+               if(key=="color")
+               {
+                       Color c(input_device->get_foreground_color());
+                       value=strprintf("%f %f %f %f",(float)c.get_r(),(float)c.get_g(),(float)c.get_b(),(float)c.get_a());
+
+                       return true;
+               }
+               
+               return Settings::get_value(key, value);
+       }
+       
+       virtual bool set_value(const sinfg::String& key,const sinfg::String& value)
+       {
+                       DEBUGPOINT();
+               if(key=="state")
+               {
+                       input_device->set_state(value);
+                       return true;
+               }
+               if(key=="bline_width")
+               {
+                       input_device->set_bline_width(sinfg::Distance(value));
+                       return true;
+               }
+               if(key=="opacity")
+               {
+                       input_device->set_opacity(atof(value.c_str()));
+                       return true;
+               }
+               if(key=="blend_method")
+               {
+                       input_device->set_blend_method(Color::BlendMethod(atoi(value.c_str())));
+                       return true;
+               }
+               if(key=="color")
+               {
+                       float r=0,g=0,b=0,a=1;
+                       if(!strscanf(value,"%f %f %f %f",&r,&g,&b,&a))
+                               return false;
+                       input_device->set_foreground_color(sinfg::Color(r,g,b,a));
+                       return true;
+               }
+               
+               return Settings::set_value(key, value);
+       }
+       
+       virtual KeyList get_key_list()const
+       {
+               KeyList ret(Settings::get_key_list());
+               ret.push_back("color");
+               ret.push_back("state");
+               ret.push_back("bline_width");
+               ret.push_back("blend_method");
+               ret.push_back("opacity");
+               return ret;
+       }
+};
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+InputDevice::InputDevice(const sinfg::String id_, Type type_):
+       id_(id_),
+       type_(type_),
+       state_((type_==TYPE_PEN)?"sketch":"normal"),
+       foreground_color_(Color::black()),
+       background_color_(Color::white()),
+       bline_width_(Distance(1,Distance::SYSTEM_POINTS)),
+       opacity_(1.0f),
+       blend_method_(Color::BLEND_COMPOSITE)
+{
+       switch(type_)
+       {
+               case TYPE_MOUSE:
+                       state_="normal";
+                       break;
+
+               case TYPE_PEN:
+                       state_="draw";
+                       break;
+
+               case TYPE_ERASER:
+                       state_="normal";
+                       break;
+
+               case TYPE_CURSOR:
+                       state_="normal";
+                       break;
+
+               default:
+                       state_="normal";
+                       break;
+       }
+       
+       device_settings=new DeviceSettings(this);
+       Main::settings().add_domain(device_settings,"input_device."+id_);
+}
+
+InputDevice::~InputDevice()
+{
+       Main::settings().remove_domain("input_device."+id_);    
+       delete device_settings;
+}
+
+Settings&
+InputDevice::settings()
+{
+       return *device_settings;
+}
+
+const Settings&
+InputDevice::settings()const
+{
+       return *device_settings;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/inputdevice.h b/synfig-studio/trunk/src/sinfgapp/inputdevice.h
new file mode 100644 (file)
index 0000000..920096c
--- /dev/null
@@ -0,0 +1,101 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: inputdevice.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_INPUTDEVICE_H
+#define __SINFG_INPUTDEVICE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/color.h>
+#include <sinfg/vector.h>
+#include <sinfg/distance.h>
+#include <sinfg/string.h>
+#include <ETL/handle>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+class DeviceSettings;
+
+namespace sinfgapp {
+class Settings;
+
+       
+class InputDevice : public etl::shared_object
+{
+public:
+       enum Type
+       {
+               TYPE_MOUSE,
+               TYPE_PEN,
+               TYPE_ERASER,
+               TYPE_CURSOR
+       };
+
+       typedef etl::handle<InputDevice> Handle;
+       
+private:
+       sinfg::String id_;
+       Type type_;
+       sinfg::String state_;
+       sinfg::Color foreground_color_;
+       sinfg::Color background_color_;
+       sinfg::Distance bline_width_;   
+       sinfg::Real opacity_;
+       sinfg::Color::BlendMethod blend_method_;
+
+       DeviceSettings* device_settings;
+
+public:
+       InputDevice(const sinfg::String id_, Type type_=TYPE_MOUSE);
+       ~InputDevice();
+
+       const sinfg::String& get_id()const { return id_; }
+       const sinfg::String& get_state()const { return state_; }
+       const sinfg::Color& get_foreground_color()const { return foreground_color_; }
+       const sinfg::Color& get_background_color()const { return background_color_; }
+       const sinfg::Distance& get_bline_width()const { return bline_width_; }
+       const sinfg::Real& get_opacity()const { return opacity_; }
+       const sinfg::Color::BlendMethod& get_blend_method()const { return blend_method_; }
+       Type get_type()const { return type_; }
+       
+       void set_state(const sinfg::String& x) { state_=x; }
+       void set_foreground_color(const sinfg::Color& x) { foreground_color_=x; }
+       void set_background_color(const sinfg::Color& x) { background_color_=x; }
+       void set_bline_width(const sinfg::Distance& x) { bline_width_=x; }
+       void set_blend_method(const sinfg::Color::BlendMethod& x) { blend_method_=x; }
+       void set_opacity(const sinfg::Real& x) { opacity_=x; }
+       void set_type(Type x) { type_=x; }
+       
+       Settings& settings();
+       const Settings& settings()const;
+}; // END of class InputDevice
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/instance.cpp b/synfig-studio/trunk/src/sinfgapp/instance.cpp
new file mode 100644 (file)
index 0000000..6cb56ac
--- /dev/null
@@ -0,0 +1,186 @@
+/* === S I N F G =========================================================== */
+/*!    \file instance.cpp
+**     \brief Instance
+**
+**     $Id: instance.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "instance.h"
+#include "canvasinterface.h"
+#include <iostream>
+#include <sinfg/loadcanvas.h>
+#include <sinfg/savecanvas.h>
+#include <sinfg/valuenode_composite.h>
+#include <sinfg/valuenode_radialcomposite.h>
+#include <sinfg/valuenode_reference.h>
+#include <map>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+static std::map<loose_handle<Canvas>, loose_handle<Instance> > instance_map_;
+
+/* === P R O C E D U R E S ================================================= */
+
+bool
+sinfgapp::is_editable(sinfg::ValueNode::Handle value_node)
+{
+       if(ValueNode_Const::Handle::cast_dynamic(value_node)
+               || ValueNode_TimedSwap::Handle::cast_dynamic(value_node)
+               || ValueNode_Animated::Handle::cast_dynamic(value_node)
+               || ValueNode_Composite::Handle::cast_dynamic(value_node)
+               || ValueNode_RadialComposite::Handle::cast_dynamic(value_node)
+               || ValueNode_Reference::Handle::cast_dynamic(value_node)
+       )
+               return true;
+       return false;
+}
+
+etl::handle<Instance>
+sinfgapp::find_instance(etl::handle<sinfg::Canvas> canvas)
+{
+       if(instance_map_.count(canvas)==0)
+               return 0;
+       return instance_map_[canvas];
+}
+
+/* === M E T H O D S ======================================================= */
+
+Instance::Instance(Canvas::Handle canvas):
+       CVSInfo(canvas->get_file_name()),
+       canvas_(canvas)
+{
+       assert(canvas->is_root());
+
+       unset_selection_manager();
+       
+       instance_map_[canvas]=this;
+} // END of sinfgapp::Instance::Instance()
+
+handle<Instance>
+Instance::create(Canvas::Handle canvas)
+{
+       // Construct a new instance
+       handle<Instance> instance(new Instance(canvas));
+
+       return instance;
+} // END of sinfgapp::Instance::create()
+
+sinfg::String
+Instance::get_file_name()const
+{
+       return get_canvas()->get_file_name();
+}
+
+void
+Instance::set_file_name(const sinfg::String &name)
+{
+       get_canvas()->set_file_name(name);
+       CVSInfo::set_file_name(name);
+}
+
+Instance::~Instance()
+{
+       instance_map_.erase(canvas_);
+       sinfg::info("studio::Instance::~Instance(): Deleted");
+} // END of studio::Instance::~Instance()
+
+handle<CanvasInterface>
+Instance::find_canvas_interface(handle<Canvas> canvas)
+{
+       if(!canvas)
+               return 0;
+       while(canvas->is_inline())
+               canvas=canvas->parent();
+       
+       CanvasInterfaceList::iterator iter;
+
+       for(iter=canvas_interface_list().begin();iter!=canvas_interface_list().end();iter++)
+               if((*iter)->get_canvas()==canvas)
+                       return *iter;
+
+       return CanvasInterface::create(this,canvas);
+}
+
+bool
+Instance::save()const
+{
+       bool ret=save_canvas(get_file_name(),canvas_);
+       if(ret)
+       {
+               reset_action_count();
+               const_cast<sigc::signal<void>& >(signal_saved_)();
+       }
+       return ret;
+}
+
+bool
+Instance::save_as(const std::string &file_name)const
+{
+       bool ret=save_canvas(file_name,canvas_);
+       if(ret)
+       {
+               reset_action_count();
+               const_cast<sigc::signal<void>& >(signal_saved_)();
+       }
+       return ret;
+}
+
+bool
+Instance::save_as(const std::string &file_name)
+{
+       bool ret;
+
+       String old_file_name(get_file_name());
+       
+       set_file_name(file_name);
+
+       ret=save_canvas(file_name,canvas_);
+
+       if(ret)
+       {
+               reset_action_count();
+               signal_saved_();
+       }
+       else
+       {
+               set_file_name(old_file_name);
+       }
+
+       signal_filename_changed_();
+
+       return ret;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/instance.h b/synfig-studio/trunk/src/sinfgapp/instance.h
new file mode 100644 (file)
index 0000000..a9901ad
--- /dev/null
@@ -0,0 +1,140 @@
+/* === S I N F G =========================================================== */
+/*!    \file instance.h
+**     \brief writeme
+**
+**     $Id: instance.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_INSTANCE_H
+#define __SINFG_APP_INSTANCE_H
+
+/* === H E A D E R S ======================================================= */
+
+#include "action.h"
+#include <ETL/handle>
+#include <sinfg/canvas.h>
+#include <sinfg/string.h>
+#include <list>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include "action_system.h"
+#include "selectionmanager.h"
+#include "cvs.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class CanvasInterface;
+
+
+class Instance : public Action::System , public CVSInfo
+{
+       friend class PassiveGrouper;
+       /*
+ -- ** -- P U B L I C   T Y P E S ---------------------------------------------
+       */
+
+public:
+
+       typedef std::list< etl::handle<CanvasInterface> > CanvasInterfaceList;
+
+       using etl::shared_object::ref;
+       using etl::shared_object::unref;
+
+       /*
+ -- ** -- P U B L I C  D A T A ------------------------------------------------
+       */
+
+public:
+       
+       /*
+ -- ** -- P R I V A T E   D A T A ---------------------------------------------
+       */
+
+private:
+       //! Handle for root canvas
+       sinfg::Canvas::Handle canvas_;
+
+
+       CanvasInterfaceList canvas_interface_list_;
+
+       sigc::signal<void> signal_filename_changed_;
+       sigc::signal<void> signal_saved_;
+       etl::handle<SelectionManager> selection_manager_;
+       
+protected:
+       Instance(etl::handle<sinfg::Canvas>);
+
+       /*
+ -- ** -- P U B L I C   M E T H O D S -----------------------------------------
+       */
+
+public:
+
+       ~Instance();
+
+       void set_selection_manager(const etl::handle<SelectionManager> &sm) { assert(sm); selection_manager_=sm; }
+       void unset_selection_manager() { selection_manager_=new NullSelectionManager(); }
+       const etl::handle<SelectionManager> &get_selection_manager() { return selection_manager_; }     
+
+
+
+       etl::handle<CanvasInterface> find_canvas_interface(sinfg::Canvas::Handle canvas);
+
+       sinfg::Canvas::Handle get_canvas()const { return canvas_; }
+
+       //! Saves the instance to filename_
+       bool save()const;
+
+       bool save_as(const sinfg::String &filename)const;
+
+       bool save_as(const sinfg::String &filename);
+
+public:        // Interfaces to internal information
+       sigc::signal<void>& signal_filename_changed() { return signal_filename_changed_; }
+       sigc::signal<void>& signal_saved() { return signal_saved_; }
+
+       CanvasInterfaceList & canvas_interface_list() { return canvas_interface_list_; }
+       const CanvasInterfaceList & canvas_interface_list()const { return canvas_interface_list_; }
+
+       sinfg::String get_file_name()const;
+
+       void set_file_name(const sinfg::String &name);
+
+public:
+       
+
+public:        // Constructor interfaces
+       static etl::handle<Instance> create(etl::handle<sinfg::Canvas> canvas);
+}; // END class Instance
+
+etl::handle<Instance> find_instance(etl::handle<sinfg::Canvas> canvas);
+
+bool is_editable(sinfg::ValueNode::Handle value_node);
+
+}; // END namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/main.cpp b/synfig-studio/trunk/src/sinfgapp/main.cpp
new file mode 100644 (file)
index 0000000..cd7becb
--- /dev/null
@@ -0,0 +1,401 @@
+/* === S I N F G =========================================================== */
+/*!    \file main.cpp
+**     \brief Template File
+**
+**     $Id: main.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "main.h"
+#include "action.h"
+
+#include <sinfg/color.h>
+#include <sinfg/gradient.h>
+
+#include <ETL/trivial>
+
+#include <list>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === S T A T I C S ======================================================= */
+
+static etl::reference_counter sinfgapp_ref_count_(0);
+static sinfgapp::Action::Main* action_main;
+
+static Color foreground_;
+static Color background_;
+static Gradient gradient_;
+static bool gradient_default_colors_;
+
+static sinfg::Distance bline_width_;
+
+static Color::BlendMethod blend_method_;
+static Real opacity_;
+
+static sinfgapp::InputDevice::Handle selected_input_device_;
+static list<sinfgapp::InputDevice::Handle> input_devices_;
+
+trivial<sigc::signal<void> > signal_foreground_color_changed_;
+trivial<sigc::signal<void> > signal_background_color_changed_;
+trivial<sigc::signal<void> > signal_gradient_changed_;
+trivial<sigc::signal<void> > signal_bline_width_changed_;
+trivial<sigc::signal<void> > signal_blend_method_changed_;
+trivial<sigc::signal<void> > signal_opacity_changed_;
+trivial<sigc::signal<void> > signal_interpolation_changed_;
+
+trivial<Settings> settings_;
+
+static sinfg::Waypoint::Interpolation interpolation_;
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+sinfgapp::Main::Main(const sinfg::String &basepath,ProgressCallback *cb):
+       sinfg::Main(basepath,cb),
+       ref_count_(sinfgapp_ref_count_)
+{
+       if(ref_count_.count())
+               return;
+
+       sinfgapp_ref_count_.reset();
+       ref_count_=sinfgapp_ref_count_;
+       
+       // Add initialization after this point
+       action_main=new sinfgapp::Action::Main();
+
+       settings_.construct();
+       
+       signal_foreground_color_changed_.construct();
+       signal_background_color_changed_.construct();
+       signal_gradient_changed_.construct();
+       signal_opacity_changed_.construct();
+       signal_blend_method_changed_.construct();
+       signal_interpolation_changed_.construct();
+       
+       set_foreground_color(Color::black());
+       set_background_color(Color::white());
+       set_gradient_default_colors();
+       set_bline_width(Distance(1,Distance::SYSTEM_POINTS));
+       set_opacity(1.0);
+       set_blend_method(Color::BLEND_COMPOSITE);
+}
+
+sinfgapp::Main::~Main()
+{
+       ref_count_.detach();
+       if(!sinfgapp_ref_count_.unique())
+               return;
+       sinfgapp_ref_count_.detach();
+       
+       // Add deinitialization after this point
+
+       delete action_main;     
+       
+       selected_input_device_=0;
+       input_devices_.clear();
+       
+       settings_.destruct();
+       signal_foreground_color_changed_.destruct();
+       signal_background_color_changed_.destruct();
+       signal_gradient_changed_.destruct();
+
+       signal_opacity_changed_.destruct();
+       signal_blend_method_changed_.destruct();
+       signal_interpolation_changed_.destruct();
+}
+
+Settings&
+sinfgapp::Main::settings()
+{
+       return settings_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_foreground_color_changed()
+{
+       return signal_foreground_color_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_background_color_changed()
+{
+       return signal_background_color_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_gradient_changed()
+{
+       return signal_gradient_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_bline_width_changed()
+{
+       return signal_bline_width_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_blend_method_changed()
+{
+       return signal_blend_method_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_opacity_changed()
+{
+       return signal_opacity_changed_;
+}
+
+sigc::signal<void>&
+sinfgapp::Main::signal_interpolation_changed()
+{
+       return signal_interpolation_changed_;
+}
+
+const sinfg::Color&
+sinfgapp::Main::get_foreground_color()
+{
+       return foreground_;
+}
+
+const sinfg::Color&
+sinfgapp::Main::get_background_color()
+{
+       return background_;
+}
+
+const sinfg::Gradient&
+sinfgapp::Main::get_gradient()
+{
+       return gradient_;
+}
+
+const sinfg::Real&
+sinfgapp::Main::get_opacity()
+{
+       return opacity_;
+}
+
+sinfg::Color::BlendMethod
+sinfgapp::Main::get_blend_method()
+{
+       return blend_method_;
+}
+
+void
+sinfgapp::Main::set_foreground_color(sinfg::Color color)
+{
+       foreground_=color;
+       signal_foreground_color_changed()();
+       if(selected_input_device_)
+               selected_input_device_->set_foreground_color(foreground_);
+       if(gradient_default_colors_)
+       {
+               gradient_=Gradient(foreground_,background_);
+               signal_gradient_changed()();
+       }
+}
+
+void
+sinfgapp::Main::set_background_color(sinfg::Color color)
+{
+       background_=color;
+       signal_background_color_changed()();
+
+       if(selected_input_device_)
+               selected_input_device_->set_background_color(background_);
+
+       if(gradient_default_colors_)
+       {
+               gradient_=Gradient(foreground_,background_);
+               signal_gradient_changed()();
+       }
+}
+
+void
+sinfgapp::Main::set_gradient(sinfg::Gradient gradient)
+{
+       gradient_=gradient;
+       gradient_default_colors_=false;
+       signal_gradient_changed()();
+}
+
+void
+sinfgapp::Main::set_gradient_default_colors()
+{
+       gradient_default_colors_=true;
+       gradient_=Gradient(foreground_,background_);
+       signal_gradient_changed()();
+}
+
+void
+sinfgapp::Main::color_swap()
+{
+       const Color tmp(foreground_);
+       foreground_=background_;
+       background_=tmp;
+
+       if(selected_input_device_)
+       {
+               selected_input_device_->set_foreground_color(foreground_);
+               selected_input_device_->set_background_color(background_);
+       }
+
+       signal_foreground_color_changed()();
+       signal_background_color_changed()();
+
+       if(gradient_default_colors_)
+       {
+               gradient_=Gradient(foreground_,background_);
+               signal_gradient_changed()();
+       }
+}
+
+sinfg::Waypoint::Interpolation
+sinfgapp::Main::get_interpolation()
+{
+       return interpolation_;
+}
+
+
+void
+sinfgapp::Main::set_interpolation(sinfg::Waypoint::Interpolation x)
+{
+       if(interpolation_!=x)
+       {
+               interpolation_=x;
+               
+               signal_interpolation_changed();
+       }
+}
+
+const sinfg::Distance&
+sinfgapp::Main::get_bline_width()
+{
+       return bline_width_;
+}
+
+void
+sinfgapp::Main::set_bline_width(sinfg::Distance x)
+{
+       if(x<0)x=0;
+       if(x!=bline_width_)
+       {
+               bline_width_=x;
+               
+               if(selected_input_device_)
+                       selected_input_device_->set_bline_width(x);
+               
+               signal_bline_width_changed()();
+       }
+}
+
+void
+sinfgapp::Main::set_opacity(sinfg::Real x)
+{
+       opacity_=x;
+       if(selected_input_device_)
+               selected_input_device_->set_opacity(opacity_);
+       signal_opacity_changed()();
+}
+
+void
+sinfgapp::Main::set_blend_method(sinfg::Color::BlendMethod x)
+{
+       blend_method_=x;
+       if(selected_input_device_)
+               selected_input_device_->set_blend_method(x);
+       signal_blend_method_changed()();
+}
+
+
+InputDevice::Handle
+sinfgapp::Main::add_input_device(const sinfg::String id, InputDevice::Type type)
+{
+       input_devices_.push_back(new InputDevice(id,type));
+       return input_devices_.back();
+}
+
+InputDevice::Handle
+sinfgapp::Main::find_input_device(const sinfg::String id)
+{
+       list<InputDevice::Handle>::iterator iter;
+       for(iter=input_devices_.begin();iter!=input_devices_.end();++iter)
+               if((*iter)->get_id()==id)
+                       return *iter;
+       return 0;
+}
+
+InputDevice::Handle
+sinfgapp::Main::select_input_device(const sinfg::String id)
+{
+       InputDevice::Handle input_device(find_input_device(id));
+       if(!input_device)
+               return 0;
+       if(!select_input_device(input_device))
+               return 0;
+       return input_device;
+}
+
+bool
+sinfgapp::Main::select_input_device(InputDevice::Handle input_device)
+{
+       assert(input_device);
+       
+       sinfg::info("Input device changed to \"%s\"",input_device->get_id().c_str());
+       
+       selected_input_device_=input_device;
+
+       set_bline_width(input_device->get_bline_width());       
+       set_foreground_color(input_device->get_foreground_color());
+       set_opacity(input_device->get_opacity());       
+       set_blend_method(input_device->get_blend_method());     
+       
+       return true;
+}
+
+InputDevice::Handle
+sinfgapp::Main::get_selected_input_device()
+{
+       return selected_input_device_;  
+}
+
+void
+sinfgapp::Main::set_state(sinfg::String state)
+{
+       if(selected_input_device_)
+               selected_input_device_->set_state(state);
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/main.h b/synfig-studio/trunk/src/sinfgapp/main.h
new file mode 100644 (file)
index 0000000..26622c3
--- /dev/null
@@ -0,0 +1,112 @@
+/* === S I N F G =========================================================== */
+/*!    \file main.h
+**     \brief Template Header
+**
+**     $Id: main.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFGAPP_MAIN_H
+#define __SINFGAPP_MAIN_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/ref_count>
+#include <sinfg/string.h>
+#include <sinfg/general.h>
+#include <sinfg/main.h>
+#include <sinfg/distance.h>
+#include <sinfg/real.h>
+#include <sinfg/waypoint.h>
+#include <sigc++/signal.h>
+#include <sigc++/object.h>
+#include "inputdevice.h"
+#include "settings.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfg {
+       class Color;
+       class Gradient;
+};
+
+namespace sinfgapp {
+       
+/*!    \class sinfgapp::Main
+**     \brief \writeme
+**
+**     \writeme
+*/
+class Main : public sinfg::Main
+{
+       etl::reference_counter ref_count_;
+public:
+       Main(const sinfg::String &basepath,sinfg::ProgressCallback *cb=0);
+       ~Main();
+
+       const etl::reference_counter& ref_count()const { return ref_count_; }
+               
+       static const sinfg::Color& get_foreground_color();
+       static const sinfg::Color& get_background_color();
+       static const sinfg::Gradient& get_gradient();
+       static const sinfg::Distance& get_bline_width();
+       static sinfg::Waypoint::Interpolation get_interpolation();
+
+
+       static void set_interpolation(sinfg::Waypoint::Interpolation x);
+       static void set_bline_width(sinfg::Distance x); 
+       static void set_foreground_color(sinfg::Color color);
+       static void set_background_color(sinfg::Color color);
+       static void set_gradient(sinfg::Gradient gradient);
+       static void set_gradient_default_colors();
+       static void color_swap();       
+
+       static sinfg::Color::BlendMethod get_blend_method();
+       static const sinfg::Real& get_opacity();
+       static void set_blend_method(sinfg::Color::BlendMethod);
+       static void set_opacity(sinfg::Real);
+       static sigc::signal<void>& signal_blend_method_changed();
+       static sigc::signal<void>& signal_opacity_changed();
+       static sigc::signal<void>& signal_interpolation_changed();
+       
+       // Input Device stuff
+       static InputDevice::Handle add_input_device(const sinfg::String id_, InputDevice::Type type_=InputDevice::TYPE_MOUSE);
+       static InputDevice::Handle find_input_device(const sinfg::String id_);
+       static InputDevice::Handle select_input_device(const sinfg::String id_);
+       static bool select_input_device(InputDevice::Handle input_device);
+       static InputDevice::Handle get_selected_input_device();
+       static void set_state(sinfg::String state);
+
+       static Settings& settings();
+       
+       // Signal interfaces    
+       static sigc::signal<void>& signal_foreground_color_changed();
+       static sigc::signal<void>& signal_background_color_changed();
+       static sigc::signal<void>& signal_gradient_changed();
+       static sigc::signal<void>& signal_bline_width_changed();
+
+}; // END of class Main
+
+}; // END if namespace sinfgapp
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/selectionmanager.h b/synfig-studio/trunk/src/sinfgapp/selectionmanager.h
new file mode 100644 (file)
index 0000000..e6abeea
--- /dev/null
@@ -0,0 +1,146 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: selectionmanager.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_SELECTIONMANAGER_H
+#define __SINFG_APP_SELECTIONMANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <list>
+#include <set>
+#include <ETL/handle>
+#include <sinfg/layer.h>
+#include <sinfg/valuenode.h>
+#include "value_desc.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class SelectionManager : public etl::shared_object
+{
+public:
+       typedef std::pair<sinfg::Layer::Handle,sinfg::String> LayerParam;
+       typedef std::list<LayerParam> LayerParamList;
+
+       typedef std::list<sinfg::Layer::Handle> LayerList;
+       typedef std::list<ValueDesc> ChildrenList;
+       //typedef std::list<sinfg::ValueNode::Handle> ValueNodeList;
+
+       virtual ~SelectionManager() { }
+
+       //! Returns the number of layers selected.
+       virtual int get_selected_layer_count()const=0;
+
+       //! Returns a list of the currently selected layers.
+       virtual LayerList get_selected_layers()const=0;
+       
+       //! Returns the first layer selected or an empty handle if none are selected.
+       virtual sinfg::Layer::Handle get_selected_layer()const=0;
+       
+       //! Sets which layers should be selected
+       virtual void set_selected_layers(const LayerList &layer_list)=0;
+
+       //! Sets which layer should be selected. Empty handle if none.
+       virtual void set_selected_layer(const sinfg::Layer::Handle &layer)=0;
+
+       //! Clears the layer selection list
+       virtual void clear_selected_layers()=0;
+
+
+
+       //! Returns the number of childrens selected.
+       virtual int get_selected_children_count()const=0;
+
+       //! Returns a list of the currently selected childrens.
+       virtual ChildrenList get_selected_children()const=0;
+       
+       //! Returns the first children selected or an empty handle if none are selected.
+       virtual ChildrenList::value_type get_selected_child()const=0;
+       
+       //! Sets which childrens should be selected
+       virtual void set_selected_children(const ChildrenList &children_list)=0;
+
+       //! Sets which children should be selected. Empty handle if none.
+       virtual void set_selected_child(const ChildrenList::value_type &children)=0;
+
+       //! Clears the children selection list
+       virtual void clear_selected_children()=0;
+
+
+       //! Returns the number of layer parameters selected.
+       virtual int get_selected_layer_parameter_count()const=0;
+
+       //! Returns a list of the currently selected layer parameters.
+       virtual LayerParamList get_selected_layer_parameters()const=0;
+       
+       //! Returns the first layer parameter selected or an empty handle if none are selected.
+       virtual LayerParam get_selected_layer_parameter()const=0;
+       
+       //! Sets which layer parameters should be selected
+       virtual void set_selected_layer_parameters(const LayerParamList &layer_param_list)=0;
+
+       //! Sets which layer parameter should be selected. Empty handle if none.
+       virtual void set_selected_layer_param(const LayerParam &layer_param)=0;
+
+       //! Clears the layer parameter selection list
+       virtual void clear_selected_layer_parameters()=0;
+}; // END of class SelectionManager
+
+//! A place holding selection manager that does nothing
+class NullSelectionManager : public SelectionManager
+{
+public:
+       int get_selected_layer_count()const { return 0; }
+       LayerList get_selected_layers()const { return LayerList(); }
+       sinfg::Layer::Handle get_selected_layer()const { return 0; }
+       void set_selected_layers(const LayerList &layer_list) { return; }
+       void set_selected_layer(const sinfg::Layer::Handle &layer) { return; }
+       void clear_selected_layers() { return; }
+
+
+       int get_selected_children_count()const { return 0; }
+       ChildrenList get_selected_children()const { return ChildrenList(); }
+       ChildrenList::value_type get_selected_child()const { return ChildrenList::value_type(); }
+       void set_selected_children(const ChildrenList &children_list) { return; }
+       void set_selected_child(const ChildrenList::value_type &child) { return; }
+       void clear_selected_children() { return; }
+
+       int get_selected_layer_parameter_count()const { return 0; }
+       LayerParamList get_selected_layer_parameters()const { return LayerParamList(); }
+       LayerParam get_selected_layer_parameter()const { return LayerParam(); }
+       void set_selected_layer_parameters(const LayerParamList &layer_param_list) { return; }
+       void set_selected_layer_param(const LayerParam &layer_param) { return; }
+       void clear_selected_layer_parameters() { return; }
+
+}; // END of class NullSelectionManager
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/settings.cpp b/synfig-studio/trunk/src/sinfgapp/settings.cpp
new file mode 100644 (file)
index 0000000..05ea188
--- /dev/null
@@ -0,0 +1,237 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: settings.cpp,v 1.2 2005/01/12 04:08:32 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include <fstream>
+#include <iostream>
+#include "settings.h"
+#include <sinfg/general.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+Settings::Settings()
+{
+}
+
+Settings::~Settings()
+{
+}
+
+sinfg::String
+Settings::get_value(const sinfg::String& key)const
+{
+       sinfg::String value;
+       if(!get_value(key,value))
+               return sinfg::String();
+       return value;
+}
+
+void
+Settings::add_domain(Settings* domain, const sinfg::String& name)
+{
+       domain_map[name]=domain;
+}
+
+void
+Settings::remove_domain(const sinfg::String& name)
+{
+       domain_map.erase(name);
+}
+
+bool
+Settings::get_value(const sinfg::String& key, sinfg::String& value)const
+{
+       // Search for the value in any children domains
+       DomainMap::const_iterator iter;
+       for(iter=domain_map.begin();iter!=domain_map.end();++iter)
+       {
+               // if we have a domain hit
+               if(key.size()>iter->first.size() && String(key.begin(),key.begin()+iter->first.size())==iter->first)
+               {
+                       sinfg::String key_(key.begin()+iter->first.size()+1,key.end());
+                       
+                       // If the domain has it, then we have got a hit
+                       if(iter->second->get_value(key_,value))
+                               return true;
+               }
+       }
+
+       // Search for the value in our simple map
+       if(simple_value_map.count(key))
+       {
+               value=simple_value_map.find(key)->second;
+               return true;
+       }
+       
+       // key not found
+       return false;
+}
+
+bool
+Settings::set_value(const sinfg::String& key,const sinfg::String& value)
+{
+       // Search for the key in any children domains
+       DomainMap::iterator iter;
+       for(iter=domain_map.begin();iter!=domain_map.end();++iter)
+       {
+               // if we have a domain hit
+               if(key.size()>iter->first.size() && String(key.begin(),key.begin()+iter->first.size())==iter->first)
+               {
+                       sinfg::String key_(key.begin()+iter->first.size()+1,key.end());
+                       
+                       return iter->second->set_value(key_,value);
+               }
+       }
+
+       simple_value_map[key]=value;
+       return true;
+}
+
+Settings::KeyList
+Settings::get_key_list()const
+{
+       KeyList key_list;
+
+       // Get keys from the domains
+       {
+               DomainMap::const_iterator iter;
+               for(iter=domain_map.begin();iter!=domain_map.end();++iter)
+               {
+                       KeyList sub_key_list(iter->second->get_key_list());
+                       KeyList::iterator key_iter;
+                       for(key_iter=sub_key_list.begin();key_iter!=sub_key_list.end();++key_iter)
+                               key_list.push_back(iter->first+'.'+*key_iter);
+               }
+       }
+       
+       // Get keys from the simple variables
+       {
+               ValueBaseMap::const_iterator iter;
+               for(iter=simple_value_map.begin();iter!=simple_value_map.end();++iter)
+                       key_list.push_back(iter->first);
+       }
+
+       // Sort the keys
+       key_list.sort();
+       
+       return key_list;
+}
+
+bool
+Settings::save_to_file(const sinfg::String& filename)const
+{
+       sinfg::String tmp_filename(filename+".TMP");
+       
+       try
+       {
+               std::ofstream file(tmp_filename.c_str());
+
+               if(!file)return false;
+       
+               KeyList key_list(get_key_list());
+               
+               // Save the keys
+               {
+                       KeyList::const_iterator iter;
+                       for(iter=key_list.begin();iter!=key_list.end();++iter)
+                       {
+                               if(!file)return false;
+                               file<<*iter<<'='<<get_value(*iter)<<endl;
+                       }
+               }
+       
+               if(!file)
+                       return false;
+       }catch(...) { return false; }
+       
+#ifdef _WIN32
+       char old_file[80]="sif.XXXXXXXX";
+       mktemp(old_file);
+       rename(filename.c_str(),old_file);      
+       if(rename(tmp_filename.c_str(),filename.c_str())!=0)
+       {
+               rename(old_file,tmp_filename.c_str());
+               return false;
+       }
+       remove(old_file);
+#else
+       if(rename(tmp_filename.c_str(),filename.c_str())!=0)
+               return false;
+#endif
+       
+       return true;
+}
+
+bool
+Settings::load_from_file(const sinfg::String& filename)
+{
+       std::ifstream file(filename.c_str());
+       if(!file)
+               return false;
+       while(file)
+       {
+               std::string line;
+               getline(file,line);
+               if(!line.empty() && ((line[0]>='a' && line[0]<='z')||(line[0]>='A' && line[0]<='Z')))
+               {
+                       std::string::iterator equal(find(line.begin(),line.end(),'='));
+                       if(equal==line.end())
+                               continue;
+                       std::string key(line.begin(),equal);
+                       std::string value(equal+1,line.end());
+                       
+                       //sinfg::info("Settings::load_from_file(): Trying Key \"%s\" with a value of \"%s\".",key.c_str(),value.c_str());
+                       try{
+                       if(!set_value(key,value))
+                               sinfg::warning("Settings::load_from_file(): Key \"%s\" with a value of \"%s\" was rejected.",key.c_str(),value.c_str());
+                       }
+                       catch(...)
+                       {
+                               sinfg::error("Settings::load_from_file(): Attept to set key \"%s\" with a value of \"%s\" has thrown an exception.",key.c_str(),value.c_str());
+                               throw;
+                       }
+               }
+       }
+       return true;
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/settings.h b/synfig-studio/trunk/src/sinfgapp/settings.h
new file mode 100644 (file)
index 0000000..d67f173
--- /dev/null
@@ -0,0 +1,78 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: settings.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_SETTINGS_H
+#define __SINFG_SETTINGS_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/string.h>
+#include <map>
+#include <list>
+#include <ETL/stringf>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class Settings
+{
+public:
+       
+       typedef std::list<sinfg::String> KeyList;
+       typedef std::map<sinfg::String,sinfg::String> ValueBaseMap;
+       typedef std::map<sinfg::String,Settings*> DomainMap;
+       
+private:
+       ValueBaseMap simple_value_map;
+
+       DomainMap domain_map;
+
+public:
+       Settings();
+       virtual ~Settings();
+
+       virtual bool get_value(const sinfg::String& key, sinfg::String& value)const;
+       virtual bool set_value(const sinfg::String& key,const sinfg::String& value);
+       virtual KeyList get_key_list()const;
+
+       sinfg::String get_value(const sinfg::String& key)const;
+       void add_domain(Settings* domain, const sinfg::String& name);
+       void remove_domain(const sinfg::String& name);
+
+       bool load_from_string(const sinfg::String& data);
+       bool save_to_string(sinfg::String& data);
+
+       bool load_from_file(const sinfg::String& filename);
+       bool save_to_file(const sinfg::String& filename)const;
+}; // END of class Settings
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/timegather.cpp b/synfig-studio/trunk/src/sinfgapp/timegather.cpp
new file mode 100644 (file)
index 0000000..22987fd
--- /dev/null
@@ -0,0 +1,311 @@
+/* === S I N F G =========================================================== */
+/*!    \file timegather.cpp
+**     \brief Time Gather File
+**
+**     $Id: timegather.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "timegather.h"
+#include "value_desc.h"
+
+#include <sinfg/layer_pastecanvas.h>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+//! Definitions for build a list of accurate valuenode references
+
+void sinfgapp::timepoints_ref::insert(sinfg::ValueNode_Animated::Handle v, sinfg::Waypoint w)
+{
+       ValueBaseTimeInfo       vt;
+       vt.val = v;
+       
+       waytracker::iterator i = waypointbiglist.find(vt);
+       
+       if(i != waypointbiglist.end())
+       {
+               i->waypoints.insert(w);
+       }else
+       {
+               vt.waypoints.insert(w);
+               waypointbiglist.insert(vt);
+       }
+}
+
+void sinfgapp::timepoints_ref::insert(sinfgapp::ValueDesc v, sinfg::Activepoint a)
+{
+       ActiveTimeInfo  vt;
+       vt.val = v;
+       
+       acttracker::iterator i = actpointbiglist.find(vt);
+       
+       if(i != actpointbiglist.end())
+       {
+               i->activepoints.insert(a);
+               /*{ //if it fails...
+                       sinfg::info("!!!!For some reason it wasn't able to insert the activepoint in the list (%s,%.4lg)",
+                                                       a.state?"true":"false", (double)a.time);
+               }*/
+       }else
+       {
+               vt.activepoints.insert(a);
+               actpointbiglist.insert(vt);
+               //sinfg::info("Insert new activept list for valdesc");
+       }
+}
+
+//recursion functions
+void sinfgapp::recurse_canvas(sinfg::Canvas::Handle h, const std::set<Time> &tlist, 
+                                                               timepoints_ref &vals)
+{
+       
+       //sinfg::info("Canvas...\n Recurse through layers");
+       // iterate through the layers
+
+       sinfg::Canvas::iterator i = h->begin(), end = h->end();
+
+       for(; i != end; ++i)
+       {
+               const Node::time_set &tset = (*i)->get_times();
+               if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end()))
+               {
+                       recurse_layer(*i,tlist,vals);
+               }
+       }
+}
+
+void sinfgapp::recurse_layer(sinfg::Layer::Handle h, const std::set<Time> &tlist, 
+                                                               timepoints_ref &vals)
+{
+       // iterate through the layers
+       //check for special case of paste canvas
+       etl::handle<sinfg::Layer_PasteCanvas> p = etl::handle<sinfg::Layer_PasteCanvas>::cast_dynamic(h);
+       
+       //sinfg::info("Layer...");
+       
+       if(p)
+       {
+               //sinfg::info("We are a paste canvas so go into that");
+               //recurse into the canvas
+               const sinfg::Node::time_set &tset = p->get_sub_canvas()->get_times();
+               
+               if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end()))
+               {
+                       //we have to offset the times so it won't wreck havoc if the canvas is imported more than once...
+                       // and so we get correct results when offsets are present
+                       std::set<Time>  tlistoff;                       
+                       std::set<Time>::iterator i = tlist.begin(), end = tlist.end();
+                       for(; i != end; ++i)
+                       {
+                               tlistoff.insert(*i - p->get_time_offset());
+                       }
+                       
+                       recurse_canvas(p->get_sub_canvas(),tlist,vals);
+               }
+       }
+
+       //check all the valuenodes regardless...
+       //sinfg::info("Recurse all valuenodes");
+       sinfg::Layer::DynamicParamList::const_iterator  i = h->dynamic_param_list().begin(),
+                                                                                                       end = h->dynamic_param_list().end();
+       for(; i != end; ++i)
+       {
+               const sinfg::Node::time_set &tset = i->second->get_times();
+               
+               if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end()))
+               {
+                       recurse_valuedesc(ValueDesc(h,i->first),tlist,vals);
+               }
+       }
+}
+
+template < typename IT, typename CMP >
+static bool sorted(IT i,IT end, const CMP &cmp = CMP())
+{
+       if(i == end) return true;
+               
+       for(IT last = i++; i != end; last = i++)
+       {
+               if(!cmp(*last,*i))
+                       return false;
+       }
+       
+       return true;
+}
+
+void sinfgapp::recurse_valuedesc(sinfgapp::ValueDesc h, const std::set<Time> &tlist, 
+                                                               timepoints_ref &vals)
+{
+       //special cases for Animated, DynamicList, and Linkable
+       
+       //sinfg::info("ValueBasenode... %p, %s", h.get_value_node().get(),typeid(*h.get_value_node()).name());
+       
+       
+       //animated case
+       {
+               sinfg::ValueNode_Animated::Handle p = sinfg::ValueNode_Animated::Handle::cast_dynamic(h.get_value_node());
+               
+               if(p)
+               {
+                       //loop through and determine which waypoint we will need to reference
+                       const sinfg::WaypointList &w = p->waypoint_list();
+                       
+                       sinfg::WaypointList::const_iterator i = w.begin(),
+                                                                                               end = w.end();
+                       
+                       std::set<Time>::const_iterator          j = tlist.begin(),
+                                                                                               jend = tlist.end();
+                       for(; i != end && j != jend;) 
+                       {
+                               //sinfg::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time()));
+                               
+                               if(j->is_equal(i->get_time()))
+                               {
+                                       vals.insert(p,*i);
+                                       ++i,++j;
+                               }else if(*i < *j) 
+                               {
+                                       ++i;
+                               }else ++j;
+                       }
+                       return;
+               }
+       }
+       
+       //parent dynamiclist case - just for active points for that object...
+       if(h.parent_is_value_node())
+       {
+               sinfg::ValueNode_DynamicList::Handle p = sinfg::ValueNode_DynamicList::Handle::cast_dynamic(h.get_parent_value_node());                                         
+                               
+               if(p)
+               {
+                       int index = h.get_index();
+                       
+                       //check all the active points in each list...
+                       const sinfg::ActivepointList &a = p->list[index].timing_info;
+                       
+                       //sinfg::info("Our parent = dynamic list, searching in %d activepts",a.size());
+                                               
+                       std::set<Time>::const_iterator                  i = tlist.begin(),
+                                                                                                       end = tlist.end();
+                       
+                       sinfg::ActivepointList::const_iterator  j = a.begin(),
+                                                                                                       jend = a.end();
+                       
+                       for(; j != jend && i != end;)
+                       {
+                               double it = *i;
+                               double jt = j->get_time();
+                               double diff = (double)(it - jt);
+                               
+                               //sinfg::info("\ttpair match(%.4lg) - %.4lg (diff = %lg",it,jt,diff);                           
+                               
+                               //
+                               if(abs(diff) < (double)Time::epsilon())
+                               {
+                                       //sinfg::info("\tActivepoint to add being referenced (%x,%s,%.4lg)",
+                                       //                              (int)j->get_uid(),j->state?"true":"false", (double)j->time);
+                                       vals.insert(ValueDesc(p,index),*j);
+                                       ++i,++j;                                                
+                               }else if(it < jt)
+                               {
+                                       ++i;
+                                       //sinfg::info("\tIncrementing time");
+                               }
+                               else 
+                               {
+                                       ++j;
+                                       //sinfg::info("\tIncrementing actpt");
+                               }
+                       }
+               }
+       }
+       
+       //dynamiclist case - we must still make sure that we read from the list entries the time values
+       //                                              because just the linked valuenodes will not do that
+       {
+               sinfg::ValueNode_DynamicList::Handle p = sinfg::ValueNode_DynamicList::Handle::cast_dynamic(h.get_value_node());
+               
+               if(p)
+               {
+                       //sinfg::info("Process dynamic list valuenode");
+                       int index = 0;
+                       
+                       std::vector<sinfg::ValueNode_DynamicList::ListEntry>::const_iterator    
+                                                       i = p->list.begin(),
+                                                       end = p->list.end();
+                       
+                       for(; i != end; ++i, ++index)
+                       {
+                               const Node::time_set &tset = i->get_times();
+                               
+                               if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end()))
+                               {
+                                       recurse_valuedesc(ValueDesc(p,index),tlist,vals);
+                               }
+                       }
+                       return;
+               }
+       }
+       
+       //the linkable case...
+       {
+               etl::handle<sinfg::LinkableValueNode> p = etl::handle<sinfg::LinkableValueNode>::cast_dynamic(h.get_value_node());
+               
+               if(p)
+               {
+                       //sinfg::info("Process Linkable ValueBasenode");
+                       int i = 0, size = p->link_count();
+                       
+                       for(; i < size; ++i)
+                       {
+                               ValueNode::Handle v = p->get_link(i);
+                               const Node::time_set &tset = v->get_times();
+                               
+                               if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end()))
+                               {
+                                       recurse_valuedesc(ValueDesc(p,i),tlist,vals);
+                               }
+                       }
+               }
+       }
+}
diff --git a/synfig-studio/trunk/src/sinfgapp/timegather.h b/synfig-studio/trunk/src/sinfgapp/timegather.h
new file mode 100644 (file)
index 0000000..fb1416b
--- /dev/null
@@ -0,0 +1,135 @@
+/* === S I N F G =========================================================== */
+/*!    \file timegather.h
+**     \brief Time Gather Header
+**
+**     $Id: timegather.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2004 Adrian Bentley
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_TIMEGATHER_H
+#define __SINFG_TIMEGATHER_H
+
+/* === H E A D E R S ======================================================= */
+#include <sinfg/valuenode_animated.h>
+#include <sinfg/valuenode_dynamiclist.h>
+#include <sinfg/time.h>
+#include "value_desc.h"
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class ValueDesc;
+class sinfg::Time;
+
+struct ValueBaseTimeInfo
+{
+       sinfg::ValueNode_Animated::Handle       val;
+       mutable std::set<sinfg::Waypoint>       waypoints;
+       
+       bool operator<(const ValueBaseTimeInfo &rhs) const
+       {
+               return val < rhs.val;
+       }
+};
+
+struct ActiveTimeInfo
+{
+       struct actcmp
+       {
+               bool operator()(const sinfg::Activepoint &lhs, const sinfg::Activepoint &rhs) const
+               {
+                       return lhs.time < rhs.time;
+               }               
+       };
+       
+       sinfgapp::ValueDesc                                             val;
+       
+       typedef std::set<sinfg::Activepoint,actcmp>     set;
+       
+       mutable set activepoints;
+       
+       bool operator<(const ActiveTimeInfo &rhs) const
+       {
+               return val.get_parent_value_node() == rhs.val.get_parent_value_node() ? 
+                                               val.get_index() < rhs.val.get_index() : 
+                                               val.get_parent_value_node() < rhs.val.get_parent_value_node();
+       }
+};
+
+struct timepoints_ref
+{
+       typedef std::set<ValueBaseTimeInfo>             waytracker;     
+       typedef std::set<ActiveTimeInfo>        acttracker;
+       
+       waytracker              waypointbiglist;
+       acttracker              actpointbiglist;        
+       
+       void insert(sinfg::ValueNode_Animated::Handle v, sinfg::Waypoint w);    
+       void insert(sinfgapp::ValueDesc v, sinfg::Activepoint a);
+};
+
+//assumes they're sorted... (incremental advance)
+//checks the intersection of the two sets... might be something better in the stl
+template < typename I1, typename I2 >
+bool check_intersect(I1 b1, I1 end1, I2 b2, I2 end2)
+{
+       if(b1 == end1 || b2 == end2) 
+               return false;
+       
+       for(; b1 != end1 && b2 != end2;)
+       {
+               if(*b1 < *b2) ++b1;
+               else if(*b2 < *b1) ++b2;
+               else
+               {
+                       assert(*b1 == *b2);
+                       return true;
+               }
+       }
+       return false;
+}
+
+//pointer kind of a hack, gets the accurate times from a value desc 
+//     (deals with dynamic list member correctly... i.e. gathers activepoints)
+const sinfg::Node::time_set *get_times_from_vdesc(const sinfgapp::ValueDesc &v);
+
+//get's the closest time inside the set
+bool get_closest_time(const sinfg::Node::time_set &tset, const sinfg::Time &t, 
+                                               const sinfg::Time &range, sinfg::Time &out);
+
+//recursion functions based on time restrictions (can be expanded later)...
+//builds a list of relevant waypoints and activepoints inside the timepoints_ref structure
+void recurse_valuedesc(sinfgapp::ValueDesc valdesc, const std::set<sinfg::Time> &tlist,
+                                                               timepoints_ref &vals);
+void recurse_layer(sinfg::Layer::Handle layer, const std::set<sinfg::Time> &tlist, 
+                                                               timepoints_ref &vals);
+void recurse_canvas(sinfg::Canvas::Handle canvas, const std::set<sinfg::Time> &tlist, 
+                                                               timepoints_ref &vals);
+
+
+
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/uimanager.cpp b/synfig-studio/trunk/src/sinfgapp/uimanager.cpp
new file mode 100644 (file)
index 0000000..e9c9e91
--- /dev/null
@@ -0,0 +1,157 @@
+/* === S I N F G =========================================================== */
+/*!    \file uimanager.cpp
+**     \brief Template File
+**
+**     $Id: uimanager.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "uimanager.h"
+#include <iostream>
+#include <string>
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+using namespace sinfgapp;
+
+/* === M A C R O S ========================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+UIInterface::Response
+ConsoleUIInterface::yes_no(const std::string &title, const std::string &message,Response dflt)
+{
+       cout<<title<<": "<<message<<' ';
+       if(dflt==RESPONSE_NO)
+               cout<<_("(no/yes)")<<endl;
+       else
+               cout<<_("(yes/no)")<<endl;
+       string resp;
+       cin>>resp;
+
+       if(dflt==RESPONSE_NO)
+       {
+               if(resp=="yes")
+                       return RESPONSE_YES;
+               else
+                       return RESPONSE_NO;
+       }
+       else
+       {
+               if(resp=="no")
+                       return RESPONSE_NO;
+               else
+                       return RESPONSE_YES;
+       }
+}
+
+UIInterface::Response
+ConsoleUIInterface::yes_no_cancel(const string &title, const string &message,Response dflt)
+{
+       cout<<title<<": "<<message<<' ';
+       if(dflt==RESPONSE_NO)
+               cout<<_("(no/yes)")<<endl;
+       else
+               cout<<_("(yes/no)")<<endl;
+       string resp;
+       cin>>resp;
+
+       if(dflt==RESPONSE_NO)
+       {
+               if(resp=="yes")
+                       return RESPONSE_YES;
+               else
+                       return RESPONSE_NO;
+       }
+       else
+       {
+               if(resp=="no")
+                       return RESPONSE_NO;
+               else
+                       return RESPONSE_YES;
+       }
+}
+
+UIInterface::Response
+ConsoleUIInterface::ok_cancel(const std::string &title, const std::string &message,Response dflt)
+{
+       cout<<title<<": "<<message<<' ';
+       if(dflt==RESPONSE_CANCEL)
+               cout<<_("(cancel/ok)")<<endl;
+       else
+               cout<<_("(ok/cancel)")<<endl;
+       string resp;
+       cin>>resp;
+
+       if(dflt==RESPONSE_CANCEL)
+       {
+               if(resp=="ok")
+                       return RESPONSE_OK;
+               else
+                       return RESPONSE_CANCEL;
+       }
+       else
+       {
+               if(resp=="cancel")
+                       return RESPONSE_CANCEL;
+               else
+                       return RESPONSE_OK;
+       }
+}
+       
+bool
+ConsoleUIInterface::task(const std::string &task)
+{
+       cout<<task<<endl;
+       return true;
+}
+
+bool
+ConsoleUIInterface::error(const std::string &task)
+{
+       cout<<_("error: ")<<task<<endl;
+       return true;
+}
+
+bool
+ConsoleUIInterface::warning(const std::string &task)
+{
+       cout<<_("warning: ")<<task<<endl;
+       return true;
+}
+
+bool
+ConsoleUIInterface::amount_complete(int current, int total)
+{
+       return true;
+}
+
+
+
diff --git a/synfig-studio/trunk/src/sinfgapp/uimanager.h b/synfig-studio/trunk/src/sinfgapp/uimanager.h
new file mode 100644 (file)
index 0000000..72fcb86
--- /dev/null
@@ -0,0 +1,115 @@
+/* === S I N F G =========================================================== */
+/*!    \file uimanager.h
+**     \brief User Interface Manager Class
+**
+**     $Id: uimanager.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_UIMANAGER_H
+#define __SINFG_APP_UIMANAGER_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <ETL/handle>
+#include <sinfg/general.h>
+#include <sinfg/string.h>
+#include <sigc++/object.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class UIInterface : public etl::shared_object, public sinfg::ProgressCallback, public sigc::trackable
+{
+public:
+       enum Response
+       {
+               RESPONSE_CANCEL=-1,
+               RESPONSE_NO=0,
+               RESPONSE_YES=1,
+               RESPONSE_OK=2
+       };
+       virtual ~UIInterface() { }
+       virtual Response yes_no(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)=0;
+       virtual Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)=0;
+       virtual Response ok_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_OK)=0;
+};     
+
+class DefaultUIInterface : public UIInterface
+{
+public:
+       Response yes_no(const std::string &title, const std::string &message,Response dflt)
+               { return dflt; }
+       Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt)
+               { return dflt; }
+       Response ok_cancel(const std::string &title, const std::string &message,Response dflt)
+               { return dflt; }
+       
+       bool task(const std::string &task)
+               { return true; }
+       bool error(const std::string &task)
+               { return true; }
+       bool warning(const std::string &task)
+               { return true; }
+       bool amount_complete(int current, int total)
+               { return true; }
+};     
+
+class ConfidentUIInterface : public UIInterface
+{
+public:
+       Response yes_no(const std::string &title, const std::string &message,Response dflt)
+               { return RESPONSE_YES; }
+       Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt)
+               { return RESPONSE_YES; }
+       Response ok_cancel(const std::string &title, const std::string &message,Response dflt)
+               { return RESPONSE_OK; }
+       
+       bool task(const std::string &task)
+               { return true; }
+       bool error(const std::string &task)
+               { return true; }
+       bool warning(const std::string &task)
+               { return true; }
+       bool amount_complete(int current, int total)
+               { return true; }
+};     
+
+class ConsoleUIInterface : public UIInterface
+{
+public:
+       Response yes_no(const std::string &title, const std::string &message,Response dflt);
+       Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt);
+       Response ok_cancel(const std::string &title, const std::string &message,Response dflt);
+       
+       bool task(const std::string &task);
+       bool error(const std::string &task);
+       bool warning(const std::string &task);
+       bool amount_complete(int current, int total);
+};     
+
+}; // END of namespace sinfgapp
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/sinfgapp/value_desc.h b/synfig-studio/trunk/src/sinfgapp/value_desc.h
new file mode 100644 (file)
index 0000000..66a185c
--- /dev/null
@@ -0,0 +1,182 @@
+/* === S I N F G =========================================================== */
+/*!    \file value_desc.h
+**     \brief Template Header
+**
+**     $Id: value_desc.h,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_APP_VALUE_DESC_H
+#define __SINFG_APP_VALUE_DESC_H
+
+/* === H E A D E R S ======================================================= */
+
+#include <sinfg/valuenode.h>
+#include <sinfg/string.h>
+#include <sinfg/layer.h>
+#include <sinfg/value.h>
+#include <sinfg/valuenode_const.h>
+#include <sinfg/canvas.h>
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace sinfgapp {
+
+class ValueDesc
+{
+       // Info for Layer parent
+       sinfg::Layer::Handle layer;
+       sinfg::String name;
+       
+       // Info for ValueNode parent
+       sinfg::ValueNode::Handle parent_value_node;
+       int index;
+
+       // Info for exported ValueNode
+       sinfg::Canvas::Handle canvas;
+       
+public:
+       bool operator==(const ValueDesc &rhs)const
+       {
+               if((layer||rhs.layer) && layer!=rhs.layer)
+                       return false;
+               if((!name.empty()||!rhs.name.empty()) && name!=rhs.name)
+                       return false;
+               if(layer)
+                       return true;
+               if((canvas||rhs.canvas) && canvas!=rhs.canvas)
+                       return false;
+               if((parent_value_node||rhs.parent_value_node) && parent_value_node!=rhs.parent_value_node)
+                       return false;
+               if((index>-1||rhs.index>-1) && index!=rhs.index)
+                       return false;
+               return true;
+       }
+       bool operator!=(const ValueDesc &rhs)const
+       {
+               return !operator==(rhs);
+       }
+
+       
+       ValueDesc(sinfg::Layer::Handle layer,const sinfg::String& param_name):
+               layer(layer),
+               name(param_name) { }
+
+       ValueDesc(sinfg::Layer::LooseHandle layer,const sinfg::String& param_name):
+               layer(layer),
+               name(param_name) { }
+
+       ValueDesc(sinfg::LinkableValueNode::Handle parent_value_node,int index):
+               parent_value_node(parent_value_node),
+               index(index) { }
+
+//     ValueDesc(sinfg::LinkableValueNode::Handle parent_value_node,const sinfg::String& param_name):
+//             parent_value_node(parent_value_node),
+//             index(parent_value_node->get_link_index_from_name(param_name)) { }
+
+       ValueDesc(sinfg::Canvas::Handle canvas,const sinfg::String& name):
+               name(name),
+               canvas(canvas) { }
+
+       ValueDesc(sinfg::ValueNode_Const::Handle parent_value_node):
+               parent_value_node(parent_value_node),
+               index(-1) { }
+
+       ValueDesc() { }
+
+       bool is_valid()const { return layer || parent_value_node || canvas; }
+       operator bool()const { return is_valid(); }
+
+       bool parent_is_layer_param()const { return (bool)layer; }
+       bool parent_is_value_node()const { return (bool)parent_value_node; }
+       bool parent_is_linkable_value_node()const { return parent_is_value_node() && index>=0; }
+       bool parent_is_value_node_const()const { return parent_is_value_node() && index==-1; }
+       bool parent_is_canvas()const { return (bool)canvas; }
+       
+       bool is_value_node()const { return parent_is_value_node() || parent_is_canvas() || (parent_is_layer_param() && (bool)layer->dynamic_param_list().count(name)); }
+       bool is_const()const { return (parent_is_layer_param() && !layer->dynamic_param_list().count(name)) || parent_is_value_node_const(); }
+       
+       sinfg::Layer::Handle get_layer()const { assert(parent_is_layer_param()); return layer; }
+       const sinfg::String& get_param_name()const { assert(parent_is_layer_param()); return name; }
+       
+       sinfg::ValueNode::Handle get_parent_value_node()const { assert(parent_is_value_node()); return parent_value_node; }
+       int get_index()const { assert(parent_is_linkable_value_node()); return index; }
+       
+       const sinfg::String& get_value_node_id()const { assert(parent_is_canvas()); return name; }
+
+       sinfg::Canvas::Handle get_canvas()const
+       {
+               if(canvas)
+                       return canvas;
+               if(layer)
+                       return layer->get_canvas();
+               if(parent_value_node)
+                       return parent_value_node->get_root_canvas();
+               return 0;
+       }
+       
+       sinfg::ValueNode::Handle
+       get_value_node()const
+       {
+               if(parent_is_canvas())
+                       return canvas->find_value_node(name);
+               if(parent_is_layer_param() && layer->dynamic_param_list().count(name))
+                       return layer->dynamic_param_list().find(name)->second;
+               if(parent_is_linkable_value_node())
+                       return sinfg::LinkableValueNode::Handle::cast_reinterpret(parent_value_node)->get_link(index);
+//                     return reinterpret_cast<sinfg::LinkableValueNode*>(parent_value_node.get())->get_link(index);
+               return 0;
+       }
+
+       sinfg::ValueBase
+       get_value(sinfg::Time time=0)const
+       {
+               if(parent_is_value_node_const() && parent_value_node)
+                       return (*parent_value_node)(0);
+               if(is_value_node() && get_value_node())
+                       return (*get_value_node())(time);
+               if(parent_is_layer_param() && layer)
+                       return layer->get_param(name);
+               return sinfg::ValueBase();
+       }       
+
+       sinfg::ValueBase::Type
+       get_value_type()const
+       {
+               sinfg::ValueNode::Handle value_node=get_value_node();
+               if(value_node)
+                       return value_node->get_type();
+               return get_value().get_type();
+       }
+       
+       bool
+       is_exported()const
+       {
+               return is_value_node() && get_value_node()->is_exported();
+       }
+}; // END of class ValueDesc
+
+}; // END of namespace sinfgapp_instance
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/src/template.cpp b/synfig-studio/trunk/src/template.cpp
new file mode 100644 (file)
index 0000000..bcc31af
--- /dev/null
@@ -0,0 +1,53 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.cpp
+**     \brief Template File
+**
+**     $Id: template.cpp,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+/*
+** Insert headers here
+*/
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace sinfg;
+
+/* === M A C R O S ========================================================= */
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+/* === E N T R Y P O I N T ================================================= */
+
+
diff --git a/synfig-studio/trunk/src/template.h b/synfig-studio/trunk/src/template.h
new file mode 100644 (file)
index 0000000..841f657
--- /dev/null
@@ -0,0 +1,41 @@
+/* === S I N F G =========================================================== */
+/*!    \file template.h
+**     \brief Template Header
+**
+**     $Id: template.h,v 1.1.1.1 2005/01/07 03:34:35 darco Exp $
+**
+**     \legal
+**     Copyright (c) 2002 Robert B. Quattlebaum Jr.
+**
+**     This software and associated documentation
+**     are CONFIDENTIAL and PROPRIETARY property of
+**     the above-mentioned copyright holder.
+**
+**     You may not copy, print, publish, or in any
+**     other way distribute this software without
+**     a prior written agreement with
+**     the copyright holder.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === S T A R T =========================================================== */
+
+#ifndef __SINFG_TEMPLATE_H
+#define __SINFG_TEMPLATE_H
+
+/* === H E A D E R S ======================================================= */
+
+/* === M A C R O S ========================================================= */
+
+/* === T Y P E D E F S ===================================================== */
+
+/* === C L A S S E S & S T R U C T S ======================================= */
+
+namespace studio {
+       
+}; // END of namespace studio
+
+/* === E N D =============================================================== */
+
+#endif
diff --git a/synfig-studio/trunk/studio.kdevprj b/synfig-studio/trunk/studio.kdevprj
new file mode 100644 (file)
index 0000000..d3f5f34
--- /dev/null
@@ -0,0 +1,395 @@
+[./ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./Makefile.am]
+files=./README,./studio.kdevprj,./INSTALL,./ChangeLog,./bootstrap,
+sub_dirs=src,config,
+type=normal
+
+[./README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./bootstrap]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[./studio.kdevprj]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[ChangeLog]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[Config for BinMakefileAm]
+addcxxflags=
+bin_program=sinfgstudio
+cflags=
+cppflags=
+cxxflags=\s-O1
+ldadd=
+ldflags=\s\s
+libtool_dir=./libtool/
+path_to_bin_program=./src
+
+[General]
+AMChanged=false
+author=darco
+configure_args=\s--build=i386-linux --host=i386-linux --target=i386-linux --enable-debug\s
+debug_args=images/studio_about.sif
+dir_where_make_will_be_called=./
+email=darco@alnitak.orion.voria.net
+kdevprj_version=1.3
+lfv_open_groups=
+make_options=\s-j2 -l 2 -j 2
+makefiles=./Makefile.am,config/Makefile.am,src/Makefile.am,images/Makefile.am,Makefile.am,src/gtkmm/Makefile.am
+modifyMakefiles=false
+project_name=studio
+project_type=normal_empty
+short_info=
+sub_dir=
+version=
+version_control=CVS
+workspace=1
+
+[INSTALL]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[LFV Groups]
+GNU=AUTHORS,COPYING,ChangeLog,INSTALL,README,TODO,NEWS,
+Headers=*.h,*.hxx,*.hpp,*.H,
+Others=*,
+Sources=*.cpp,*.c,*.cc,*.C,*.cxx,*.ec,*.ecpp,*.lxx,*.l++,*.ll,*.l,
+Translations=*.ts,*.po,
+User Interface=*.ui,*.kdevdlg,*.rc,
+groups=Headers,Sources,GNU,Translations,User Interface,Others
+
+[Makefile.am]
+dist=true
+files=bootstrap,ChangeLog,INSTALL,Makefile.am,README
+install=false
+install_location=
+sub_dirs=src,images
+type=DATA
+
+[README]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[bootstrap]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/ETL.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/Makefile.am]
+files=config/ETL.m4,config/libxml.m4,config/sinfg.m4,config/configure.ac,config/cxx_macros.m4,config/project.spec.in,config/build.cfg,config/gnome.m4,
+sub_dirs=
+type=normal
+
+[config/build.cfg]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/configure.ac]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/cxx_macros.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/gnome.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/libxml.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/project.spec.in]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[config/sinfg.m4]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[images/Makefile.am]
+dist=true
+files=images/studio_about.sif,images/Makefile.am,images/about_dialog.sif,images/about_icon.sif,images/canvas_icon.sif
+install=false
+install_location=
+sub_dirs=
+type=DATA
+
+[images/about_dialog.sif]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[images/about_icon.sif]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[images/canvas_icon.sif]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[images/studio_about.sif]
+dist=true
+install=false
+install_location=
+type=DATA
+
+[src/Makefile.am]
+dist=true
+files=src/main.cpp,src/template.cpp,src/template.h,src/Makefile.am,src/app.h,src/app.cpp,src/instance.cpp,src/instance.h,src/actions.h,src/actions.cpp,src/toolbox.h,src/toolbox.cpp,src/compview.h,src/compview.cpp,src/canvasview.cpp,src/canvasview.h,src/workarea.cpp,src/workarea.h
+install=false
+install_location=
+sub_dirs=gtkmm
+type=static_library
+
+[src/actions.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/actions.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/app.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/app.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/canvasview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/canvasview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/compview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/compview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/Makefile.am]
+dist=true
+files=src/gtkmm/app.cpp,src/gtkmm/app.h,src/gtkmm/Makefile.am,src/gtkmm/instance.h,src/gtkmm/instance.cpp,src/gtkmm/toolbox.h,src/gtkmm/toolbox.cpp,src/gtkmm/compview.cpp,src/gtkmm/compview.h,src/gtkmm/canvasview.cpp,src/gtkmm/canvasview.h,src/gtkmm/workarea.cpp,src/gtkmm/workarea.h,src/gtkmm/about.h,src/gtkmm/about.cpp
+install=false
+install_location=
+sharedlib_LDFLAGS=-version-info 0:0:0
+sharedlib_rootname=gtkmm
+sub_dirs=
+type=static_library
+
+[src/gtkmm/about.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/about.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/app.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/app.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/canvasview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/canvasview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/compview.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/compview.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/instance.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/instance.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/toolbox.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/toolbox.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/gtkmm/workarea.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/gtkmm/workarea.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/instance.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/instance.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/main.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/template.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/template.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/toolbox.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/toolbox.h]
+dist=true
+install=false
+install_location=
+type=HEADER
+
+[src/workarea.cpp]
+dist=true
+install=false
+install_location=
+type=SOURCE
+
+[src/workarea.h]
+dist=true
+install=false
+install_location=
+type=HEADER
diff --git a/synfig-studio/trunk/studio.pbproj/project.pbxproj b/synfig-studio/trunk/studio.pbproj/project.pbxproj
new file mode 100755 (executable)
index 0000000..485d024
--- /dev/null
@@ -0,0 +1,4588 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 38;
+       objects = {
+               A630F0B6047D9BEB0006EC77 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = duckmatic.cpp;
+                       path = src/gtkmm/duckmatic.cpp;
+                       refType = 4;
+               };
+               A630F0B7047D9BEB0006EC77 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = duckmatic.h;
+                       path = src/gtkmm/duckmatic.h;
+                       refType = 4;
+               };
+               A630F0B8047D9BEB0006EC77 = {
+                       fileRef = A630F0B6047D9BEB0006EC77;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A630F0B9047D9BEB0006EC77 = {
+                       fileRef = A630F0B7047D9BEB0006EC77;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE1605446F1500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = eventkey.h;
+                       path = src/gtkmm/eventkey.h;
+                       refType = 4;
+               };
+               A63EEE1705446F1500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_eyedrop.cpp;
+                       path = src/gtkmm/state_eyedrop.cpp;
+                       refType = 4;
+               };
+               A63EEE1805446F1500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_eyedrop.h;
+                       path = src/gtkmm/state_eyedrop.h;
+                       refType = 4;
+               };
+               A63EEE1905446F1500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_normal.cpp;
+                       path = src/gtkmm/state_normal.cpp;
+                       refType = 4;
+               };
+               A63EEE1A05446F1500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_normal.h;
+                       path = src/gtkmm/state_normal.h;
+                       refType = 4;
+               };
+               A63EEE1B05446F1500140006 = {
+                       fileRef = A63EEE1605446F1500140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE1C05446F1500140006 = {
+                       fileRef = A63EEE1705446F1500140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE1D05446F1500140006 = {
+                       fileRef = A63EEE1805446F1500140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE1E05446F1500140006 = {
+                       fileRef = A63EEE1905446F1500140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE1F05446F1500140006 = {
+                       fileRef = A63EEE1A05446F1500140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE2005446F5B00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layersetdesc.cpp;
+                       path = src/sinfgapp/actions/layersetdesc.cpp;
+                       refType = 4;
+               };
+               A63EEE2105446F5B00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layersetdesc.h;
+                       path = src/sinfgapp/actions/layersetdesc.h;
+                       refType = 4;
+               };
+               A63EEE2205446F5B00140006 = {
+                       fileRef = A63EEE2005446F5B00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63EEE2305446F5B00140006 = {
+                       fileRef = A63EEE2105446F5B00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63F3B46054DAC3A00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cvs.cpp;
+                       path = src/sinfgapp/cvs.cpp;
+                       refType = 4;
+               };
+               A63F3B47054DAC3A00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cvs.h;
+                       path = src/sinfgapp/cvs.h;
+                       refType = 4;
+               };
+               A63F3B48054DAC3A00140006 = {
+                       fileRef = A63F3B46054DAC3A00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63F3B49054DAC3A00140006 = {
+                       fileRef = A63F3B47054DAC3A00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63F3B4A054DAC6A00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = onemoment.cpp;
+                       path = src/gtkmm/onemoment.cpp;
+                       refType = 4;
+               };
+               A63F3B4B054DAC6A00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = onemoment.h;
+                       path = src/gtkmm/onemoment.h;
+                       refType = 4;
+               };
+               A63F3B4C054DAC6A00140006 = {
+                       fileRef = A63F3B4A054DAC6A00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63F3B4D054DAC6A00140006 = {
+                       fileRef = A63F3B4B054DAC6A00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A63F3B4E054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = angle_icon.sif;
+                       path = images/angle_icon.sif;
+                       refType = 4;
+               };
+               A63F3B4F054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blinepoint_icon.sif;
+                       path = images/blinepoint_icon.sif;
+                       refType = 4;
+               };
+               A63F3B50054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = bool_icon.sif;
+                       path = images/bool_icon.sif;
+                       refType = 4;
+               };
+               A63F3B51054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvas_pointer_icon.sif;
+                       path = images/canvas_pointer_icon.sif;
+                       refType = 4;
+               };
+               A63F3B52054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = eyedrop_icon.sif;
+                       path = images/eyedrop_icon.sif;
+                       refType = 4;
+               };
+               A63F3B53054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = integer_icon.sif;
+                       path = images/integer_icon.sif;
+                       refType = 4;
+               };
+               A63F3B54054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = list_icon.sif;
+                       path = images/list_icon.sif;
+                       refType = 4;
+               };
+               A63F3B55054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = saveall_icon.sif;
+                       path = images/saveall_icon.sif;
+                       refType = 4;
+               };
+               A63F3B56054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = segment_icon.sif;
+                       path = images/segment_icon.sif;
+                       refType = 4;
+               };
+               A63F3B57054DACB700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = string_icon.sif;
+                       path = images/string_icon.sif;
+                       refType = 4;
+               };
+               A64DD827057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = childrentree.cpp;
+                       path = src/gtkmm/childrentree.cpp;
+                       refType = 4;
+               };
+               A64DD828057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = childrentree.h;
+                       path = src/gtkmm/childrentree.h;
+                       refType = 4;
+               };
+               A64DD829057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = duck.cpp;
+                       path = src/gtkmm/duck.cpp;
+                       refType = 4;
+               };
+               A64DD82A057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = duck.h;
+                       path = src/gtkmm/duck.h;
+                       refType = 4;
+               };
+               A64DD82B057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ducktransform_rotate.h;
+                       path = src/gtkmm/ducktransform_rotate.h;
+                       refType = 4;
+               };
+               A64DD82C057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ducktransform_scale.h;
+                       path = src/gtkmm/ducktransform_scale.h;
+                       refType = 4;
+               };
+               A64DD82D057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ducktransform_translate.h;
+                       path = src/gtkmm/ducktransform_translate.h;
+                       refType = 4;
+               };
+               A64DD82E057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = event_layerclick.h;
+                       path = src/gtkmm/event_layerclick.h;
+                       refType = 4;
+               };
+               A64DD82F057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = event_mouse.h;
+                       path = src/gtkmm/event_mouse.h;
+                       refType = 4;
+               };
+               A64DD830057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = smach.h;
+                       path = src/gtkmm/smach.h;
+                       refType = 4;
+               };
+               A64DD831057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_roto.cpp;
+                       path = src/gtkmm/state_roto.cpp;
+                       refType = 4;
+               };
+               A64DD832057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_roto.h;
+                       path = src/gtkmm/state_roto.h;
+                       refType = 4;
+               };
+               A64DD833057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_scribble.cpp;
+                       path = src/gtkmm/state_scribble.cpp;
+                       refType = 4;
+               };
+               A64DD834057FEEF700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_scribble.h;
+                       path = src/gtkmm/state_scribble.h;
+                       refType = 4;
+               };
+               A64DD835057FEEF700140006 = {
+                       fileRef = A64DD827057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD836057FEEF700140006 = {
+                       fileRef = A64DD828057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD837057FEEF700140006 = {
+                       fileRef = A64DD829057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD838057FEEF700140006 = {
+                       fileRef = A64DD82A057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD839057FEEF700140006 = {
+                       fileRef = A64DD82B057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83A057FEEF700140006 = {
+                       fileRef = A64DD82C057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83B057FEEF700140006 = {
+                       fileRef = A64DD82D057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83C057FEEF700140006 = {
+                       fileRef = A64DD82E057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83D057FEEF700140006 = {
+                       fileRef = A64DD82F057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83E057FEEF700140006 = {
+                       fileRef = A64DD830057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD83F057FEEF700140006 = {
+                       fileRef = A64DD831057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD840057FEEF700140006 = {
+                       fileRef = A64DD832057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD841057FEEF700140006 = {
+                       fileRef = A64DD833057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD842057FEEF700140006 = {
+                       fileRef = A64DD834057FEEF700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD843057FEF2300140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blineconvert.cpp;
+                       path = src/sinfgapp/blineconvert.cpp;
+                       refType = 4;
+               };
+               A64DD844057FEF2300140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blineconvert.h;
+                       path = src/sinfgapp/blineconvert.h;
+                       refType = 4;
+               };
+               A64DD845057FEF2300140006 = {
+                       fileRef = A64DD843057FEF2300140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64DD846057FEF2300140006 = {
+                       fileRef = A64DD844057FEF2300140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64EF68F059F5D9D00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_fill.cpp;
+                       path = src/gtkmm/state_fill.cpp;
+                       refType = 4;
+               };
+               A64EF690059F5D9D00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = state_fill.h;
+                       path = src/gtkmm/state_fill.h;
+                       refType = 4;
+               };
+               A64EF691059F5D9E00140006 = {
+                       fileRef = A64EF68F059F5D9D00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64EF692059F5D9E00140006 = {
+                       fileRef = A64EF690059F5D9D00140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64EF693059F5DAF00140006 = {
+                       children = (
+                               A63EEE1705446F1500140006,
+                               A63EEE1805446F1500140006,
+                               A63EEE1905446F1500140006,
+                               A63EEE1A05446F1500140006,
+                               A64DD831057FEEF700140006,
+                               A64DD832057FEEF700140006,
+                               A64DD833057FEEF700140006,
+                               A64DD834057FEEF700140006,
+                               A64EF68F059F5D9D00140006,
+                               A64EF690059F5D9D00140006,
+                               A64F6ECB052AA6B100140006,
+                               A64F6ECC052AA6B100140006,
+                               A64F6ECD052AA6B100140006,
+                               A64F6ECE052AA6B100140006,
+                       );
+                       isa = PBXGroup;
+                       name = States;
+                       refType = 4;
+               };
+               A64EF694059F5EE900140006 = {
+                       children = (
+                               A63EEE1605446F1500140006,
+                               A64DD82E057FEEF700140006,
+                               A64DD82F057FEEF700140006,
+                       );
+                       isa = PBXGroup;
+                       name = "Event Stuff";
+                       refType = 4;
+               };
+               A64EF695059F5F2000140006 = {
+                       children = (
+                               A630F0B6047D9BEB0006EC77,
+                               A630F0B7047D9BEB0006EC77,
+                               A64DD829057FEEF700140006,
+                               A64DD82A057FEEF700140006,
+                               A64DD82B057FEEF700140006,
+                               A64DD82C057FEEF700140006,
+                               A64DD82D057FEEF700140006,
+                       );
+                       isa = PBXGroup;
+                       name = "Duck Stuff";
+                       refType = 4;
+               };
+               A64EF696059F5F5100140006 = {
+                       children = (
+                               A658A9C4047AC2E400A80006,
+                               A658A9C5047AC2E400A80006,
+                               A658A9CC047AC2E400A80006,
+                               A658A9CD047AC2E400A80006,
+                               A658A9D0047AC2E400A80006,
+                               A658A9D1047AC2E400A80006,
+                               A658A9D4047AC2E400A80006,
+                               A658A9D5047AC2E400A80006,
+                               A658A9D6047AC2E400A80006,
+                               A658A9D7047AC2E400A80006,
+                               A658A9D8047AC2E400A80006,
+                               A658A9D9047AC2E400A80006,
+                               A658A9DA047AC2E400A80006,
+                               A658A9DB047AC2E400A80006,
+                               A64DD827057FEEF700140006,
+                               A64DD828057FEEF700140006,
+                       );
+                       isa = PBXGroup;
+                       name = "Tree Stuff";
+                       refType = 4;
+               };
+               A64EF697059F5FE500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = fill_icon.sif;
+                       path = images/fill_icon.sif;
+                       refType = 4;
+               };
+               A64F6D2A052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action_param.cpp;
+                       path = src/sinfgapp/action_param.cpp;
+                       refType = 4;
+               };
+               A64F6D2B052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action_param.h;
+                       path = src/sinfgapp/action_param.h;
+                       refType = 4;
+               };
+               A64F6D2C052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action_system.cpp;
+                       path = src/sinfgapp/action_system.cpp;
+                       refType = 4;
+               };
+               A64F6D2D052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action_system.h;
+                       path = src/sinfgapp/action_system.h;
+                       refType = 4;
+               };
+               A64F6D2E052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = editmode.h;
+                       path = src/sinfgapp/editmode.h;
+                       refType = 4;
+               };
+               A64F6D2F052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = main.cpp;
+                       path = src/sinfgapp/main.cpp;
+                       refType = 4;
+               };
+               A64F6D30052AA52700140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = main.h;
+                       path = src/sinfgapp/main.h;
+                       refType = 4;
+               };
+               A64F6D31052AA52700140006 = {
+                       fileRef = A64F6D2A052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D32052AA52700140006 = {
+                       fileRef = A64F6D2B052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               A64F6D33052AA52700140006 = {
+                       fileRef = A64F6D2C052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D34052AA52700140006 = {
+                       fileRef = A64F6D2D052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               A64F6D35052AA52700140006 = {
+                       fileRef = A64F6D2E052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               A64F6D36052AA52700140006 = {
+                       fileRef = A64F6D2F052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D37052AA52700140006 = {
+                       fileRef = A64F6D30052AA52700140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               A64F6D38052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointadd.cpp;
+                       path = src/sinfgapp/actions/activepointadd.cpp;
+                       refType = 4;
+               };
+               A64F6D39052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointadd.h;
+                       path = src/sinfgapp/actions/activepointadd.h;
+                       refType = 4;
+               };
+               A64F6D3A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointremove.cpp;
+                       path = src/sinfgapp/actions/activepointremove.cpp;
+                       refType = 4;
+               };
+               A64F6D3B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointremove.h;
+                       path = src/sinfgapp/actions/activepointremove.h;
+                       refType = 4;
+               };
+               A64F6D3C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointset.cpp;
+                       path = src/sinfgapp/actions/activepointset.cpp;
+                       refType = 4;
+               };
+               A64F6D3D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointset.h;
+                       path = src/sinfgapp/actions/activepointset.h;
+                       refType = 4;
+               };
+               A64F6D3E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointsetoff.cpp;
+                       path = src/sinfgapp/actions/activepointsetoff.cpp;
+                       refType = 4;
+               };
+               A64F6D3F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointsetoff.h;
+                       path = src/sinfgapp/actions/activepointsetoff.h;
+                       refType = 4;
+               };
+               A64F6D40052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointseton.cpp;
+                       path = src/sinfgapp/actions/activepointseton.cpp;
+                       refType = 4;
+               };
+               A64F6D41052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointseton.h;
+                       path = src/sinfgapp/actions/activepointseton.h;
+                       refType = 4;
+               };
+               A64F6D42052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointsetsmart.cpp;
+                       path = src/sinfgapp/actions/activepointsetsmart.cpp;
+                       refType = 4;
+               };
+               A64F6D43052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = activepointsetsmart.h;
+                       path = src/sinfgapp/actions/activepointsetsmart.h;
+                       refType = 4;
+               };
+               A64F6D44052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blinepointtangentmerge.cpp;
+                       path = src/sinfgapp/actions/blinepointtangentmerge.cpp;
+                       refType = 4;
+               };
+               A64F6D45052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blinepointtangentmerge.h;
+                       path = src/sinfgapp/actions/blinepointtangentmerge.h;
+                       refType = 4;
+               };
+               A64F6D46052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blinepointtangentsplit.cpp;
+                       path = src/sinfgapp/actions/blinepointtangentsplit.cpp;
+                       refType = 4;
+               };
+               A64F6D47052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = blinepointtangentsplit.h;
+                       path = src/sinfgapp/actions/blinepointtangentsplit.h;
+                       refType = 4;
+               };
+               A64F6D48052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasadd.cpp;
+                       path = src/sinfgapp/actions/canvasadd.cpp;
+                       refType = 4;
+               };
+               A64F6D49052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasadd.h;
+                       path = src/sinfgapp/actions/canvasadd.h;
+                       refType = 4;
+               };
+               A64F6D4A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasremove.cpp;
+                       path = src/sinfgapp/actions/canvasremove.cpp;
+                       refType = 4;
+               };
+               A64F6D4B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasremove.h;
+                       path = src/sinfgapp/actions/canvasremove.h;
+                       refType = 4;
+               };
+               A64F6D4C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasrenddescset.cpp;
+                       path = src/sinfgapp/actions/canvasrenddescset.cpp;
+                       refType = 4;
+               };
+               A64F6D4D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasrenddescset.h;
+                       path = src/sinfgapp/actions/canvasrenddescset.h;
+                       refType = 4;
+               };
+               A64F6D4E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = editmodeset.cpp;
+                       path = src/sinfgapp/actions/editmodeset.cpp;
+                       refType = 4;
+               };
+               A64F6D4F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = editmodeset.h;
+                       path = src/sinfgapp/actions/editmodeset.h;
+                       refType = 4;
+               };
+               A64F6D50052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeadd.cpp;
+                       path = src/sinfgapp/actions/keyframeadd.cpp;
+                       refType = 4;
+               };
+               A64F6D51052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeadd.h;
+                       path = src/sinfgapp/actions/keyframeadd.h;
+                       refType = 4;
+               };
+               A64F6D52052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeduplicate.cpp;
+                       path = src/sinfgapp/actions/keyframeduplicate.cpp;
+                       refType = 4;
+               };
+               A64F6D53052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeduplicate.h;
+                       path = src/sinfgapp/actions/keyframeduplicate.h;
+                       refType = 4;
+               };
+               A64F6D54052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeremove.cpp;
+                       path = src/sinfgapp/actions/keyframeremove.cpp;
+                       refType = 4;
+               };
+               A64F6D55052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeremove.h;
+                       path = src/sinfgapp/actions/keyframeremove.h;
+                       refType = 4;
+               };
+               A64F6D56052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeset.cpp;
+                       path = src/sinfgapp/actions/keyframeset.cpp;
+                       refType = 4;
+               };
+               A64F6D57052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframeset.h;
+                       path = src/sinfgapp/actions/keyframeset.h;
+                       refType = 4;
+               };
+               A64F6D58052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layeractivate.cpp;
+                       path = src/sinfgapp/actions/layeractivate.cpp;
+                       refType = 4;
+               };
+               A64F6D59052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layeractivate.h;
+                       path = src/sinfgapp/actions/layeractivate.h;
+                       refType = 4;
+               };
+               A64F6D5A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layeradd.cpp;
+                       path = src/sinfgapp/actions/layeradd.cpp;
+                       refType = 4;
+               };
+               A64F6D5B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layeradd.h;
+                       path = src/sinfgapp/actions/layeradd.h;
+                       refType = 4;
+               };
+               A64F6D5C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerduplicate.cpp;
+                       path = src/sinfgapp/actions/layerduplicate.cpp;
+                       refType = 4;
+               };
+               A64F6D5D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerduplicate.h;
+                       path = src/sinfgapp/actions/layerduplicate.h;
+                       refType = 4;
+               };
+               A64F6D5E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerencapsulate.cpp;
+                       path = src/sinfgapp/actions/layerencapsulate.cpp;
+                       refType = 4;
+               };
+               A64F6D5F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerencapsulate.h;
+                       path = src/sinfgapp/actions/layerencapsulate.h;
+                       refType = 4;
+               };
+               A64F6D60052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerlower.cpp;
+                       path = src/sinfgapp/actions/layerlower.cpp;
+                       refType = 4;
+               };
+               A64F6D61052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerlower.h;
+                       path = src/sinfgapp/actions/layerlower.h;
+                       refType = 4;
+               };
+               A64F6D62052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layermove.cpp;
+                       path = src/sinfgapp/actions/layermove.cpp;
+                       refType = 4;
+               };
+               A64F6D63052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layermove.h;
+                       path = src/sinfgapp/actions/layermove.h;
+                       refType = 4;
+               };
+               A64F6D64052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamconnect.cpp;
+                       path = src/sinfgapp/actions/layerparamconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D65052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamconnect.h;
+                       path = src/sinfgapp/actions/layerparamconnect.h;
+                       refType = 4;
+               };
+               A64F6D66052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamdisconnect.cpp;
+                       path = src/sinfgapp/actions/layerparamdisconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D67052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamdisconnect.h;
+                       path = src/sinfgapp/actions/layerparamdisconnect.h;
+                       refType = 4;
+               };
+               A64F6D68052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamset.cpp;
+                       path = src/sinfgapp/actions/layerparamset.cpp;
+                       refType = 4;
+               };
+               A64F6D69052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerparamset.h;
+                       path = src/sinfgapp/actions/layerparamset.h;
+                       refType = 4;
+               };
+               A64F6D6A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerraise.cpp;
+                       path = src/sinfgapp/actions/layerraise.cpp;
+                       refType = 4;
+               };
+               A64F6D6B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerraise.h;
+                       path = src/sinfgapp/actions/layerraise.h;
+                       refType = 4;
+               };
+               A64F6D6C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerremove.cpp;
+                       path = src/sinfgapp/actions/layerremove.cpp;
+                       refType = 4;
+               };
+               A64F6D6D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layerremove.h;
+                       path = src/sinfgapp/actions/layerremove.h;
+                       refType = 4;
+               };
+               A64F6D6E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescconnect.cpp;
+                       path = src/sinfgapp/actions/valuedescconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D6F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescconnect.h;
+                       path = src/sinfgapp/actions/valuedescconnect.h;
+                       refType = 4;
+               };
+               A64F6D70052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescconvert.cpp;
+                       path = src/sinfgapp/actions/valuedescconvert.cpp;
+                       refType = 4;
+               };
+               A64F6D71052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescconvert.h;
+                       path = src/sinfgapp/actions/valuedescconvert.h;
+                       refType = 4;
+               };
+               A64F6D72052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescdisconnect.cpp;
+                       path = src/sinfgapp/actions/valuedescdisconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D73052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescdisconnect.h;
+                       path = src/sinfgapp/actions/valuedescdisconnect.h;
+                       refType = 4;
+               };
+               A64F6D74052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescexport.cpp;
+                       path = src/sinfgapp/actions/valuedescexport.cpp;
+                       refType = 4;
+               };
+               A64F6D75052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescexport.h;
+                       path = src/sinfgapp/actions/valuedescexport.h;
+                       refType = 4;
+               };
+               A64F6D76052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescset.cpp;
+                       path = src/sinfgapp/actions/valuedescset.cpp;
+                       refType = 4;
+               };
+               A64F6D77052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuedescset.h;
+                       path = src/sinfgapp/actions/valuedescset.h;
+                       refType = 4;
+               };
+               A64F6D78052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodeadd.cpp;
+                       path = src/sinfgapp/actions/valuenodeadd.cpp;
+                       refType = 4;
+               };
+               A64F6D79052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodeadd.h;
+                       path = src/sinfgapp/actions/valuenodeadd.h;
+                       refType = 4;
+               };
+               A64F6D7A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodeconstset.cpp;
+                       path = src/sinfgapp/actions/valuenodeconstset.cpp;
+                       refType = 4;
+               };
+               A64F6D7B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodeconstset.h;
+                       path = src/sinfgapp/actions/valuenodeconstset.h;
+                       refType = 4;
+               };
+               A64F6D7C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistinsert.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistinsert.cpp;
+                       refType = 4;
+               };
+               A64F6D7D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistinsert.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistinsert.h;
+                       refType = 4;
+               };
+               A64F6D7E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistinsertsmart.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistinsertsmart.cpp;
+                       refType = 4;
+               };
+               A64F6D7F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistinsertsmart.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistinsertsmart.h;
+                       refType = 4;
+               };
+               A64F6D80052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistloop.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistloop.cpp;
+                       refType = 4;
+               };
+               A64F6D81052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistloop.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistloop.h;
+                       refType = 4;
+               };
+               A64F6D82052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistremove.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistremove.cpp;
+                       refType = 4;
+               };
+               A64F6D83052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistremove.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistremove.h;
+                       refType = 4;
+               };
+               A64F6D84052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistremovesmart.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistremovesmart.cpp;
+                       refType = 4;
+               };
+               A64F6D85052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistremovesmart.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistremovesmart.h;
+                       refType = 4;
+               };
+               A64F6D86052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistunloop.cpp;
+                       path = src/sinfgapp/actions/valuenodedynamiclistunloop.cpp;
+                       refType = 4;
+               };
+               A64F6D87052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodedynamiclistunloop.h;
+                       path = src/sinfgapp/actions/valuenodedynamiclistunloop.h;
+                       refType = 4;
+               };
+               A64F6D88052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodelinkconnect.cpp;
+                       path = src/sinfgapp/actions/valuenodelinkconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D89052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodelinkconnect.h;
+                       path = src/sinfgapp/actions/valuenodelinkconnect.h;
+                       refType = 4;
+               };
+               A64F6D8A052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodelinkdisconnect.cpp;
+                       path = src/sinfgapp/actions/valuenodelinkdisconnect.cpp;
+                       refType = 4;
+               };
+               A64F6D8B052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodelinkdisconnect.h;
+                       path = src/sinfgapp/actions/valuenodelinkdisconnect.h;
+                       refType = 4;
+               };
+               A64F6D8C052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenoderemove.cpp;
+                       path = src/sinfgapp/actions/valuenoderemove.cpp;
+                       refType = 4;
+               };
+               A64F6D8D052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenoderemove.h;
+                       path = src/sinfgapp/actions/valuenoderemove.h;
+                       refType = 4;
+               };
+               A64F6D8E052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenoderename.cpp;
+                       path = src/sinfgapp/actions/valuenoderename.cpp;
+                       refType = 4;
+               };
+               A64F6D8F052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenoderename.h;
+                       path = src/sinfgapp/actions/valuenoderename.h;
+                       refType = 4;
+               };
+               A64F6D90052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodereplace.cpp;
+                       path = src/sinfgapp/actions/valuenodereplace.cpp;
+                       refType = 4;
+               };
+               A64F6D91052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenodereplace.h;
+                       path = src/sinfgapp/actions/valuenodereplace.h;
+                       refType = 4;
+               };
+               A64F6D92052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointadd.cpp;
+                       path = src/sinfgapp/actions/waypointadd.cpp;
+                       refType = 4;
+               };
+               A64F6D93052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointadd.h;
+                       path = src/sinfgapp/actions/waypointadd.h;
+                       refType = 4;
+               };
+               A64F6D94052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointremove.cpp;
+                       path = src/sinfgapp/actions/waypointremove.cpp;
+                       refType = 4;
+               };
+               A64F6D95052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointremove.h;
+                       path = src/sinfgapp/actions/waypointremove.h;
+                       refType = 4;
+               };
+               A64F6D96052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointset.cpp;
+                       path = src/sinfgapp/actions/waypointset.cpp;
+                       refType = 4;
+               };
+               A64F6D97052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointset.h;
+                       path = src/sinfgapp/actions/waypointset.h;
+                       refType = 4;
+               };
+               A64F6D98052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointsetsmart.cpp;
+                       path = src/sinfgapp/actions/waypointsetsmart.cpp;
+                       refType = 4;
+               };
+               A64F6D99052AA5C100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = waypointsetsmart.h;
+                       path = src/sinfgapp/actions/waypointsetsmart.h;
+                       refType = 4;
+               };
+               A64F6D9A052AA5C100140006 = {
+                       fileRef = A64F6D38052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D9B052AA5C100140006 = {
+                       fileRef = A64F6D39052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D9C052AA5C100140006 = {
+                       fileRef = A64F6D3A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D9D052AA5C100140006 = {
+                       fileRef = A64F6D3B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D9E052AA5C100140006 = {
+                       fileRef = A64F6D3C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6D9F052AA5C100140006 = {
+                       fileRef = A64F6D3D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA0052AA5C100140006 = {
+                       fileRef = A64F6D3E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA1052AA5C100140006 = {
+                       fileRef = A64F6D3F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA2052AA5C100140006 = {
+                       fileRef = A64F6D40052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA3052AA5C100140006 = {
+                       fileRef = A64F6D41052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA4052AA5C100140006 = {
+                       fileRef = A64F6D42052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA5052AA5C100140006 = {
+                       fileRef = A64F6D43052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA6052AA5C100140006 = {
+                       fileRef = A64F6D44052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA7052AA5C100140006 = {
+                       fileRef = A64F6D45052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA8052AA5C100140006 = {
+                       fileRef = A64F6D46052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DA9052AA5C100140006 = {
+                       fileRef = A64F6D47052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAA052AA5C100140006 = {
+                       fileRef = A64F6D48052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAB052AA5C100140006 = {
+                       fileRef = A64F6D49052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAC052AA5C100140006 = {
+                       fileRef = A64F6D4A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAD052AA5C100140006 = {
+                       fileRef = A64F6D4B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAE052AA5C100140006 = {
+                       fileRef = A64F6D4C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DAF052AA5C100140006 = {
+                       fileRef = A64F6D4D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB0052AA5C100140006 = {
+                       fileRef = A64F6D4E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB1052AA5C100140006 = {
+                       fileRef = A64F6D4F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB2052AA5C100140006 = {
+                       fileRef = A64F6D50052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB3052AA5C100140006 = {
+                       fileRef = A64F6D51052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB4052AA5C100140006 = {
+                       fileRef = A64F6D52052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB5052AA5C100140006 = {
+                       fileRef = A64F6D53052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB6052AA5C100140006 = {
+                       fileRef = A64F6D54052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB7052AA5C100140006 = {
+                       fileRef = A64F6D55052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB8052AA5C100140006 = {
+                       fileRef = A64F6D56052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DB9052AA5C100140006 = {
+                       fileRef = A64F6D57052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBA052AA5C100140006 = {
+                       fileRef = A64F6D58052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBB052AA5C100140006 = {
+                       fileRef = A64F6D59052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBC052AA5C100140006 = {
+                       fileRef = A64F6D5A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBD052AA5C100140006 = {
+                       fileRef = A64F6D5B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBE052AA5C100140006 = {
+                       fileRef = A64F6D5C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DBF052AA5C100140006 = {
+                       fileRef = A64F6D5D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC0052AA5C100140006 = {
+                       fileRef = A64F6D5E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC1052AA5C100140006 = {
+                       fileRef = A64F6D5F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC2052AA5C100140006 = {
+                       fileRef = A64F6D60052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC3052AA5C100140006 = {
+                       fileRef = A64F6D61052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC4052AA5C100140006 = {
+                       fileRef = A64F6D62052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC5052AA5C100140006 = {
+                       fileRef = A64F6D63052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC6052AA5C100140006 = {
+                       fileRef = A64F6D64052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC7052AA5C100140006 = {
+                       fileRef = A64F6D65052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC8052AA5C100140006 = {
+                       fileRef = A64F6D66052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DC9052AA5C100140006 = {
+                       fileRef = A64F6D67052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCA052AA5C100140006 = {
+                       fileRef = A64F6D68052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCB052AA5C100140006 = {
+                       fileRef = A64F6D69052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCC052AA5C100140006 = {
+                       fileRef = A64F6D6A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCD052AA5C100140006 = {
+                       fileRef = A64F6D6B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCE052AA5C100140006 = {
+                       fileRef = A64F6D6C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DCF052AA5C100140006 = {
+                       fileRef = A64F6D6D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD0052AA5C100140006 = {
+                       fileRef = A64F6D6E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD1052AA5C100140006 = {
+                       fileRef = A64F6D6F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD2052AA5C100140006 = {
+                       fileRef = A64F6D70052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD3052AA5C100140006 = {
+                       fileRef = A64F6D71052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD4052AA5C100140006 = {
+                       fileRef = A64F6D72052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD5052AA5C100140006 = {
+                       fileRef = A64F6D73052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD6052AA5C100140006 = {
+                       fileRef = A64F6D74052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD7052AA5C100140006 = {
+                       fileRef = A64F6D75052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD8052AA5C100140006 = {
+                       fileRef = A64F6D76052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DD9052AA5C100140006 = {
+                       fileRef = A64F6D77052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDA052AA5C100140006 = {
+                       fileRef = A64F6D78052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDB052AA5C100140006 = {
+                       fileRef = A64F6D79052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDC052AA5C100140006 = {
+                       fileRef = A64F6D7A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDD052AA5C100140006 = {
+                       fileRef = A64F6D7B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDE052AA5C100140006 = {
+                       fileRef = A64F6D7C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DDF052AA5C100140006 = {
+                       fileRef = A64F6D7D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE0052AA5C100140006 = {
+                       fileRef = A64F6D7E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE1052AA5C100140006 = {
+                       fileRef = A64F6D7F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE2052AA5C100140006 = {
+                       fileRef = A64F6D80052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE3052AA5C100140006 = {
+                       fileRef = A64F6D81052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE4052AA5C100140006 = {
+                       fileRef = A64F6D82052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE5052AA5C100140006 = {
+                       fileRef = A64F6D83052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE6052AA5C100140006 = {
+                       fileRef = A64F6D84052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE7052AA5C100140006 = {
+                       fileRef = A64F6D85052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE8052AA5C100140006 = {
+                       fileRef = A64F6D86052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DE9052AA5C100140006 = {
+                       fileRef = A64F6D87052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DEA052AA5C100140006 = {
+                       fileRef = A64F6D88052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DEB052AA5C100140006 = {
+                       fileRef = A64F6D89052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DEC052AA5C100140006 = {
+                       fileRef = A64F6D8A052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DED052AA5C100140006 = {
+                       fileRef = A64F6D8B052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DEE052AA5C100140006 = {
+                       fileRef = A64F6D8C052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DEF052AA5C100140006 = {
+                       fileRef = A64F6D8D052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF0052AA5C100140006 = {
+                       fileRef = A64F6D8E052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF1052AA5C100140006 = {
+                       fileRef = A64F6D8F052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF2052AA5C100140006 = {
+                       fileRef = A64F6D90052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF3052AA5C100140006 = {
+                       fileRef = A64F6D91052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF4052AA5C100140006 = {
+                       fileRef = A64F6D92052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF5052AA5C100140006 = {
+                       fileRef = A64F6D93052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF6052AA5C100140006 = {
+                       fileRef = A64F6D94052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF7052AA5C100140006 = {
+                       fileRef = A64F6D95052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF8052AA5C100140006 = {
+                       fileRef = A64F6D96052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DF9052AA5C100140006 = {
+                       fileRef = A64F6D97052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DFA052AA5C100140006 = {
+                       fileRef = A64F6D98052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6DFB052AA5C100140006 = {
+                       fileRef = A64F6D99052AA5C100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EC1052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_gradient.cpp;
+                       path = src/gtkmm/cellrenderer_gradient.cpp;
+                       refType = 4;
+               };
+               A64F6EC2052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_gradient.h;
+                       path = src/gtkmm/cellrenderer_gradient.h;
+                       refType = 4;
+               };
+               A64F6EC3052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_color.cpp;
+                       path = src/gtkmm/dialog_color.cpp;
+                       refType = 4;
+               };
+               A64F6EC4052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_color.h;
+                       path = src/gtkmm/dialog_color.h;
+                       refType = 4;
+               };
+               A64F6EC5052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_gradient.cpp;
+                       path = src/gtkmm/dialog_gradient.cpp;
+                       refType = 4;
+               };
+               A64F6EC6052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_gradient.h;
+                       path = src/gtkmm/dialog_gradient.h;
+                       refType = 4;
+               };
+               A64F6EC7052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_keyframe.cpp;
+                       path = src/gtkmm/dialog_keyframe.cpp;
+                       refType = 4;
+               };
+               A64F6EC8052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_keyframe.h;
+                       path = src/gtkmm/dialog_keyframe.h;
+                       refType = 4;
+               };
+               A64F6EC9052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_setup.cpp;
+                       path = src/gtkmm/dialog_setup.cpp;
+                       refType = 4;
+               };
+               A64F6ECA052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_setup.h;
+                       path = src/gtkmm/dialog_setup.h;
+                       refType = 4;
+               };
+               A64F6ECB052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = rotoscope_bline.cpp;
+                       path = src/gtkmm/rotoscope_bline.cpp;
+                       refType = 4;
+               };
+               A64F6ECC052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = rotoscope_bline.h;
+                       path = src/gtkmm/rotoscope_bline.h;
+                       refType = 4;
+               };
+               A64F6ECD052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = rotoscope_polygon.cpp;
+                       path = src/gtkmm/rotoscope_polygon.cpp;
+                       refType = 4;
+               };
+               A64F6ECE052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = rotoscope_polygon.h;
+                       path = src/gtkmm/rotoscope_polygon.h;
+                       refType = 4;
+               };
+               A64F6ECF052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_coloredit.cpp;
+                       path = src/gtkmm/widget_coloredit.cpp;
+                       refType = 4;
+               };
+               A64F6ED0052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_coloredit.h;
+                       path = src/gtkmm/widget_coloredit.h;
+                       refType = 4;
+               };
+               A64F6ED1052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_defaults.cpp;
+                       path = src/gtkmm/widget_defaults.cpp;
+                       refType = 4;
+               };
+               A64F6ED2052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_defaults.h;
+                       path = src/gtkmm/widget_defaults.h;
+                       refType = 4;
+               };
+               A64F6ED3052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_gradient.cpp;
+                       path = src/gtkmm/widget_gradient.cpp;
+                       refType = 4;
+               };
+               A64F6ED4052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_gradient.h;
+                       path = src/gtkmm/widget_gradient.h;
+                       refType = 4;
+               };
+               A64F6ED5052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_waypoint.cpp;
+                       path = src/gtkmm/widget_waypoint.cpp;
+                       refType = 4;
+               };
+               A64F6ED6052AA6B100140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_waypoint.h;
+                       path = src/gtkmm/widget_waypoint.h;
+                       refType = 4;
+               };
+               A64F6ED7052AA6B100140006 = {
+                       fileRef = A64F6EC1052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6ED8052AA6B100140006 = {
+                       fileRef = A64F6EC2052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6ED9052AA6B100140006 = {
+                       fileRef = A64F6EC3052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDA052AA6B100140006 = {
+                       fileRef = A64F6EC4052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDB052AA6B100140006 = {
+                       fileRef = A64F6EC5052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDC052AA6B100140006 = {
+                       fileRef = A64F6EC6052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDD052AA6B100140006 = {
+                       fileRef = A64F6EC7052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDE052AA6B100140006 = {
+                       fileRef = A64F6EC8052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EDF052AA6B100140006 = {
+                       fileRef = A64F6EC9052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE0052AA6B100140006 = {
+                       fileRef = A64F6ECA052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE1052AA6B100140006 = {
+                       fileRef = A64F6ECB052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE2052AA6B100140006 = {
+                       fileRef = A64F6ECC052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE3052AA6B100140006 = {
+                       fileRef = A64F6ECD052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE4052AA6B100140006 = {
+                       fileRef = A64F6ECE052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE5052AA6B100140006 = {
+                       fileRef = A64F6ECF052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE6052AA6B100140006 = {
+                       fileRef = A64F6ED0052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE7052AA6B100140006 = {
+                       fileRef = A64F6ED1052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE8052AA6B100140006 = {
+                       fileRef = A64F6ED2052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EE9052AA6B100140006 = {
+                       fileRef = A64F6ED3052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EEA052AA6B100140006 = {
+                       fileRef = A64F6ED4052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EEB052AA6B100140006 = {
+                       fileRef = A64F6ED5052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EEC052AA6B100140006 = {
+                       fileRef = A64F6ED6052AA6B100140006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A64F6EED052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = bline_icon.sif;
+                       path = images/bline_icon.sif;
+                       refType = 4;
+               };
+               A64F6EEE052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = duplicate_icon.sif;
+                       path = images/duplicate_icon.sif;
+                       refType = 4;
+               };
+               A64F6EEF052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gradient_icon.sif;
+                       path = images/gradient_icon.sif;
+                       refType = 4;
+               };
+               A64F6EF0052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframe_lock_icon.sif;
+                       path = images/keyframe_lock_icon.sif;
+                       refType = 4;
+               };
+               A64F6EF1052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layer_icon.sif;
+                       path = images/layer_icon.sif;
+                       refType = 4;
+               };
+               A64F6EF2052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = logo.sif;
+                       path = images/logo.sif;
+                       refType = 4;
+               };
+               A64F6EF3052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = polygon_icon.sif;
+                       path = images/polygon_icon.sif;
+                       refType = 4;
+               };
+               A64F6EF4052AA73200140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = valuenode_icon.sif;
+                       path = images/valuenode_icon.sif;
+                       refType = 4;
+               };
+               A64F6EF5052AA82D00140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = Makefile.inc;
+                       path = images/Makefile.inc;
+                       refType = 4;
+               };
+               A658A9C2047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasoptions.cpp;
+                       path = src/gtkmm/canvasoptions.cpp;
+                       refType = 4;
+               };
+               A658A9C3047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasoptions.h;
+                       path = src/gtkmm/canvasoptions.h;
+                       refType = 4;
+               };
+               A658A9C4047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvastreestore.cpp;
+                       path = src/gtkmm/canvastreestore.cpp;
+                       refType = 4;
+               };
+               A658A9C5047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvastreestore.h;
+                       path = src/gtkmm/canvastreestore.h;
+                       refType = 4;
+               };
+               A658A9C6047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_time.cpp;
+                       path = src/gtkmm/cellrenderer_time.cpp;
+                       refType = 4;
+               };
+               A658A9C7047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_time.h;
+                       path = src/gtkmm/cellrenderer_time.h;
+                       refType = 4;
+               };
+               A658A9C8047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_timetrack.cpp;
+                       path = src/gtkmm/cellrenderer_timetrack.cpp;
+                       refType = 4;
+               };
+               A658A9C9047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_timetrack.h;
+                       path = src/gtkmm/cellrenderer_timetrack.h;
+                       refType = 4;
+               };
+               A658A9CA047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_value.cpp;
+                       path = src/gtkmm/cellrenderer_value.cpp;
+                       refType = 4;
+               };
+               A658A9CB047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cellrenderer_value.h;
+                       path = src/gtkmm/cellrenderer_value.h;
+                       refType = 4;
+               };
+               A658A9CC047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = childrentreestore.cpp;
+                       path = src/gtkmm/childrentreestore.cpp;
+                       refType = 4;
+               };
+               A658A9CD047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = childrentreestore.h;
+                       path = src/gtkmm/childrentreestore.h;
+                       refType = 4;
+               };
+               A658A9CE047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_waypoint.cpp;
+                       path = src/gtkmm/dialog_waypoint.cpp;
+                       refType = 4;
+               };
+               A658A9CF047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = dialog_waypoint.h;
+                       path = src/gtkmm/dialog_waypoint.h;
+                       refType = 4;
+               };
+               A658A9D0047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = historytreestore.cpp;
+                       path = src/gtkmm/historytreestore.cpp;
+                       refType = 4;
+               };
+               A658A9D1047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = historytreestore.h;
+                       path = src/gtkmm/historytreestore.h;
+                       refType = 4;
+               };
+               A658A9D4047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframetree.cpp;
+                       path = src/gtkmm/keyframetree.cpp;
+                       refType = 4;
+               };
+               A658A9D5047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframetree.h;
+                       path = src/gtkmm/keyframetree.h;
+                       refType = 4;
+               };
+               A658A9D6047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframetreestore.cpp;
+                       path = src/gtkmm/keyframetreestore.cpp;
+                       refType = 4;
+               };
+               A658A9D7047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = keyframetreestore.h;
+                       path = src/gtkmm/keyframetreestore.h;
+                       refType = 4;
+               };
+               A658A9D8047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layertree.cpp;
+                       path = src/gtkmm/layertree.cpp;
+                       refType = 4;
+               };
+               A658A9D9047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layertree.h;
+                       path = src/gtkmm/layertree.h;
+                       refType = 4;
+               };
+               A658A9DA047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layertreestore.cpp;
+                       path = src/gtkmm/layertreestore.cpp;
+                       refType = 4;
+               };
+               A658A9DB047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = layertreestore.h;
+                       path = src/gtkmm/layertreestore.h;
+                       refType = 4;
+               };
+               A658A9DC047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = render.cpp;
+                       path = src/gtkmm/render.cpp;
+                       refType = 4;
+               };
+               A658A9DD047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = render.h;
+                       path = src/gtkmm/render.h;
+                       refType = 4;
+               };
+               A658A9DE047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_canvaschooser.cpp;
+                       path = src/gtkmm/widget_canvaschooser.cpp;
+                       refType = 4;
+               };
+               A658A9DF047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_canvaschooser.h;
+                       path = src/gtkmm/widget_canvaschooser.h;
+                       refType = 4;
+               };
+               A658A9E0047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_color.cpp;
+                       path = src/gtkmm/widget_color.cpp;
+                       refType = 4;
+               };
+               A658A9E1047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_color.h;
+                       path = src/gtkmm/widget_color.h;
+                       refType = 4;
+               };
+               A658A9E2047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_enum.cpp;
+                       path = src/gtkmm/widget_enum.cpp;
+                       refType = 4;
+               };
+               A658A9E3047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_enum.h;
+                       path = src/gtkmm/widget_enum.h;
+                       refType = 4;
+               };
+               A658A9E4047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_filename.cpp;
+                       path = src/gtkmm/widget_filename.cpp;
+                       refType = 4;
+               };
+               A658A9E5047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_filename.h;
+                       path = src/gtkmm/widget_filename.h;
+                       refType = 4;
+               };
+               A658A9E6047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_time.cpp;
+                       path = src/gtkmm/widget_time.cpp;
+                       refType = 4;
+               };
+               A658A9E7047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_time.h;
+                       path = src/gtkmm/widget_time.h;
+                       refType = 4;
+               };
+               A658A9E8047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_value.cpp;
+                       path = src/gtkmm/widget_value.cpp;
+                       refType = 4;
+               };
+               A658A9E9047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_value.h;
+                       path = src/gtkmm/widget_value.h;
+                       refType = 4;
+               };
+               A658A9EA047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_vector.cpp;
+                       path = src/gtkmm/widget_vector.cpp;
+                       refType = 4;
+               };
+               A658A9EB047AC2E400A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = widget_vector.h;
+                       path = src/gtkmm/widget_vector.h;
+                       refType = 4;
+               };
+               A658A9EC047AC2E400A80006 = {
+                       fileRef = A658A9C2047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9ED047AC2E400A80006 = {
+                       fileRef = A658A9C3047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9EE047AC2E400A80006 = {
+                       fileRef = A658A9C4047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9EF047AC2E400A80006 = {
+                       fileRef = A658A9C5047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F0047AC2E400A80006 = {
+                       fileRef = A658A9C6047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F1047AC2E400A80006 = {
+                       fileRef = A658A9C7047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F2047AC2E400A80006 = {
+                       fileRef = A658A9C8047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F3047AC2E400A80006 = {
+                       fileRef = A658A9C9047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F4047AC2E400A80006 = {
+                       fileRef = A658A9CA047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F5047AC2E400A80006 = {
+                       fileRef = A658A9CB047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F6047AC2E400A80006 = {
+                       fileRef = A658A9CC047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F7047AC2E400A80006 = {
+                       fileRef = A658A9CD047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F8047AC2E400A80006 = {
+                       fileRef = A658A9CE047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9F9047AC2E400A80006 = {
+                       fileRef = A658A9CF047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9FA047AC2E400A80006 = {
+                       fileRef = A658A9D0047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9FB047AC2E400A80006 = {
+                       fileRef = A658A9D1047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9FE047AC2E400A80006 = {
+                       fileRef = A658A9D4047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658A9FF047AC2E400A80006 = {
+                       fileRef = A658A9D5047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA00047AC2E400A80006 = {
+                       fileRef = A658A9D6047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA01047AC2E400A80006 = {
+                       fileRef = A658A9D7047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA02047AC2E400A80006 = {
+                       fileRef = A658A9D8047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA03047AC2E400A80006 = {
+                       fileRef = A658A9D9047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA04047AC2E400A80006 = {
+                       fileRef = A658A9DA047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA05047AC2E400A80006 = {
+                       fileRef = A658A9DB047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA06047AC2E400A80006 = {
+                       fileRef = A658A9DC047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA07047AC2E400A80006 = {
+                       fileRef = A658A9DD047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA08047AC2E400A80006 = {
+                       fileRef = A658A9DE047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA09047AC2E400A80006 = {
+                       fileRef = A658A9DF047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0A047AC2E400A80006 = {
+                       fileRef = A658A9E0047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0B047AC2E400A80006 = {
+                       fileRef = A658A9E1047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0C047AC2E400A80006 = {
+                       fileRef = A658A9E2047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0D047AC2E400A80006 = {
+                       fileRef = A658A9E3047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0E047AC2E400A80006 = {
+                       fileRef = A658A9E4047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA0F047AC2E400A80006 = {
+                       fileRef = A658A9E5047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA10047AC2E400A80006 = {
+                       fileRef = A658A9E6047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA11047AC2E400A80006 = {
+                       fileRef = A658A9E7047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA12047AC2E400A80006 = {
+                       fileRef = A658A9E8047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA13047AC2E400A80006 = {
+                       fileRef = A658A9E9047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA14047AC2E400A80006 = {
+                       fileRef = A658A9EA047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA15047AC2E400A80006 = {
+                       fileRef = A658A9EB047AC2E400A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A658AA16047AC30100A80006 = {
+                       children = (
+                               A658A9DE047AC2E400A80006,
+                               A658A9DF047AC2E400A80006,
+                               A658A9E0047AC2E400A80006,
+                               A658A9E1047AC2E400A80006,
+                               A658A9E2047AC2E400A80006,
+                               A658A9E3047AC2E400A80006,
+                               A658A9E4047AC2E400A80006,
+                               A658A9E5047AC2E400A80006,
+                               A658A9E6047AC2E400A80006,
+                               A658A9E7047AC2E400A80006,
+                               A658A9E8047AC2E400A80006,
+                               A658A9E9047AC2E400A80006,
+                               A658A9EA047AC2E400A80006,
+                               A658A9EB047AC2E400A80006,
+                               A64F6ECF052AA6B100140006,
+                               A64F6ED0052AA6B100140006,
+                               A64F6ED1052AA6B100140006,
+                               A64F6ED2052AA6B100140006,
+                               A64F6ED3052AA6B100140006,
+                               A64F6ED4052AA6B100140006,
+                               A64F6ED5052AA6B100140006,
+                               A64F6ED6052AA6B100140006,
+                       );
+                       isa = PBXGroup;
+                       name = Widgets;
+                       refType = 4;
+               };
+               A658AA17047AC30F00A80006 = {
+                       children = (
+                               A64F6EC1052AA6B100140006,
+                               A64F6EC2052AA6B100140006,
+                               A658A9C6047AC2E400A80006,
+                               A658A9C7047AC2E400A80006,
+                               A658A9C8047AC2E400A80006,
+                               A658A9C9047AC2E400A80006,
+                               A658A9CA047AC2E400A80006,
+                               A658A9CB047AC2E400A80006,
+                       );
+                       isa = PBXGroup;
+                       name = CellRenderers;
+                       refType = 4;
+               };
+               A658AA18047AC32100A80006 = {
+                       children = (
+                               F581E12F03B23D710101DBD7,
+                               F581E13003B23D710101DBD7,
+                               A658A9CE047AC2E400A80006,
+                               A658A9CF047AC2E400A80006,
+                               A658A9DC047AC2E400A80006,
+                               A658A9DD047AC2E400A80006,
+                               A658A9C2047AC2E400A80006,
+                               A658A9C3047AC2E400A80006,
+                               A64F6EC3052AA6B100140006,
+                               A64F6EC4052AA6B100140006,
+                               A64F6EC5052AA6B100140006,
+                               A64F6EC6052AA6B100140006,
+                               A64F6EC7052AA6B100140006,
+                               A64F6EC8052AA6B100140006,
+                               A64F6EC9052AA6B100140006,
+                               A64F6ECA052AA6B100140006,
+                       );
+                       isa = PBXGroup;
+                       name = Dialogs;
+                       refType = 4;
+               };
+               A6714E0A0413F36C00F656BD = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = value_desc.h;
+                       path = src/sinfgapp/value_desc.h;
+                       refType = 4;
+               };
+               A6714E110413F36C00F656BD = {
+                       fileRef = A6714E0A0413F36C00F656BD;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               A6714E140413F39900F656BD = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = zoomdial.cpp;
+                       path = src/gtkmm/zoomdial.cpp;
+                       refType = 4;
+               };
+               A6714E150413F39900F656BD = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = zoomdial.h;
+                       path = src/gtkmm/zoomdial.h;
+                       refType = 4;
+               };
+               A6714E180413F39900F656BD = {
+                       fileRef = A6714E140413F39900F656BD;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6714E190413F39900F656BD = {
+                       fileRef = A6714E150413F39900F656BD;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A69BDDC3047AF153005B6F89 = {
+                       isa = PBXFileReference;
+                       name = libXinerama.a;
+                       path = /usr/X11R6/lib/libXinerama.a;
+                       refType = 0;
+               };
+               A69BDDC4047AF153005B6F89 = {
+                       fileRef = A69BDDC3047AF153005B6F89;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A69BDDC5047AF21C005B6F89 = {
+                       isa = PBXFileReference;
+                       name = libXext.6.dylib;
+                       path = /usr/X11R6/lib/libXext.6.dylib;
+                       refType = 0;
+               };
+               A69BDDC6047AF21C005B6F89 = {
+                       fileRef = A69BDDC5047AF21C005B6F89;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A69BDDC7047AF260005B6F89 = {
+                       isa = PBXFileReference;
+                       name = libX11.6.dylib;
+                       path = /usr/X11R6/lib/libX11.6.dylib;
+                       refType = 0;
+               };
+               A69BDDC8047AF260005B6F89 = {
+                       fileRef = A69BDDC7047AF260005B6F89;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6B8624803E8A00100A80006 = {
+                       fileRef = F581E12F03B23D710101DBD7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6B8624903E8A00100A80006 = {
+                       fileRef = F581E13003B23D710101DBD7;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6B8624A03E8A07000A80006 = {
+                       fileRef = F5F2706303C94C7C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6B8624B03E8A07000A80006 = {
+                       fileRef = F5F2706203C94C7C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6BEE1CF058004B500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = normal_icon.sif;
+                       path = images/normal_icon.sif;
+                       refType = 4;
+               };
+               A6BEE1D0058004B500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = sif_icon.sif;
+                       path = images/sif_icon.sif;
+                       refType = 4;
+               };
+               A6BEE1D1058004B500140006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = sinfg_icon.sif;
+                       path = images/sinfg_icon.sif;
+                       refType = 4;
+               };
+               A6C8247303CC275900A80006 = {
+                       isa = PBXFileReference;
+                       name = "libatkmm-1.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libatkmm-1.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247403CC275900A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgdkmm-2.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libgdkmm-2.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247503CC275900A80006 = {
+                       isa = PBXFileReference;
+                       name = "libglibmm-2.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libglibmm-2.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247603CC275900A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgtkmm_generate_extra_defs-2.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libgtkmm_generate_extra_defs-2.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247703CC275900A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgtkmm-2.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libgtkmm-2.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247803CC275A00A80006 = {
+                       isa = PBXFileReference;
+                       name = "libpangomm-1.0.1.5.1.dylib";
+                       path = "/usr/local/lib/libpangomm-1.0.1.5.1.dylib";
+                       refType = 0;
+               };
+               A6C8247903CC275A00A80006 = {
+                       fileRef = A6C8247303CC275900A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247A03CC275A00A80006 = {
+                       fileRef = A6C8247403CC275900A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247B03CC275A00A80006 = {
+                       fileRef = A6C8247503CC275900A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247C03CC275A00A80006 = {
+                       fileRef = A6C8247603CC275900A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247D03CC275A00A80006 = {
+                       fileRef = A6C8247703CC275900A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247E03CC275A00A80006 = {
+                       fileRef = A6C8247803CC275A00A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6C8247F03CC276900A80006 = {
+                       children = (
+                               A6C8247303CC275900A80006,
+                               A6C8247403CC275900A80006,
+                               A6C8247503CC275900A80006,
+                               A6C8247603CC275900A80006,
+                               A6C8247703CC275900A80006,
+                               A6C8247803CC275A00A80006,
+                       );
+                       isa = PBXGroup;
+                       name = "Gtk-- 2.0";
+                       path = "";
+                       refType = 4;
+               };
+               A6D3457C03CF516D00A80006 = {
+                       isa = PBXFileReference;
+                       name = "libpangoft2-1.0.0.0.5.dylib";
+                       path = "/usr/local/lib/libpangoft2-1.0.0.0.5.dylib";
+                       refType = 0;
+               };
+               A6D3457D03CF516D00A80006 = {
+                       isa = PBXFileReference;
+                       name = "libpangoxft-1.0.dylib";
+                       path = "/usr/local/lib/libpangoxft-1.0.dylib";
+                       refType = 0;
+               };
+               A6D3457E03CF516D00A80006 = {
+                       fileRef = A6D3457C03CF516D00A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6D3457F03CF516D00A80006 = {
+                       fileRef = A6D3457D03CF516D00A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               A6D347FE03CF574000A80006 = {
+                       children = (
+                               A6D34AE103CF7C2100A80006,
+                               A6D34AE203CF7C2100A80006,
+                               A6D34AE303CF7C2100A80006,
+                               A6D34AE503CF7C2100A80006,
+                       );
+                       isa = PBXGroup;
+                       name = Icons;
+                       refType = 4;
+               };
+               A6D34AE103CF7C2100A80006 = {
+                       isa = PBXFileReference;
+                       name = about_icon.tif;
+                       path = /Users/darco/src/voria/studio/images/about_icon.tif;
+                       refType = 0;
+               };
+               A6D34AE203CF7C2100A80006 = {
+                       isa = PBXFileReference;
+                       name = canvas_icon.tif;
+                       path = /Users/darco/src/voria/studio/images/canvas_icon.tif;
+                       refType = 0;
+               };
+               A6D34AE303CF7C2100A80006 = {
+                       isa = PBXFileReference;
+                       name = color_icon.tif;
+                       path = /Users/darco/src/voria/studio/images/color_icon.tif;
+                       refType = 0;
+               };
+               A6D34AE503CF7C2100A80006 = {
+                       isa = PBXFileReference;
+                       name = real_icon.tif;
+                       path = /Users/darco/src/voria/studio/images/real_icon.tif;
+                       refType = 0;
+               };
+//A60
+//A61
+//A62
+//A63
+//A64
+//F50
+//F51
+//F52
+//F53
+//F54
+               F50C84CA0377988001A80006 = {
+                       children = (
+                               F5F2703003C947C701BABFEF,
+                               F56E5E4403BCF0E801A80006,
+                               F50C84D00377995201A80006,
+                               F50C84F303779A0301A80006,
+                               F50C84F403779A1701A80006,
+                       );
+                       isa = PBXGroup;
+                       refType = 4;
+               };
+               F50C84CC0377988001A80006 = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               MACOSX_DEPLOYMENT_TARGET = 10.2;
+                               OPTIMIZATION_CFLAGS = "-O0 -g";
+                               OTHER_CXXFLAGS = "\U0001-DHAVE_CFLAGS -D_DEBUG";
+                               USE_GCC3_PFE_SUPPORT = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               F50C84CD0377988001A80006 = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               MACOSX_DEPLOYMENT_TARGET = 10.2;
+                               OPTIMIZATION_CFLAGS = "-O1 -ffast-math";
+                               OTHER_CXXFLAGS = "\U0001-DHAVE_CFLAGS -DNDEBUG";
+                               USE_GCC3_PFE_SUPPORT = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+               F50C84CE0377988001A80006 = {
+                       buildStyles = (
+                               F50C84CC0377988001A80006,
+                               F50C84CD0377988001A80006,
+                       );
+                       hasScannedForEncodings = 1;
+                       isa = PBXProject;
+                       mainGroup = F50C84CA0377988001A80006;
+                       projectDirPath = "";
+                       targets = (
+                               F50C84F903779A4701A80006,
+                               F5F2703603C947FC01BABFEF,
+                               F56E5BBF03BCE6B101A80006,
+                       );
+               };
+               F50C84D00377995201A80006 = {
+                       children = (
+                               F5F2705E03C94BE301BABFEF,
+                               F50C84E0037799AE01A80006,
+                       );
+                       isa = PBXGroup;
+                       name = "Sinfg Studio Sources";
+                       refType = 4;
+               };
+               F50C84E0037799AE01A80006 = {
+                       children = (
+                               A64EF696059F5F5100140006,
+                               A64EF695059F5F2000140006,
+                               A64EF694059F5EE900140006,
+                               A64EF693059F5DAF00140006,
+                               A658AA17047AC30F00A80006,
+                               A658AA18047AC32100A80006,
+                               A658AA16047AC30100A80006,
+                               F50C84E3037799F301A80006,
+                               F50C84E4037799F301A80006,
+                               F50C84EB037799F301A80006,
+                               F50C84EC037799F301A80006,
+                               F50C84F1037799F301A80006,
+                               F50C84F2037799F301A80006,
+                               F5213F2F0384C1D501A80006,
+                               F5213F300384C1D501A80006,
+                               F5213F310384C1D501A80006,
+                               F5213F320384C1D501A80006,
+                               F5429FA203A911B301A80006,
+                               F5429FA303A911B301A80006,
+                               F5429FA403A911B301A80006,
+                               F5429FA503A911B301A80006,
+                               F5F2705F03C94C7C01BABFEF,
+                               F5F2706003C94C7C01BABFEF,
+                               F5F2706103C94C7C01BABFEF,
+                               F5F2706203C94C7C01BABFEF,
+                               F5F2706303C94C7C01BABFEF,
+                               A6714E140413F39900F656BD,
+                               A6714E150413F39900F656BD,
+                               A63F3B4A054DAC6A00140006,
+                               A63F3B4B054DAC6A00140006,
+                               A64DD830057FEEF700140006,
+                       );
+                       isa = PBXGroup;
+                       name = "Gtk--";
+                       refType = 4;
+               };
+               F50C84E3037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = app.cpp;
+                       path = src/gtkmm/app.cpp;
+                       refType = 4;
+               };
+               F50C84E4037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = app.h;
+                       path = src/gtkmm/app.h;
+                       refType = 4;
+               };
+               F50C84EB037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = toolbox.cpp;
+                       path = src/gtkmm/toolbox.cpp;
+                       refType = 4;
+               };
+               F50C84EC037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = toolbox.h;
+                       path = src/gtkmm/toolbox.h;
+                       refType = 4;
+               };
+               F50C84F1037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = workarea.cpp;
+                       path = src/gtkmm/workarea.cpp;
+                       refType = 4;
+               };
+               F50C84F2037799F301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = workarea.h;
+                       path = src/gtkmm/workarea.h;
+                       refType = 4;
+               };
+               F50C84F303779A0301A80006 = {
+                       children = (
+                               F50C84FC03779A8301A80006,
+                               F50C84FD03779A8301A80006,
+                               F50C858E03779DA401A80006,
+                               F50C85A20377A0CA01A80006,
+                               F50C85A30377A0CA01A80006,
+                               F50C859A0377A0CA01A80006,
+                               A6C8247F03CC276900A80006,
+                               F50C85B50377A0E601A80006,
+                               A69BDDC3047AF153005B6F89,
+                               A69BDDC5047AF21C005B6F89,
+                               A69BDDC7047AF260005B6F89,
+                       );
+                       isa = PBXGroup;
+                       name = "Libraries and Frameworks";
+                       refType = 4;
+               };
+               F50C84F403779A1701A80006 = {
+                       children = (
+                               F50C84FA03779A4701A80006,
+                               F5F2703703C947FC01BABFEF,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       path = "";
+                       refType = 4;
+               };
+               F50C84F503779A4701A80006 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F50C857D03779AAF01A80006,
+                               F50C858403779AB201A80006,
+                               F5213F340384C1D501A80006,
+                               F5213F360384C1D501A80006,
+                               F5429FA703A911B301A80006,
+                               F5429FA903A911B301A80006,
+                               F5F2706503C94C7C01BABFEF,
+                               F5827D6103CBAB940112B647,
+                               A6B8624903E8A00100A80006,
+                               A6B8624A03E8A07000A80006,
+                               A6714E190413F39900F656BD,
+                               A658A9ED047AC2E400A80006,
+                               A658A9EF047AC2E400A80006,
+                               A658A9F1047AC2E400A80006,
+                               A658A9F3047AC2E400A80006,
+                               A658A9F5047AC2E400A80006,
+                               A658A9F7047AC2E400A80006,
+                               A658A9F9047AC2E400A80006,
+                               A658A9FB047AC2E400A80006,
+                               A658A9FF047AC2E400A80006,
+                               A658AA01047AC2E400A80006,
+                               A658AA03047AC2E400A80006,
+                               A658AA05047AC2E400A80006,
+                               A658AA07047AC2E400A80006,
+                               A658AA09047AC2E400A80006,
+                               A658AA0B047AC2E400A80006,
+                               A658AA0D047AC2E400A80006,
+                               A658AA0F047AC2E400A80006,
+                               A658AA11047AC2E400A80006,
+                               A658AA13047AC2E400A80006,
+                               A658AA15047AC2E400A80006,
+                               A630F0B9047D9BEB0006EC77,
+                               A64F6ED8052AA6B100140006,
+                               A64F6EDA052AA6B100140006,
+                               A64F6EDC052AA6B100140006,
+                               A64F6EDE052AA6B100140006,
+                               A64F6EE0052AA6B100140006,
+                               A64F6EE2052AA6B100140006,
+                               A64F6EE4052AA6B100140006,
+                               A64F6EE6052AA6B100140006,
+                               A64F6EE8052AA6B100140006,
+                               A64F6EEA052AA6B100140006,
+                               A64F6EEC052AA6B100140006,
+                               A63EEE1B05446F1500140006,
+                               A63EEE1D05446F1500140006,
+                               A63EEE1F05446F1500140006,
+                               A63F3B4D054DAC6A00140006,
+                               A64DD836057FEEF700140006,
+                               A64DD838057FEEF700140006,
+                               A64DD839057FEEF700140006,
+                               A64DD83A057FEEF700140006,
+                               A64DD83B057FEEF700140006,
+                               A64DD83C057FEEF700140006,
+                               A64DD83D057FEEF700140006,
+                               A64DD83E057FEEF700140006,
+                               A64DD840057FEEF700140006,
+                               A64DD842057FEEF700140006,
+                               A64EF692059F5D9E00140006,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F50C84F603779A4701A80006 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F50C857C03779AAE01A80006,
+                               F50C858503779AB301A80006,
+                               F5213F330384C1D501A80006,
+                               F5213F350384C1D501A80006,
+                               F5429FA603A911B301A80006,
+                               F5429FA803A911B301A80006,
+                               F5F2706403C94C7C01BABFEF,
+                               F5F2706603C94C7C01BABFEF,
+                               F5827D6203CBAB950112B647,
+                               A6B8624803E8A00100A80006,
+                               A6B8624B03E8A07000A80006,
+                               A6714E180413F39900F656BD,
+                               A658A9EC047AC2E400A80006,
+                               A658A9EE047AC2E400A80006,
+                               A658A9F0047AC2E400A80006,
+                               A658A9F2047AC2E400A80006,
+                               A658A9F4047AC2E400A80006,
+                               A658A9F6047AC2E400A80006,
+                               A658A9F8047AC2E400A80006,
+                               A658A9FA047AC2E400A80006,
+                               A658A9FE047AC2E400A80006,
+                               A658AA00047AC2E400A80006,
+                               A658AA02047AC2E400A80006,
+                               A658AA04047AC2E400A80006,
+                               A658AA06047AC2E400A80006,
+                               A658AA08047AC2E400A80006,
+                               A658AA0A047AC2E400A80006,
+                               A658AA0C047AC2E400A80006,
+                               A658AA0E047AC2E400A80006,
+                               A658AA10047AC2E400A80006,
+                               A658AA12047AC2E400A80006,
+                               A658AA14047AC2E400A80006,
+                               A630F0B8047D9BEB0006EC77,
+                               A64F6ED7052AA6B100140006,
+                               A64F6ED9052AA6B100140006,
+                               A64F6EDB052AA6B100140006,
+                               A64F6EDD052AA6B100140006,
+                               A64F6EDF052AA6B100140006,
+                               A64F6EE1052AA6B100140006,
+                               A64F6EE3052AA6B100140006,
+                               A64F6EE5052AA6B100140006,
+                               A64F6EE7052AA6B100140006,
+                               A64F6EE9052AA6B100140006,
+                               A64F6EEB052AA6B100140006,
+                               A63EEE1C05446F1500140006,
+                               A63EEE1E05446F1500140006,
+                               A63F3B4C054DAC6A00140006,
+                               A64DD835057FEEF700140006,
+                               A64DD837057FEEF700140006,
+                               A64DD83F057FEEF700140006,
+                               A64DD841057FEEF700140006,
+                               A64EF691059F5D9E00140006,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F50C84F703779A4701A80006 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F50C856903779A8301A80006,
+                               F50C856A03779A8301A80006,
+                               F50C859003779DA401A80006,
+                               F50C859703779DFB01A80006,
+                               F50C85A70377A0CA01A80006,
+                               F50C85A80377A0CA01A80006,
+                               F50C85A90377A0CA01A80006,
+                               F50C85AA0377A0CA01A80006,
+                               F50C85AB0377A0CA01A80006,
+                               F50C85AC0377A0CA01A80006,
+                               F50C85AD0377A0CA01A80006,
+                               F50C85AE0377A0CA01A80006,
+                               F50C85AF0377A0CA01A80006,
+                               F50C85B00377A0CA01A80006,
+                               F50C85B10377A0CA01A80006,
+                               F50C85B20377A0CA01A80006,
+                               F50C85B40377A0CA01A80006,
+                               F5F2706903C94C8E01BABFEF,
+                               A6C8247903CC275A00A80006,
+                               A6C8247A03CC275A00A80006,
+                               A6C8247B03CC275A00A80006,
+                               A6C8247C03CC275A00A80006,
+                               A6C8247D03CC275A00A80006,
+                               A6C8247E03CC275A00A80006,
+                               A6D3457E03CF516D00A80006,
+                               A6D3457F03CF516D00A80006,
+                               A69BDDC4047AF153005B6F89,
+                               A69BDDC6047AF21C005B6F89,
+                               A69BDDC8047AF260005B6F89,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F50C84F803779A4701A80006 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F50C84F903779A4701A80006 = {
+                       buildPhases = (
+                               F50C84F503779A4701A80006,
+                               F50C84F603779A4701A80006,
+                               F50C84F703779A4701A80006,
+                               F50C84F803779A4701A80006,
+                       );
+                       buildSettings = {
+                               HEADER_SEARCH_PATHS = "src /usr/local/include/atk-1.0 /usr/X11R6/include /usr/local/include/pango-1.0 /usr/local/lib/gtk-2.0/include /usr/local/lib/glib-2.0/include /usr/local/include/glib-2.0 /usr/local/include/gtk-2.0 /usr/local/include/sigc++-1.2 /usr/local/lib/sigc++-1.2/include /usr/local/lib/gtkmm-2.0/include /usr/local/include/gtkmm-2.0";
+                               LIBRARY_SEARCH_PATHS = "/usr/local/lib /usr/X11R6/lib";
+                               OTHER_CFLAGS = "\\\"'-DIMAGE_DIR=\\\"/Users/darco/src/voria/studio/images/\\\"'\\\"";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = sinfgstudio;
+                               REZ_EXECUTABLE = YES;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                       };
+                       dependencies = (
+                               F5F2706A03C94D2101BABFEF,
+                       );
+                       isa = PBXToolTarget;
+                       name = "Sinfg Studio (Gtk--)";
+                       productInstallPath = /usr/local/bin;
+                       productName = "Sinfg Studio GTKMM-2.0";
+                       productReference = F50C84FA03779A4701A80006;
+               };
+               F50C84FA03779A4701A80006 = {
+                       isa = PBXExecutableFileReference;
+                       path = sinfgstudio;
+                       refType = 3;
+               };
+               F50C84FC03779A8301A80006 = {
+                       isa = PBXFrameworkReference;
+                       name = ETL.framework;
+                       path = /Library/Frameworks/ETL.framework;
+                       refType = 0;
+               };
+               F50C84FD03779A8301A80006 = {
+                       isa = PBXFrameworkReference;
+                       name = sinfg.framework;
+                       path = /Library/Frameworks/sinfg.framework;
+                       refType = 0;
+               };
+               F50C856903779A8301A80006 = {
+                       fileRef = F50C84FC03779A8301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C856A03779A8301A80006 = {
+                       fileRef = F50C84FD03779A8301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C857C03779AAE01A80006 = {
+                       fileRef = F50C84E3037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C857D03779AAF01A80006 = {
+                       fileRef = F50C84E4037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C858403779AB201A80006 = {
+                       fileRef = F50C84EC037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C858503779AB301A80006 = {
+                       fileRef = F50C84EB037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C858E03779DA401A80006 = {
+                       isa = PBXFileReference;
+                       name = "libsigc-1.2.dylib";
+                       path = "/usr/local/lib/libsigc-1.2.5.0.4.dylib";
+                       refType = 0;
+               };
+               F50C859003779DA401A80006 = {
+                       fileRef = F50C858E03779DA401A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C859303779DFB01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libglib-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libglib-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C859703779DFB01A80006 = {
+                       fileRef = F50C859303779DFB01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85990377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libatk-1.0.0.200.0.dylib";
+                       path = "/usr/local/lib/libatk-1.0.0.200.0.dylib";
+                       refType = 0;
+               };
+               F50C859A0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = libfreetype.6.dylib;
+                       path = /usr/X11R6/lib/libfreetype.6.2.dylib;
+                       refType = 0;
+               };
+               F50C859B0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgdk_pixbuf_xlib-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgdk_pixbuf_xlib-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C859C0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgdk_pixbuf-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgdk_pixbuf-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C859D0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgdk-x11-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgdk-x11-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C859E0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libglib-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libglib-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C859F0377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgmodule-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgmodule-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C85A00377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgobject-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgobject-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C85A10377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libgtk-x11-2.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libgtk-x11-2.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C85A20377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = libiconv.2.1.0.dylib;
+                       path = /usr/local/lib/libiconv.2.1.0.dylib;
+                       refType = 0;
+               };
+               F50C85A30377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = libintl.dylib;
+                       path = /usr/local/lib/libintl.2.2.0.dylib;
+                       refType = 0;
+               };
+               F50C85A40377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libpango-1.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libpango-1.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C85A60377A0CA01A80006 = {
+                       isa = PBXFileReference;
+                       name = "libpangox-1.0.0.200.1.dylib";
+                       path = "/usr/local/lib/libpangox-1.0.0.200.1.dylib";
+                       refType = 0;
+               };
+               F50C85A70377A0CA01A80006 = {
+                       fileRef = F50C85990377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85A80377A0CA01A80006 = {
+                       fileRef = F50C859A0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85A90377A0CA01A80006 = {
+                       fileRef = F50C859B0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AA0377A0CA01A80006 = {
+                       fileRef = F50C859C0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AB0377A0CA01A80006 = {
+                       fileRef = F50C859D0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AC0377A0CA01A80006 = {
+                       fileRef = F50C859E0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AD0377A0CA01A80006 = {
+                       fileRef = F50C859F0377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AE0377A0CA01A80006 = {
+                       fileRef = F50C85A00377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85AF0377A0CA01A80006 = {
+                       fileRef = F50C85A10377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85B00377A0CA01A80006 = {
+                       fileRef = F50C85A20377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85B10377A0CA01A80006 = {
+                       fileRef = F50C85A30377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85B20377A0CA01A80006 = {
+                       fileRef = F50C85A40377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85B40377A0CA01A80006 = {
+                       fileRef = F50C85A60377A0CA01A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F50C85B50377A0E601A80006 = {
+                       children = (
+                               F50C859303779DFB01A80006,
+                               F50C85990377A0CA01A80006,
+                               F50C859B0377A0CA01A80006,
+                               F50C859C0377A0CA01A80006,
+                               F50C859D0377A0CA01A80006,
+                               F50C859E0377A0CA01A80006,
+                               F50C859F0377A0CA01A80006,
+                               F50C85A00377A0CA01A80006,
+                               F50C85A10377A0CA01A80006,
+                               F50C85A40377A0CA01A80006,
+                               F50C85A60377A0CA01A80006,
+                               A6D3457C03CF516D00A80006,
+                               A6D3457D03CF516D00A80006,
+                       );
+                       isa = PBXGroup;
+                       name = "Gtk+ 2.0";
+                       path = "";
+                       refType = 4;
+               };
+               F5213F2F0384C1D501A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = compview.cpp;
+                       path = src/gtkmm/compview.cpp;
+                       refType = 4;
+               };
+               F5213F300384C1D501A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = compview.h;
+                       path = src/gtkmm/compview.h;
+                       refType = 4;
+               };
+               F5213F310384C1D501A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = instance.cpp;
+                       path = src/gtkmm/instance.cpp;
+                       refType = 4;
+               };
+               F5213F320384C1D501A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = instance.h;
+                       path = src/gtkmm/instance.h;
+                       refType = 4;
+               };
+               F5213F330384C1D501A80006 = {
+                       fileRef = F5213F2F0384C1D501A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5213F340384C1D501A80006 = {
+                       fileRef = F5213F300384C1D501A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5213F350384C1D501A80006 = {
+                       fileRef = F5213F310384C1D501A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5213F360384C1D501A80006 = {
+                       fileRef = F5213F320384C1D501A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5429FA203A911B301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = about.cpp;
+                       path = src/gtkmm/about.cpp;
+                       refType = 4;
+               };
+               F5429FA303A911B301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = about.h;
+                       path = src/gtkmm/about.h;
+                       refType = 4;
+               };
+               F5429FA403A911B301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasview.cpp;
+                       path = src/gtkmm/canvasview.cpp;
+                       refType = 4;
+               };
+               F5429FA503A911B301A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasview.h;
+                       path = src/gtkmm/canvasview.h;
+                       refType = 4;
+               };
+               F5429FA603A911B301A80006 = {
+                       fileRef = F5429FA203A911B301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5429FA703A911B301A80006 = {
+                       fileRef = F5429FA303A911B301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5429FA803A911B301A80006 = {
+                       fileRef = F5429FA403A911B301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5429FA903A911B301A80006 = {
+                       fileRef = F5429FA503A911B301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F56E5BBF03BCE6B101A80006 = {
+                       buildArgumentsString = "-f Makefile.inc $ACTION";
+                       buildPhases = (
+                       );
+                       buildSettings = {
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PRODUCT_NAME = Icons;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                       };
+                       buildToolPath = /usr/bin/gnumake;
+                       buildWorkingDirectory = /Users/darco/src/voria/studio/images/;
+                       dependencies = (
+                       );
+                       isa = PBXLegacyTarget;
+                       name = Icons;
+                       passBuildSettingsInEnvironment = 1;
+                       productName = Icons;
+                       settingsToExpand = 6;
+                       settingsToPassInEnvironment = 287;
+                       settingsToPassOnCommandLine = 280;
+               };
+               F56E5E4403BCF0E801A80006 = {
+                       children = (
+                               A6D347FE03CF574000A80006,
+                               F56E5E4903BCF10B01A80006,
+                               A64F6EF5052AA82D00140006,
+                               F56E5E4503BCF10B01A80006,
+                               F56E5E4603BCF10B01A80006,
+                               F56E5E4703BCF10B01A80006,
+                               F56E5E4803BCF10B01A80006,
+                               F56E5E4A03BCF10B01A80006,
+                               F56E5E4B03BCF10B01A80006,
+                               A64F6EED052AA73200140006,
+                               A64F6EEE052AA73200140006,
+                               A64F6EEF052AA73200140006,
+                               A64F6EF0052AA73200140006,
+                               A64F6EF1052AA73200140006,
+                               A64F6EF2052AA73200140006,
+                               A64F6EF3052AA73200140006,
+                               A64F6EF4052AA73200140006,
+                               A63F3B4E054DACB700140006,
+                               A63F3B4F054DACB700140006,
+                               A63F3B50054DACB700140006,
+                               A63F3B51054DACB700140006,
+                               A63F3B52054DACB700140006,
+                               A63F3B53054DACB700140006,
+                               A63F3B54054DACB700140006,
+                               A63F3B55054DACB700140006,
+                               A63F3B56054DACB700140006,
+                               A63F3B57054DACB700140006,
+                               A6BEE1CF058004B500140006,
+                               A6BEE1D0058004B500140006,
+                               A6BEE1D1058004B500140006,
+                               A64EF697059F5FE500140006,
+                       );
+                       isa = PBXGroup;
+                       name = Images;
+                       refType = 4;
+               };
+               F56E5E4503BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = about_dialog.sif;
+                       path = images/about_dialog.sif;
+                       refType = 4;
+               };
+               F56E5E4603BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = about_icon.sif;
+                       path = images/about_icon.sif;
+                       refType = 4;
+               };
+               F56E5E4703BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvas_icon.sif;
+                       path = images/canvas_icon.sif;
+                       refType = 4;
+               };
+               F56E5E4803BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = color_icon.sif;
+                       path = images/color_icon.sif;
+                       refType = 4;
+               };
+               F56E5E4903BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = Makefile.am;
+                       path = images/Makefile.am;
+                       refType = 4;
+               };
+               F56E5E4A03BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = real_icon.sif;
+                       path = images/real_icon.sif;
+                       refType = 4;
+               };
+               F56E5E4B03BCF10B01A80006 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vector_icon.sif;
+                       path = images/vector_icon.sif;
+                       refType = 4;
+               };
+               F581E12F03B23D710101DBD7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasproperties.cpp;
+                       path = src/gtkmm/canvasproperties.cpp;
+                       refType = 4;
+               };
+               F581E13003B23D710101DBD7 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasproperties.h;
+                       path = src/gtkmm/canvasproperties.h;
+                       refType = 4;
+               };
+               F5827D6103CBAB940112B647 = {
+                       fileRef = F50C84F2037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5827D6203CBAB950112B647 = {
+                       fileRef = F50C84F1037799F301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2703003C947C701BABFEF = {
+                       children = (
+                               F5F2705C03C948C301BABFEF,
+                               F5F2704003C9487C01BABFEF,
+                               A64F6D2A052AA52700140006,
+                               A64F6D2B052AA52700140006,
+                               A64F6D2C052AA52700140006,
+                               A64F6D2D052AA52700140006,
+                               A64F6D2E052AA52700140006,
+                               A64F6D2F052AA52700140006,
+                               A64F6D30052AA52700140006,
+                               F5F2704103C9487C01BABFEF,
+                               A6714E0A0413F36C00F656BD,
+                               F5F2704203C9487C01BABFEF,
+                               F5F2704303C9487C01BABFEF,
+                               F5F2704403C9487C01BABFEF,
+                               F5F2704503C9487C01BABFEF,
+                               F5F2704603C9487C01BABFEF,
+                               F5F2704703C9487C01BABFEF,
+                               F5F2704803C9487C01BABFEF,
+                               A63F3B46054DAC3A00140006,
+                               A63F3B47054DAC3A00140006,
+                               A64DD843057FEF2300140006,
+                               A64DD844057FEF2300140006,
+                       );
+                       isa = PBXGroup;
+                       name = "Sinfg Application Library";
+                       refType = 4;
+               };
+               F5F2703103C947FC01BABFEF = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F5F2705203C9487C01BABFEF,
+                               F5F2705403C9487C01BABFEF,
+                               F5F2705603C9487C01BABFEF,
+                               F5F2705703C9487C01BABFEF,
+                               F5F2705903C9487C01BABFEF,
+                               A6714E110413F36C00F656BD,
+                               A64F6D32052AA52700140006,
+                               A64F6D34052AA52700140006,
+                               A64F6D35052AA52700140006,
+                               A64F6D37052AA52700140006,
+                               A64F6D9B052AA5C100140006,
+                               A64F6D9D052AA5C100140006,
+                               A64F6D9F052AA5C100140006,
+                               A64F6DA1052AA5C100140006,
+                               A64F6DA3052AA5C100140006,
+                               A64F6DA5052AA5C100140006,
+                               A64F6DA7052AA5C100140006,
+                               A64F6DA9052AA5C100140006,
+                               A64F6DAB052AA5C100140006,
+                               A64F6DAD052AA5C100140006,
+                               A64F6DAF052AA5C100140006,
+                               A64F6DB1052AA5C100140006,
+                               A64F6DB3052AA5C100140006,
+                               A64F6DB5052AA5C100140006,
+                               A64F6DB7052AA5C100140006,
+                               A64F6DB9052AA5C100140006,
+                               A64F6DBB052AA5C100140006,
+                               A64F6DBD052AA5C100140006,
+                               A64F6DBF052AA5C100140006,
+                               A64F6DC1052AA5C100140006,
+                               A64F6DC3052AA5C100140006,
+                               A64F6DC5052AA5C100140006,
+                               A64F6DC7052AA5C100140006,
+                               A64F6DC9052AA5C100140006,
+                               A64F6DCB052AA5C100140006,
+                               A64F6DCD052AA5C100140006,
+                               A64F6DCF052AA5C100140006,
+                               A64F6DD1052AA5C100140006,
+                               A64F6DD3052AA5C100140006,
+                               A64F6DD5052AA5C100140006,
+                               A64F6DD7052AA5C100140006,
+                               A64F6DD9052AA5C100140006,
+                               A64F6DDB052AA5C100140006,
+                               A64F6DDD052AA5C100140006,
+                               A64F6DDF052AA5C100140006,
+                               A64F6DE1052AA5C100140006,
+                               A64F6DE3052AA5C100140006,
+                               A64F6DE5052AA5C100140006,
+                               A64F6DE7052AA5C100140006,
+                               A64F6DE9052AA5C100140006,
+                               A64F6DEB052AA5C100140006,
+                               A64F6DED052AA5C100140006,
+                               A64F6DEF052AA5C100140006,
+                               A64F6DF1052AA5C100140006,
+                               A64F6DF3052AA5C100140006,
+                               A64F6DF5052AA5C100140006,
+                               A64F6DF7052AA5C100140006,
+                               A64F6DF9052AA5C100140006,
+                               A64F6DFB052AA5C100140006,
+                               A63EEE2305446F5B00140006,
+                               A63F3B49054DAC3A00140006,
+                               A64DD846057FEF2300140006,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F5F2703203C947FC01BABFEF = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXResourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F5F2703303C947FC01BABFEF = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F5F2705103C9487C01BABFEF,
+                               F5F2705303C9487C01BABFEF,
+                               F5F2705503C9487C01BABFEF,
+                               F5F2705803C9487C01BABFEF,
+                               A64F6D31052AA52700140006,
+                               A64F6D33052AA52700140006,
+                               A64F6D36052AA52700140006,
+                               A64F6D9A052AA5C100140006,
+                               A64F6D9C052AA5C100140006,
+                               A64F6D9E052AA5C100140006,
+                               A64F6DA0052AA5C100140006,
+                               A64F6DA2052AA5C100140006,
+                               A64F6DA4052AA5C100140006,
+                               A64F6DA6052AA5C100140006,
+                               A64F6DA8052AA5C100140006,
+                               A64F6DAA052AA5C100140006,
+                               A64F6DAC052AA5C100140006,
+                               A64F6DAE052AA5C100140006,
+                               A64F6DB0052AA5C100140006,
+                               A64F6DB2052AA5C100140006,
+                               A64F6DB4052AA5C100140006,
+                               A64F6DB6052AA5C100140006,
+                               A64F6DB8052AA5C100140006,
+                               A64F6DBA052AA5C100140006,
+                               A64F6DBC052AA5C100140006,
+                               A64F6DBE052AA5C100140006,
+                               A64F6DC0052AA5C100140006,
+                               A64F6DC2052AA5C100140006,
+                               A64F6DC4052AA5C100140006,
+                               A64F6DC6052AA5C100140006,
+                               A64F6DC8052AA5C100140006,
+                               A64F6DCA052AA5C100140006,
+                               A64F6DCC052AA5C100140006,
+                               A64F6DCE052AA5C100140006,
+                               A64F6DD0052AA5C100140006,
+                               A64F6DD2052AA5C100140006,
+                               A64F6DD4052AA5C100140006,
+                               A64F6DD6052AA5C100140006,
+                               A64F6DD8052AA5C100140006,
+                               A64F6DDA052AA5C100140006,
+                               A64F6DDC052AA5C100140006,
+                               A64F6DDE052AA5C100140006,
+                               A64F6DE0052AA5C100140006,
+                               A64F6DE2052AA5C100140006,
+                               A64F6DE4052AA5C100140006,
+                               A64F6DE6052AA5C100140006,
+                               A64F6DE8052AA5C100140006,
+                               A64F6DEA052AA5C100140006,
+                               A64F6DEC052AA5C100140006,
+                               A64F6DEE052AA5C100140006,
+                               A64F6DF0052AA5C100140006,
+                               A64F6DF2052AA5C100140006,
+                               A64F6DF4052AA5C100140006,
+                               A64F6DF6052AA5C100140006,
+                               A64F6DF8052AA5C100140006,
+                               A64F6DFA052AA5C100140006,
+                               A63EEE2205446F5B00140006,
+                               A63F3B48054DAC3A00140006,
+                               A64DD845057FEF2300140006,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F5F2703403C947FC01BABFEF = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               F5F2705A03C9489C01BABFEF,
+                               F5F2705B03C9489D01BABFEF,
+                               F5F2705D03C9496901BABFEF,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F5F2703503C947FC01BABFEF = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               F5F2703603C947FC01BABFEF = {
+                       buildPhases = (
+                               F5F2703103C947FC01BABFEF,
+                               F5F2703203C947FC01BABFEF,
+                               F5F2703303C947FC01BABFEF,
+                               F5F2703403C947FC01BABFEF,
+                               F5F2703503C947FC01BABFEF,
+                       );
+                       buildSettings = {
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               FRAMEWORK_VERSION = A;
+                               HEADER_SEARCH_PATHS = "\"/usr/local/lib/sigc++-1.2/include\" \"/usr/local/include/sigc++-1.2\"";
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               OTHER_LIBTOOL_FLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREBINDING = NO;
+                               PRINCIPAL_CLASS = "";
+                               PRODUCT_NAME = sinfgapp;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                               WRAPPER_EXTENSION = framework;
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXFrameworkTarget;
+                       name = "Sinfg Application Library";
+                       productInstallPath = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+                       productName = sinfgapp;
+                       productReference = F5F2703703C947FC01BABFEF;
+                       productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string></string>
+       <key>CFBundleGetInfoString</key>
+       <string></string>
+       <key>CFBundleIconFile</key>
+       <string>canvas_icon</string>
+       <key>CFBundleIdentifier</key>
+       <string></string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string></string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string></string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>0.0.1d1</string>
+</dict>
+</plist>
+";
+               };
+               F5F2703703C947FC01BABFEF = {
+                       isa = PBXFrameworkReference;
+                       path = sinfgapp.framework;
+                       refType = 3;
+               };
+               F5F2704003C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action.cpp;
+                       path = src/sinfgapp/action.cpp;
+                       refType = 4;
+               };
+               F5F2704103C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = action.h;
+                       path = src/sinfgapp/action.h;
+                       refType = 4;
+               };
+               F5F2704203C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasinterface.cpp;
+                       path = src/sinfgapp/canvasinterface.cpp;
+                       refType = 4;
+               };
+               F5F2704303C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = canvasinterface.h;
+                       path = src/sinfgapp/canvasinterface.h;
+                       refType = 4;
+               };
+               F5F2704403C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = instance.cpp;
+                       path = src/sinfgapp/instance.cpp;
+                       refType = 4;
+               };
+               F5F2704503C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = instance.h;
+                       path = src/sinfgapp/instance.h;
+                       refType = 4;
+               };
+               F5F2704603C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = selectionmanager.h;
+                       path = src/sinfgapp/selectionmanager.h;
+                       refType = 4;
+               };
+               F5F2704703C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = uimanager.cpp;
+                       path = src/sinfgapp/uimanager.cpp;
+                       refType = 4;
+               };
+               F5F2704803C9487C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = uimanager.h;
+                       path = src/sinfgapp/uimanager.h;
+                       refType = 4;
+               };
+               F5F2705103C9487C01BABFEF = {
+                       fileRef = F5F2704003C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705203C9487C01BABFEF = {
+                       fileRef = F5F2704103C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F5F2705303C9487C01BABFEF = {
+                       fileRef = F5F2704203C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705403C9487C01BABFEF = {
+                       fileRef = F5F2704303C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F5F2705503C9487C01BABFEF = {
+                       fileRef = F5F2704403C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705603C9487C01BABFEF = {
+                       fileRef = F5F2704503C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F5F2705703C9487C01BABFEF = {
+                       fileRef = F5F2704603C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F5F2705803C9487C01BABFEF = {
+                       fileRef = F5F2704703C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705903C9487C01BABFEF = {
+                       fileRef = F5F2704803C9487C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                               ATTRIBUTES = (
+                                       Public,
+                               );
+                       };
+               };
+               F5F2705A03C9489C01BABFEF = {
+                       fileRef = F50C84FD03779A8301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705B03C9489D01BABFEF = {
+                       fileRef = F50C84FC03779A8301A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705C03C948C301BABFEF = {
+                       children = (
+                               A63EEE2005446F5B00140006,
+                               A63EEE2105446F5B00140006,
+                               A64F6D38052AA5C100140006,
+                               A64F6D39052AA5C100140006,
+                               A64F6D3A052AA5C100140006,
+                               A64F6D3B052AA5C100140006,
+                               A64F6D3C052AA5C100140006,
+                               A64F6D3D052AA5C100140006,
+                               A64F6D3E052AA5C100140006,
+                               A64F6D3F052AA5C100140006,
+                               A64F6D40052AA5C100140006,
+                               A64F6D41052AA5C100140006,
+                               A64F6D42052AA5C100140006,
+                               A64F6D43052AA5C100140006,
+                               A64F6D44052AA5C100140006,
+                               A64F6D45052AA5C100140006,
+                               A64F6D46052AA5C100140006,
+                               A64F6D47052AA5C100140006,
+                               A64F6D48052AA5C100140006,
+                               A64F6D49052AA5C100140006,
+                               A64F6D4A052AA5C100140006,
+                               A64F6D4B052AA5C100140006,
+                               A64F6D4C052AA5C100140006,
+                               A64F6D4D052AA5C100140006,
+                               A64F6D4E052AA5C100140006,
+                               A64F6D4F052AA5C100140006,
+                               A64F6D50052AA5C100140006,
+                               A64F6D51052AA5C100140006,
+                               A64F6D52052AA5C100140006,
+                               A64F6D53052AA5C100140006,
+                               A64F6D54052AA5C100140006,
+                               A64F6D55052AA5C100140006,
+                               A64F6D56052AA5C100140006,
+                               A64F6D57052AA5C100140006,
+                               A64F6D58052AA5C100140006,
+                               A64F6D59052AA5C100140006,
+                               A64F6D5A052AA5C100140006,
+                               A64F6D5B052AA5C100140006,
+                               A64F6D5C052AA5C100140006,
+                               A64F6D5D052AA5C100140006,
+                               A64F6D5E052AA5C100140006,
+                               A64F6D5F052AA5C100140006,
+                               A64F6D60052AA5C100140006,
+                               A64F6D61052AA5C100140006,
+                               A64F6D62052AA5C100140006,
+                               A64F6D63052AA5C100140006,
+                               A64F6D64052AA5C100140006,
+                               A64F6D65052AA5C100140006,
+                               A64F6D66052AA5C100140006,
+                               A64F6D67052AA5C100140006,
+                               A64F6D68052AA5C100140006,
+                               A64F6D69052AA5C100140006,
+                               A64F6D6A052AA5C100140006,
+                               A64F6D6B052AA5C100140006,
+                               A64F6D6C052AA5C100140006,
+                               A64F6D6D052AA5C100140006,
+                               A64F6D6E052AA5C100140006,
+                               A64F6D6F052AA5C100140006,
+                               A64F6D70052AA5C100140006,
+                               A64F6D71052AA5C100140006,
+                               A64F6D72052AA5C100140006,
+                               A64F6D73052AA5C100140006,
+                               A64F6D74052AA5C100140006,
+                               A64F6D75052AA5C100140006,
+                               A64F6D76052AA5C100140006,
+                               A64F6D77052AA5C100140006,
+                               A64F6D78052AA5C100140006,
+                               A64F6D79052AA5C100140006,
+                               A64F6D7A052AA5C100140006,
+                               A64F6D7B052AA5C100140006,
+                               A64F6D7C052AA5C100140006,
+                               A64F6D7D052AA5C100140006,
+                               A64F6D7E052AA5C100140006,
+                               A64F6D7F052AA5C100140006,
+                               A64F6D80052AA5C100140006,
+                               A64F6D81052AA5C100140006,
+                               A64F6D82052AA5C100140006,
+                               A64F6D83052AA5C100140006,
+                               A64F6D84052AA5C100140006,
+                               A64F6D85052AA5C100140006,
+                               A64F6D86052AA5C100140006,
+                               A64F6D87052AA5C100140006,
+                               A64F6D88052AA5C100140006,
+                               A64F6D89052AA5C100140006,
+                               A64F6D8A052AA5C100140006,
+                               A64F6D8B052AA5C100140006,
+                               A64F6D8C052AA5C100140006,
+                               A64F6D8D052AA5C100140006,
+                               A64F6D8E052AA5C100140006,
+                               A64F6D8F052AA5C100140006,
+                               A64F6D90052AA5C100140006,
+                               A64F6D91052AA5C100140006,
+                               A64F6D92052AA5C100140006,
+                               A64F6D93052AA5C100140006,
+                               A64F6D94052AA5C100140006,
+                               A64F6D95052AA5C100140006,
+                               A64F6D96052AA5C100140006,
+                               A64F6D97052AA5C100140006,
+                               A64F6D98052AA5C100140006,
+                               A64F6D99052AA5C100140006,
+                       );
+                       isa = PBXGroup;
+                       name = Actions;
+                       refType = 4;
+               };
+               F5F2705D03C9496901BABFEF = {
+                       fileRef = F50C858E03779DA401A80006;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2705E03C94BE301BABFEF = {
+                       children = (
+                       );
+                       isa = PBXGroup;
+                       name = Cocoa;
+                       refType = 4;
+               };
+               F5F2705F03C94C7C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iconcontroler.cpp;
+                       path = src/gtkmm/iconcontroler.cpp;
+                       refType = 4;
+               };
+               F5F2706003C94C7C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iconcontroler.h;
+                       path = src/gtkmm/iconcontroler.h;
+                       refType = 4;
+               };
+               F5F2706103C94C7C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = main.cpp;
+                       path = src/gtkmm/main.cpp;
+                       refType = 4;
+               };
+               F5F2706203C94C7C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = renddesc.cpp;
+                       path = src/gtkmm/renddesc.cpp;
+                       refType = 4;
+               };
+               F5F2706303C94C7C01BABFEF = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = renddesc.h;
+                       path = src/gtkmm/renddesc.h;
+                       refType = 4;
+               };
+               F5F2706403C94C7C01BABFEF = {
+                       fileRef = F5F2705F03C94C7C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2706503C94C7C01BABFEF = {
+                       fileRef = F5F2706003C94C7C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2706603C94C7C01BABFEF = {
+                       fileRef = F5F2706103C94C7C01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2706903C94C8E01BABFEF = {
+                       fileRef = F5F2703703C947FC01BABFEF;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               F5F2706A03C94D2101BABFEF = {
+                       isa = PBXTargetDependency;
+                       target = F5F2703603C947FC01BABFEF;
+               };
+       };
+       rootObject = F50C84CE0377988001A80006;
+}
diff --git a/synfig-studio/trunk/studio.prj b/synfig-studio/trunk/studio.prj
new file mode 100644 (file)
index 0000000..a1a2891
--- /dev/null
@@ -0,0 +1,166 @@
+# Anjuta Version 1.2.2 
+Compatibility Level: 1 
+
+<PROJECT_DESCRIPTION_START>
+
+<PROJECT_DESCRIPTION_END>
+<CONFIG_PROGS_START>
+<CONFIG_PROGS_END>
+<CONFIG_LIBS_START>
+<CONFIG_LIBS_END>
+<CONFIG_HEADERS_START>
+<CONFIG_HEADERS_END>
+<CONFIG_CHARACTERISTICS_START>
+<CONFIG_CHARACTERISTICS_END>
+<CONFIG_LIB_FUNCS_START>
+<CONFIG_LIB_FUNCS_END>
+<CONFIG_ADDITIONAL_START>
+<CONFIG_ADDITIONAL_END>
+<CONFIG_FILES_START>
+<CONFIG_FILES_END>
+<MAKEFILE_AM_START>
+<MAKEFILE_AM_END>
+
+props.file.type=project
+
+anjuta.version=1.2.2
+anjuta.compatibility.level=1
+
+project.name=studio
+project.type=GNOMEmm 2.0
+project.target.type=EXECUTABLE
+project.version=0.60.00
+project.author=Robert Quattlebaum
+project.source.target=src/gtkmm/sinfgstudio
+project.has.gettext=0
+project.gui.command=
+project.programming.language=C++
+project.excluded.modules=      intl
+
+project.config.extra.modules.before=
+project.config.extra.modules.after=
+project.config.blocked=1
+project.config.disable.overwriting=1 1 1 1 1 1 1 1 1 
+
+project.menu.entry=studio Version 0.60.00
+project.menu.group=Application
+project.menu.comment=studio Version 0.60.00
+project.menu.icon=
+project.menu.need.terminal=0
+
+project.configure.options=--enable-debug --enable-static=no
+anjuta.program.arguments=
+preferences.build.option.jobs=0
+preferences.build.option.silent=0
+preferences.build.option.autosave=0
+preferences.anjuta.make.options=-j6
+preferences.make=make
+preferences.build.option.keep.going=0
+preferences.build.option.warn.undef=0
+preferences.autoformat.custom.style= -i8 -sc -bli0 -bl0 -cbi0 -ss
+preferences.indent.opening=0
+preferences.autoformat.disable=0
+preferences.indent.automatic=1
+preferences.use.tabs=1
+preferences.indent.size=4
+preferences.tabsize=4
+preferences.indent.closing=0
+
+module.include.name=.
+module.include.type=
+module.include.files=\
+       src/gtkmm/View.h\
+       src/gtkmm/app.h\
+       src/gtkmm/renddesc.h\
+       src/gtkmm/toolbox.h\
+       src/gtkmm/trackview.h\
+       src/gtkmm/workarea.h\
+       src/gtkmm/about.h\
+       src/gtkmm/datanode.h\
+       src/gtkmm/datatype.h\
+       src/gtkmm/canvasview.h\
+       src/gtkmm/compview.h\
+       src/gtkmm/instance.h\
+       src/actions.h\
+       src/app.h\
+       src/template.h\
+       src/toolbox.h\
+       src/trackview.h\
+       src/view.h\
+       src/workarea.h\
+       src/instance.h\
+       src/compview.h\
+       src/canvasview.h\
+       config.h
+
+module.source.name=.
+module.source.type=
+module.source.files=\
+       src/gtkmm/View.cpp\
+       src/gtkmm/app.cpp\
+       src/gtkmm/renddesc.cpp\
+       src/gtkmm/toolbox.cpp\
+       src/gtkmm/trackview.cpp\
+       src/gtkmm/workarea.cpp\
+       src/gtkmm/canvasview.cpp\
+       src/gtkmm/datanode.cpp\
+       src/gtkmm/datatype.cpp\
+       src/gtkmm/compview.cpp\
+       src/gtkmm/instance.cpp\
+       src/gtkmm/about.cpp\
+       src/actions.cpp\
+       src/app.cpp\
+       src/main.cpp\
+       src/template.cpp\
+       src/toolbox.cpp\
+       src/trackview.cpp\
+       src/view.cpp\
+       src/workarea.cpp\
+       src/instance.cpp\
+       src/compview.cpp\
+       src/canvasview.cpp
+
+module.pixmap.name=.
+module.pixmap.type=
+module.pixmap.files=\
+       images/sif_icon.png\
+       images/sinfg_icon.png\
+       images/about_icon.png\
+       images/canvas_icon.png\
+       images/about_dialog.png
+
+module.data.name=.
+module.data.type=
+module.data.files=
+
+module.help.name=.
+module.help.type=
+module.help.files=
+
+module.doc.name=.
+module.doc.type=
+module.doc.files=\
+       ChangeLog\
+       INSTALL\
+       README
+
+module.po.files=
+
+compiler.options.supports=
+compiler.options.include.paths=\
+       .\
+       ..
+compiler.options.library.paths=
+compiler.options.libraries=
+compiler.options.libraries.selected=
+compiler.options.defines=\
+       HAVE_CONFIG_H
+compiler.options.defines.selected=
+compiler.options.warning.buttons=0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 0 
+compiler.options.optimize.buttons=0 0 1 0 
+compiler.options.other.buttons=1 0 
+compiler.options.other.c.flags=
+compiler.options.other.l.flags=
+compiler.options.other.l.libs=
+
+project.src.paths=
diff --git a/synfig-studio/trunk/win32build.sh b/synfig-studio/trunk/win32build.sh
new file mode 100755 (executable)
index 0000000..2616725
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+OPT_FLAGS="--disable-optimization --disable-debug --enable-license-key"
+
+./configure --host=mingw32 --prefix=C:/PROGRA~1/Synfig $OPT_FLAGS
+
+make clean
+
+make installer
+
diff --git a/synfig-studio/trunk/win32inst.nsi.in b/synfig-studio/trunk/win32inst.nsi.in
new file mode 100644 (file)
index 0000000..8594deb
--- /dev/null
@@ -0,0 +1,192 @@
+; example2.nsi
+;
+; This script is based on example1.nsi, but it remember the directory, 
+; has uninstall support and (optionally) installs start menu shortcuts.
+;
+; It will install makensisw.exe into a directory that the user selects,
+
+!include "MUI.nsh"
+
+;--------------------------------
+
+; The name of the installer
+Name "@PACKAGE_NAME@ @PACKAGE_VERSION@"
+
+; The file to write
+OutFile "@PACKAGE_TARNAME@-@PACKAGE_VERSION@.exe"
+
+; The default installation directory
+InstallDir $PROGRAMFILES\Synfig
+
+; Registry key to check for directory (so if you install again, it will 
+; overwrite the old one automatically)
+InstallDirRegKey HKLM "Software\Voria_@PACKAGE_TARNAME@" "Install_Dir"
+
+!define MUI_ABORTWARNING
+
+!define SHCNE_ASSOCCHANGED 0x8000000
+!define SHCNF_IDLIST 0
+
+!define PRODUCT_REG_KEY "Software\@PACKAGE_TARNAME@\@API_VERSION@"
+!define PRODUCT_UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\@PACKAGE_TARNAME@"
+!define PRODUCT_UNINSTALL_EXE "uninstall-@PACKAGE_TARNAME@.exe"
+
+;--------------------------------
+
+;!define MUI_WELCOMEFINISHPAGE_BITMAP "images\about_dialog.bmp"
+
+; Pages
+
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_LICENSE "alphalicense.txt"
+!insertmacro MUI_PAGE_COMPONENTS
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+
+!insertmacro MUI_LANGUAGE "English"
+
+;--------------------------------
+
+; The stuff to install
+Section "Synfig Studio"
+
+  SectionIn RO
+  
+  SetOutPath "$INSTDIR\share\pixmaps"
+  File "images\*.png"
+  
+  SetOutPath "$INSTDIR\share"
+  File "images\*.ico"
+
+  SetOutPath "$INSTDIR\bin"
+  File "src\sinfgapp\.libs\libsinfgapp-0.dll"
+  File "src\gtkmm\.libs\sinfgstudio.exe"
+
+       FileOpen $0 $PROFILE\.gtkrc-2.0 a
+       FileSeek $0 0 END
+       FileWrite $0 "gtk-toolbar-style = 0"
+       FileWriteByte $0 "13"
+       FileWriteByte $0 "10"
+       FileWrite $0 'gtk-theme-name = "Default"'
+       FileWriteByte $0 "13"
+       FileWriteByte $0 "10"   
+       FileClose $0
+
+  WriteRegStr HKLM "${PRODUCT_REG_KEY}" "Path" "$INSTDIR"
+  WriteRegStr HKLM "${PRODUCT_REG_KEY}" "Version" "@PRODUCT_VERSION@"
+  
+  ; Write the uninstall keys for Windows
+  WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayName" "@PACKAGE_NAME@"
+  WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayVersion" "@PACKAGE_VERSION@"
+  WriteRegStr HKLM "${PRODUCT_UNINSTALL_KEY}" "UninstallString" '"$INSTDIR\${PRODUCT_UNINSTALL_EXE}"'
+  WriteRegDWORD HKLM "${PRODUCT_UNINSTALL_KEY}" "NoModify" 1
+  WriteRegDWORD HKLM "${PRODUCT_UNINSTALL_KEY}" "NoRepair" 1
+
+
+       WriteRegStr HKCR ".sif" "" "Synfig.Composition"
+       WriteRegStr HKCR ".sif" "Content Type" "image/x-sif"
+       WriteRegStr HKCR ".sif" "PerceivedType" "image"
+
+       WriteRegStr HKCR ".sif.gz" "" "Synfig.Composition"
+       WriteRegStr HKCR ".sif.gz" "Content Type" "image/x-sifz"
+       WriteRegStr HKCR ".sif.gz" "PerceivedType" "image"
+
+       WriteRegStr HKCR "Synfig.Composition" "" "Synfig Composition File"
+       WriteRegStr HKCR "Synfig.Composition\DefaultIcon" "" "$INSTDIR\bin\sinfgstudio.exe;1"
+       WriteRegStr HKCR "Synfig.Composition\shell" "" "open"
+       WriteRegStr HKCR "Synfig.Composition\shell\open\command" "" '$INSTDIR\bin\sinfgstudio.exe "%1"'
+       
+       System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)'
+  WriteUninstaller "${PRODUCT_UNINSTALL_EXE}"
+SectionEnd
+
+
+; Optional section (can be disabled by the user)
+Section "Start Menu Shortcuts"
+
+  CreateDirectory "$SMPROGRAMS\Voria"
+  CreateShortCut "$SMPROGRAMS\Voria\Uninstall Synfig Studio.lnk" "$INSTDIR\uninstall-@PACKAGE_TARNAME@.exe" "" "$INSTDIR\uninstall-@PACKAGE_TARNAME@.exe" 0
+  CreateShortCut "$SMPROGRAMS\Voria\Synfig Studio.lnk" "$INSTDIR\bin\sinfgstudio.exe" "" "$INSTDIR\bin\sinfgstudio.exe" 0
+  
+SectionEnd
+
+;--------------------------------
+
+; Uninstaller
+
+Section "Uninstall"
+  
+       DeleteRegKey HKCR "Synfig.Composition\shell\open\command" 
+       DeleteRegKey HKCR "Synfig.Composition\DefaultIcon" 
+       DeleteRegKey HKCR "Synfig.Composition\shell"
+       DeleteRegKey HKCR "Synfig.Composition" 
+       DeleteRegKey HKCR ".sif"
+       DeleteRegKey HKCR ".sif.gz"
+  
+  ; Remove registry keys
+  DeleteRegKey HKLM "${PRODUCT_REG_KEY}"
+  DeleteRegKey HKLM "${PRODUCT_UNINSTALL_KEY}"
+
+  ; Remove files and uninstaller
+       Delete "$INSTDIR\${PRODUCT_UNINSTALL_EXE}"
+  Delete $INSTDIR\bin\sinfgstudio.exe
+  Delete $INSTDIR\bin\libsinfgapp-0.dll
+  RMDir $INSTDIR\bin
+
+  ; Remove shortcuts, if any
+  Delete "$SMPROGRAMS\Voria\Uninstall Synfig Studio.lnk"
+  Delete "$SMPROGRAMS\Voria\Synfig Studio.lnk"
+
+  ; Remove directories used
+  RMDir "$SMPROGRAMS\Voria"
+  RMDir "$INSTDIR"
+
+       System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, i 0, i 0)'
+SectionEnd
+
+Function .onInit
+       ; Get installer location
+       ReadRegStr $R0 HKLM "${PRODUCT_UNINSTALL_KEY}" "UninstallString"
+;      IfErrors 0 +2
+;      ReadRegStr $R0 HKCU "${PRODUCT_UNINSTALL_KEY}" "UninstallString"
+       
+       StrCmp $R0 "" done
+
+       ; Get current installed version
+       ReadRegStr $R1 HKLM "${PRODUCT_UNINSTALL_KEY}" "DisplayVersion"
+;      IfErrors 0 +2
+;      ReadRegStr $R1 HKCU "${PRODUCT_UNINSTALL_KEY}" "DisplayVersion"
+
+;  StrCmp $R1 ${PRODUCT_VERSION} done
+
+       MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION "A previous version of @PACKAGE_NAME@ appears to be installed. Would you like to uninstall it first?" IDNO done IDCANCEL abortInstall
+
+       ; Run the uninstaller
+       
+       ClearErrors
+       ; CopyFiles "$R0" $TEMP
+       ExecWait '$R0 _?=$INSTDIR'
+       IfErrors no_remove_uninstaller
+       Delete $R0
+       RMDir $INSTDIR
+
+no_remove_uninstaller:
+;    Delete "$TEMP\$R0"
+       
+    ; Check that the user completed the uninstallation by examining the registry
+    ReadRegStr $R0 HKLM "${PRODUCT_UNINSTALL_KEY}" "UninstallString"
+       StrCmp $R0 "" done abortInstall
+       ReadRegStr $R0 HKCU "${PRODUCT_UNINSTALL_KEY}" "UninstallString"
+       StrCmp $R0 "" done abortInstall
+
+abortInstall:
+    MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to uninstall previous version of @PACKAGE_NAME@"
+    Abort
+
+done:
+    BringToFront
+
+FunctionEnd