/* * DisplacementControl.cs * Copyright (c) 2007-2009 kbinani * * This file is part of LipSync. * * LipSync is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * LipSync is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Drawing; using System.Windows.Forms; using System.IO; using System.Text; using Boare.Lib.AppUtil; using CurveEditor; namespace LipSync { public partial class DisplacementControl : Form, IMultiLanguageControl { private PointF m_scaleandoffset_x = new PointF( 1f, 0f ); private PointF m_scaleandoffset_y = new PointF( 1f, 0f ); private PointF m_scaleandoffset_alpha = new PointF( 400f, 0.3f ); private PointF m_scaleandoffset_scale = new PointF( 40f, 0.5f ); private PointF m_scaleandoffset_rotate = new PointF( 1f, 0f ); private bool m_first_scaleandoffset = true; private FormCurveExport m_dialog = null; public DisplacementControl() { InitializeComponent(); ApplyFont( AppManager.Config.Font.GetFont() ); ApplyLanguage(); Rectangle r = AppManager.Config.CurveWindowPos; Point pt_lt = new Point( r.Left, r.Top ); Point pt_lb = new Point( r.Left, r.Bottom ); Point pt_rt = new Point( r.Right, r.Top ); Point pt_rb = new Point( r.Right, r.Bottom ); bool visible = false; foreach ( Screen s in Screen.AllScreens ) { visible = visible | (IsInRectangle( pt_lt, s.Bounds ) | IsInRectangle( pt_lb, s.Bounds ) | IsInRectangle( pt_rt, s.Bounds ) | IsInRectangle( pt_rb, s.Bounds )); } if ( visible ) { this.Left = r.Left; this.Top = r.Top; this.Width = r.Width; this.Height = r.Height; } else { this.Width = Screen.PrimaryScreen.Bounds.Width / 2; this.Height = Screen.PrimaryScreen.Bounds.Height / 2; this.Left = this.Width / 2; this.Top = this.Height / 2; } if ( AppManager.Config.CurveMaximized ) { this.WindowState = FormWindowState.Maximized; } else { this.WindowState = FormWindowState.Normal; } this.SizeChanged += new EventHandler( DisplacementControl_LocationOrSizeChanged ); this.LocationChanged += new EventHandler( DisplacementControl_LocationOrSizeChanged ); } /// /// どのカーブも選択されていない状態にします /// public void SetSelectedNone() { curveEditor.Clear(); curveEditor.ClearBuffer(); comboObjects.SelectedIndex = -1; } /// /// rectの中にpointが入っているかどうかを判定 /// /// /// /// private static bool IsInRectangle( Point point, Rectangle rect ) { if ( rect.X <= point.X && point.X <= rect.X + rect.Width ) { if ( rect.Y <= point.Y && point.Y <= rect.Y + rect.Height ) { return true; } } return false; } public void ApplyLanguage() { this.Text = _( "Edit Motion Curve" ); menuClose.Text = _( "Close" ) + "(&C)"; menuFile.Text = _( "File" ) + "(&F)"; menuFileImport.Text = _( "Import" ) + "(&I)"; menuFileExport.Text = _( "Export" ) + "(&E)"; menuRedo.Text = _( "Redo" ); menuUndo.Text = _( "Undo" ); menuEdit.Text = _( "Edit" ) + "(&E)"; } public void ApplyFont( Font font ) { this.Font = font; foreach ( Control c in this.Controls ) { Boare.Lib.AppUtil.Util.applyFontRecurse( c, font ); } } public static string _( string s ) { return Messaging.getMessage( s ); } /// /// 現在の編集情報を破棄します /// public void Clear() { curveEditor.Clear(); comboObjects.Items.Clear(); comboObjects.Text = ""; } private void DisplacementControl_FormClosing( object sender, FormClosingEventArgs e ) { e.Cancel = true; } private void menuUndo_Click( object sender, EventArgs e ) { curveEditor.Undo(); } private void menuRedo_Click( object sender, EventArgs e ) { curveEditor.Redo(); } private void menuEdit_DropDownOpening( object sender, EventArgs e ) { menuUndo.Enabled = curveEditor.IsUndoAvailable; menuRedo.Enabled = curveEditor.IsRedoAvailable; } private void comboObjects_SelectedIndexChanged( object sender, EventArgs e ) { int index = comboObjects.SelectedIndex; #if DEBUG Console.WriteLine( "DisplacementControl+comboObjects_SelectedIndexChanged" ); Console.WriteLine( " index=" + index ); #endif if ( m_first_scaleandoffset ) { float scale, offset; if ( curveEditor.GetYScaleAndYOffset( "X", out scale, out offset ) ) { m_scaleandoffset_x = new PointF( scale, offset ); } if ( curveEditor.GetYScaleAndYOffset( "Y", out scale, out offset ) ) { m_scaleandoffset_y = new PointF( scale, offset ); } if ( curveEditor.GetYScaleAndYOffset( "Alpha", out scale, out offset ) ) { m_scaleandoffset_alpha = new PointF( scale, offset ); #if DEBUG Console.WriteLine( "Alpha, scale=" + scale + "; offset=" + offset ); #endif } if ( curveEditor.GetYScaleAndYOffset( "Scale", out scale, out offset ) ) { m_scaleandoffset_scale = new PointF( scale, offset ); } if ( curveEditor.GetYScaleAndYOffset( "Rotate", out scale, out offset ) ) { m_scaleandoffset_rotate = new PointF( scale, offset ); } } curveEditor.Clear(); curveEditor.ClearBuffer(); if ( index >= 0 ) { TagForTreeNode node = (TagForTreeNode)comboObjects.Items[index]; int id = node.id_or_index; switch ( node.type ) { case ZorderItemType.another: curveEditor.Add( "X", AppManager.SaveData.m_group_another[id].mc_x ); curveEditor.Add( "Y", AppManager.SaveData.m_group_another[id].mc_y ); curveEditor.Add( "Alpha", AppManager.SaveData.m_group_another[id].mc_alpha ); curveEditor.Add( "Scale", AppManager.SaveData.m_group_another[id].mc_scale ); curveEditor.Add( "Rotate", AppManager.SaveData.m_group_another[id].mc_rotate ); break; case ZorderItemType.character: curveEditor.Add( "X", AppManager.SaveData.m_groups_character[id].mc_x ); curveEditor.Add( "Y", AppManager.SaveData.m_groups_character[id].mc_y ); curveEditor.Add( "Alpha", AppManager.SaveData.m_groups_character[id].mc_alpha ); curveEditor.Add( "Scale", AppManager.SaveData.m_groups_character[id].mc_scale ); curveEditor.Add( "Rotate", AppManager.SaveData.m_groups_character[id].mc_rotate ); break; case ZorderItemType.plugin: curveEditor.Add( "X", AppManager.SaveData.m_group_plugin[id].mc_x ); curveEditor.Add( "Y", AppManager.SaveData.m_group_plugin[id].mc_y ); curveEditor.Add( "Alpha", AppManager.SaveData.m_group_plugin[id].mc_alpha ); curveEditor.Add( "Scale", AppManager.SaveData.m_group_plugin[id].mc_scale ); curveEditor.Add( "Rotate", AppManager.SaveData.m_group_plugin[id].mc_rotate ); break; case ZorderItemType.telop: curveEditor.Add( "X", AppManager.SaveData[id].mc_x ); curveEditor.Add( "Y", AppManager.SaveData[id].mc_y ); curveEditor.Add( "Alpha", AppManager.SaveData[id].mc_alpha ); curveEditor.Add( "Scale", AppManager.SaveData[id].mc_scale ); curveEditor.Add( "Rotate", AppManager.SaveData[id].mc_rotate ); break; } curveEditor.SetYScaleAndYOffset( "X", m_scaleandoffset_x.X, m_scaleandoffset_x.Y ); curveEditor.SetYScaleAndYOffset( "Y", m_scaleandoffset_y.X, m_scaleandoffset_y.Y ); curveEditor.SetYScaleAndYOffset( "Alpha", m_scaleandoffset_alpha.X, m_scaleandoffset_alpha.Y ); curveEditor.SetYScaleAndYOffset( "Scale", m_scaleandoffset_scale.X, m_scaleandoffset_scale.Y ); curveEditor.SetYScaleAndYOffset( "Rotate", m_scaleandoffset_rotate.X, m_scaleandoffset_rotate.Y ); if ( m_first_scaleandoffset ) { m_first_scaleandoffset = false; } curveEditor.Invalidate(); } } private void DisplacementControl_VisibleChanged( object sender, EventArgs e ) { ApplyLanguage(); } private void menuVisualNumericInput_CheckedChanged( object sender, EventArgs e ) { this.Invalidate(); } private void curveEditor_CurveEdited() { AppManager.Edited = true; } private void DisplacementControl_LocationOrSizeChanged( object sender, EventArgs e ) { if ( AppManager.Config != null ) { if ( this.WindowState == FormWindowState.Normal ) { AppManager.Config.CurveWindowPos = this.Bounds; } AppManager.Config.CurveMaximized = (this.WindowState == FormWindowState.Maximized); } } private void menuClose_Click( object sender, EventArgs e ) { this.Close(); } private void menuFileExport_Click( object sender, EventArgs e ) { #if DEBUG Console.WriteLine( "DisplacementControl#menuFileExport_Click" ); #endif if ( m_dialog == null ) { m_dialog = new FormCurveExport(); } m_dialog.setMode( FormCurveExport.Mode.EXPORT ); if ( m_dialog.ShowDialog() != DialogResult.OK ) { return; } int index = comboObjects.SelectedIndex; if ( index < 0 ) { return; } TagForTreeNode node = (TagForTreeNode)comboObjects.Items[index]; int id = node.id_or_index; BezierChain x = null; BezierChain y = null; BezierChain alpha = null; BezierChain scale = null; BezierChain rotate = null; switch ( node.type ) { case ZorderItemType.another: x = AppManager.SaveData.m_group_another[id].mc_x; y = AppManager.SaveData.m_group_another[id].mc_y; alpha = AppManager.SaveData.m_group_another[id].mc_alpha; scale = AppManager.SaveData.m_group_another[id].mc_scale; rotate = AppManager.SaveData.m_group_another[id].mc_rotate; break; case ZorderItemType.character: x = AppManager.SaveData.m_groups_character[id].mc_x; y = AppManager.SaveData.m_groups_character[id].mc_y; alpha = AppManager.SaveData.m_groups_character[id].mc_alpha; scale = AppManager.SaveData.m_groups_character[id].mc_scale; rotate = AppManager.SaveData.m_groups_character[id].mc_rotate; break; case ZorderItemType.plugin: x = AppManager.SaveData.m_group_plugin[id].mc_x; y = AppManager.SaveData.m_group_plugin[id].mc_y; alpha = AppManager.SaveData.m_group_plugin[id].mc_alpha; scale = AppManager.SaveData.m_group_plugin[id].mc_scale; rotate = AppManager.SaveData.m_group_plugin[id].mc_rotate; break; case ZorderItemType.telop: x = AppManager.SaveData[id].mc_x; y = AppManager.SaveData[id].mc_y; alpha = AppManager.SaveData[id].mc_alpha; scale = AppManager.SaveData[id].mc_scale; rotate = AppManager.SaveData[id].mc_rotate; break; } String name = comboObjects.Items[index].ToString(); String dir = m_dialog.getPath(); if ( m_dialog.isX() ) { exportBezierChain( x, Path.Combine( dir, name + "_X.txt" ) ); } if ( m_dialog.isY() ) { exportBezierChain( y, Path.Combine( dir, name + "_Y.txt" ) ); } if ( m_dialog.isAlpha() ) { exportBezierChain( alpha, Path.Combine( dir, name + "_ALPHA.txt" ) ); } if ( m_dialog.isScale() ) { exportBezierChain( scale, Path.Combine( dir, name + "_SCALE.txt" ) ); } if ( m_dialog.isRotation() ) { exportBezierChain( rotate, Path.Combine( dir, name + "_ROTATE.txt" ) ); } } private void menuFileImport_Click( object sender, EventArgs e ) { #if DEBUG Console.WriteLine( "menuFileImport_Click" ); #endif if ( m_dialog == null ) m_dialog = new FormCurveExport(); m_dialog.setMode( FormCurveExport.Mode.IMPORT ); if ( m_dialog.ShowDialog() != DialogResult.OK ) return; BezierChain chain = new BezierChain( Color.Black ); if ( m_dialog.isX() ) chain.Color = Common.CURVE_X; if ( m_dialog.isY() ) chain.Color = Common.CURVE_Y; if ( m_dialog.isAlpha() ) chain.Color = Common.CURVE_ALPHA; if ( m_dialog.isScale() ) chain.Color = Common.CURVE_SCALE; if ( m_dialog.isRotation() ) chain.Color = Common.CURVE_ROTATE; String file = m_dialog.getPath(); if ( !File.Exists( file ) ) return; if ( comboObjects.SelectedIndex < 0 ) return; using ( StreamReader sr = new StreamReader( file, Encoding.GetEncoding( 0 ) ) ) { String line = ""; int point_id = 0; while ( (line = sr.ReadLine()) != null ) { string[] spl = line.Split( new char[] { '\t', ' ', ' ' }, StringSplitOptions.RemoveEmptyEntries ); if ( spl.Length < 2 ) continue; ControlType tleft = ControlType.None; ControlType tright = ControlType.None; PointF pbase = new PointF(); PointF pleft = new PointF(); PointF pright = new PointF(); float v = 0.0f; if ( float.TryParse( spl[0], out v ) ) pbase.X = v; if ( float.TryParse( spl[1], out v ) ) pbase.Y = v; if ( spl.Length >= 8 ) { if ( float.TryParse( spl[2], out v ) ) pleft.X = v; if ( float.TryParse( spl[3], out v ) ) pleft.Y = v; String s = spl[4].Trim().ToLower(); if ( s.Equals( "master" ) ) tleft = ControlType.Master; if ( s.Equals( "normal" ) ) tleft = ControlType.Normal; if ( float.TryParse( spl[5], out v ) ) pright.X = v; if ( float.TryParse( spl[6], out v ) ) pright.Y = v; s = spl[7].Trim().ToLower(); if ( s.Equals( "master" ) ) tright = ControlType.Master; if ( s.Equals( "normal" ) ) tright = ControlType.Normal; } point_id++; BezierPoint bp = new BezierPoint( pbase, new PointF(), new PointF() ); bp.ID = point_id; bp.m_control_left = pleft; bp.m_control_right = pright; bp.ControlLeftType = tleft; bp.ControlRightType = tright; #if DEBUG Console.WriteLine( " bp=" + bp.ToString() ); #endif chain.List.Add( bp ); } } String id = "X"; if ( m_dialog.isX() ) id = "X"; if ( m_dialog.isY() ) id = "Y"; if ( m_dialog.isAlpha() ) id = "Alpha"; if ( m_dialog.isScale() ) id = "Scale"; if ( m_dialog.isRotation() ) id = "Rotate"; CurveEditor.Command run = CurveEditor.Command.GCommandReplace( id, chain ); curveEditor.Register( curveEditor.Execute( run ) ); } private void exportBezierChain( BezierChain chain, String file ) { int count = chain.List.Count; using ( StreamWriter sw = new StreamWriter( file, false, Encoding.GetEncoding( 0 ) ) ) { for ( int i = 0; i < count; i++ ) { BezierPoint point = chain.List[i]; sw.WriteLine( point.Base.X + "\t" + point.Base.Y + "\t" + point.m_control_left.X + "\t" + point.m_control_left.Y + "\t" + point.ControlLeftType + "\t" + point.m_control_right.X + "\t" + point.m_control_right.Y + "\t" + point.ControlRightType ); } } } } }