using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using CommonAI.Zone.ZoneEditor.Plugin.EditorToScene; using CommonAI.Zone.ZoneEditor.Plugin.SceneToEditor; using CommonAI.Zone; using CommonAI.Zone.ZoneEditor; using CommonAI.RTS; using CommonLang.Vector; using System.Collections; using CommonAI.Zone.Instance; using CommonLang; using GameEditorPlugin.Win32; using CommonFroms.Drawing; namespace GameEditorPlugin.Win32.Editor { public abstract partial class EditorDisplayPanel : UserControl { public static bool ShowUnit = false; public static bool ShowRegion = false; public static bool ShowItem = false; public static bool ShowPoint = false; public static bool ShowDecoration = false; public static bool ShowArea = false; public static bool ShowAll { get { return !(ShowUnit || ShowItem || ShowDecoration || ShowRegion || ShowPoint || ShowArea); } } //--------------------------------------------------------------------------- private EditorWorld world; public bool ShowGrid { get; private set; } private ToolStripButton[] btns_ShowGroup; public EditorDisplayPanel() { InitializeComponent(); this.btns_ShowGroup = new ToolStripButton[] { btn_ShowUnit, btn_ShowItem, btn_ShowDecoration, btn_ShowPoint, btn_ShowRegion, btn_ShowArea}; this.pictureBox1.KeyDown += PictureBox1_KeyDown; this.pictureBox1.KeyUp += PictureBox1_KeyUp; this.pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel); } public void SetSceneData(MsgSetScene data) { try { if (world != null) { this.world.ResetTerrain(data.Data); } else { this.world = new EditorWorld(this, data.Data); float scale = Math.Max( ((float)pictureBox1.Width) / world.Width, ((float)pictureBox1.Height) / world.Height); world.setCameraScale(scale, scale); } } catch (Exception err) { MessageBox.Show(err.Message); } } private void Win32EditorPanel_Load(object sender, EventArgs e) { this.SendToEditor(new RspEditorState()); btn_ShowUnit.Checked = ShowUnit; btn_ShowItem.Checked = ShowItem; btn_ShowDecoration.Checked = ShowDecoration; btn_ShowRegion.Checked = ShowRegion; btn_ShowPoint.Checked = ShowPoint; refresh_Show(); } //--------------------------------------------------------------------------- #region Abstract abstract public void SendToEditor(object data); abstract protected T CallAddObjectData(Action callback) where T : SceneObjectData; abstract protected T CallResetObjectData(string name, Action callback) where T : SceneObjectData; #endregion //--------------------------------------------------------------------------- #region ShowObject private void btn_Show_Click(object sender, EventArgs e) { foreach (ToolStripButton btn in btns_ShowGroup) { if (sender != btn) { btn.Checked = false; } } } private void btn_Show_CheckedChanged(object sender, EventArgs e) { pictureBox1.Refresh(); } private void refresh_Show() { ShowUnit = btn_ShowUnit.Checked; ShowItem = btn_ShowItem.Checked; ShowDecoration = btn_ShowDecoration.Checked; ShowRegion = btn_ShowRegion.Checked; ShowPoint = btn_ShowPoint.Checked; ShowArea = btn_ShowArea.Checked; if (world.SelectedObject != null && !ShowAll && !world.SelectedObject.Pickable) { world.Deselect(world.SelectedObject); } } #endregion //--------------------------------------------------------------------------- #region Message internal MsgSetTerrainBrush LastBrush = new MsgSetTerrainBrush(); internal MsgSetEditorMode LastMode = new MsgSetEditorMode(); virtual public void OnMsgReceived(object data) { if (data is MsgSetScene) { SetSceneData(data as MsgSetScene); } else if (data is MsgPutUnit) { world.AddUnit(data as MsgPutUnit); } else if (data is MsgPutItem) { world.AddItem(data as MsgPutItem); } else if (data is MsgPutPoint) { world.AddPoint(data as MsgPutPoint); } else if (data is MsgPutRegion) { world.AddRegion(data as MsgPutRegion); } else if (data is MsgPutDecoration) { world.AddDecoration(data as MsgPutDecoration); } else if (data is MsgPutArea) { world.AddArea(data as MsgPutArea); } else if (data is MsgRemoveObject) { world.RemoveObject(data as MsgRemoveObject); } else if (data is MsgRenameObject) { world.RenameObject(data as MsgRenameObject); } else if (data is MsgSelectObject) { world.SelectObject(data as MsgSelectObject); } else if (data is MsgShowTerrain) { ShowGrid = (data as MsgShowTerrain).Show; } else if (data is MsgLocateCamera) { MsgLocateCamera msg = data as MsgLocateCamera; world.setCamera(msg.X, msg.Y); rsp_CameraChanged(); } else if (data is MsgSetTerrainBrush) { this.LastBrush = data as MsgSetTerrainBrush; this.LastBrush.Size = Math.Max(1, LastBrush.Size); } else if (data is MsgSetEditorMode) { this.LastMode = data as MsgSetEditorMode; } pictureBox1.Refresh(); } void rsp_CameraChanged() { RspCameraChanged rsp = new RspCameraChanged(); rsp.X = world.CameraX; rsp.Y = world.CameraY; rsp.W = world.screenToWorldSizeX(pictureBox1.Width); rsp.H = world.screenToWorldSizeY(pictureBox1.Height); SendToEditor(rsp); } void rsp_ObjectPositionChanged(EditorObject u) { RspObjectPositionChanged rsp = new RspObjectPositionChanged(); rsp.Name = u.Name; rsp.x = u.X; rsp.y = u.Y; SendToEditor(rsp); } void rsp_RspObjectDirectionChanged(EditorObject u) { RspObjectDirectionChanged rsp = new RspObjectDirectionChanged(); rsp.Name = u.Name; rsp.dir = u.Direction; SendToEditor(rsp); } void rsp_FillTerrain() { List changed = world.PopFillTerrainStack(); if (changed.Count > 0) { RspZoneFlagBathChanged bath = new RspZoneFlagBathChanged(); bath.Flags = changed; SendToEditor(bath); } } void rsp_RspTerrainBrushChanged() { RspTerrainBrushChanged changed = new RspTerrainBrushChanged(); changed.Size = LastBrush.Size; SendToEditor(changed); } #endregion //--------------------------------------------------------------------------- #region Render private void pictureBox1_Paint(object sender, PaintEventArgs e) { refresh_Show(); world.setWindow(new RectangleF(0, 0, pictureBox1.Width, pictureBox1.Height)); world.render(e.Graphics); if (LastMode.Mode == MsgSetEditorMode.MODE_TERRAIN) { draw_mode_terrain(e); } else if (LastMode.Mode == MsgSetEditorMode.MODE_OBJECT) { draw_mode_object(e); } } private void draw_mode_terrain(PaintEventArgs e) { Point pp = pictureBox1.PointToClient(Control.MousePosition); Pen pen = new Pen(Color.White); float sizeW = world.worldToScreenSizeX(LastBrush.Size * world.CellW); float sizeH = world.worldToScreenSizeY(LastBrush.Size * world.CellH); if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Round) { e.Graphics.DrawEllipse(pen, pp.X - sizeW / 2, pp.Y - sizeH / 2, sizeW, sizeH); } else if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Rectangle) { e.Graphics.DrawRectangle(pen, pp.X - sizeW / 2, pp.Y - sizeH / 2, sizeW, sizeH); } if (pic_lastMouesPos != null) { float wx = world.screenToWorldX(pic_lastMouesPos.X); float wy = world.screenToWorldY(pic_lastMouesPos.Y); float ww = world.CellW; float wh = world.CellH; Brush brush = new SolidBrush(Color.FromArgb(0x20, Color.White)); world.drawInWorldSpace(e.Graphics, (g, bounds) => { if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Round) { world.ForEachTerrainRound(wx, wy, LastBrush.Size, (t, ix, iy) => { g.FillRectangle(brush, ix * ww, iy * wh, ww, wh); }); } else if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Rectangle) { world.ForEachTerrainRectangle(wx, wy, LastBrush.Size, LastBrush.Size, (t, ix, iy) => { g.FillRectangle(brush, ix * ww, iy * wh, ww, wh); }); } }); } float sy = pictureBox1.Height - 1; DrawStringLeftBottom(e.Graphics, "Page Up 扩大笔刷", true, ref sy); DrawStringLeftBottom(e.Graphics, "Page Down 缩小笔刷", true, ref sy); DrawStringLeftBottom(e.Graphics, "按住 Shift 抹去地块", CommonFroms.Keyboard.IsShiftDown, ref sy); } private void draw_mode_object(PaintEventArgs e) { if (pic_lastMouesPos != null) { float wx = world.screenToWorldX(pic_lastMouesPos.X); float wy = world.screenToWorldY(pic_lastMouesPos.Y); e.Graphics.DrawString(string.Format("Mouse=({0} , {1})", wx.ToString("#0.0"), wy.ToString("#0.0")), this.Font, tip_brush_h, 0, 1); } float sy = pictureBox1.Height - 1; if (world.SelectedObject != null) { DrawStringLeftBottom(e.Graphics, "按住 Shift 调整坐标", CommonFroms.Keyboard.IsShiftDown, ref sy); if (world.SelectedObject.IsDirectionality) DrawStringLeftBottom(e.Graphics, "按住 Ctrl 调整角度", CommonFroms.Keyboard.IsCtrlDown, ref sy); } if (ShowPoint) { DrawStringLeftBottom(e.Graphics, "按住 Ctrl 点击添加路点", CommonFroms.Keyboard.IsCtrlDown & !CommonFroms.Keyboard.IsAltDown, ref sy); DrawStringLeftBottom(e.Graphics, "按住 Ctrl+Alt 点击添加并连接路点", CommonFroms.Keyboard.IsCtrlDown & CommonFroms.Keyboard.IsAltDown, ref sy); DrawStringLeftBottom(e.Graphics, "按住 Alt 点击链接/解开路点", !CommonFroms.Keyboard.IsCtrlDown & CommonFroms.Keyboard.IsAltDown, ref sy); } } private Brush tip_brush_h = new SolidBrush(Color.White); private Brush tip_brush_t = new SolidBrush(Color.FromArgb(0xFF, 0xA0, 0xA0, 0xA0)); private void DrawStringLeftBottom(Graphics g, string text, bool enable, ref float sy) { SizeF size = g.MeasureString(text, this.Font); g.DrawString(text, this.Font, enable ? tip_brush_h : tip_brush_t, 0, sy - size.Height); sy -= size.Height + 1; } #endregion //--------------------------------------------------------------------------- #region Mouse private void PictureBox1_KeyDown(object sender, KeyEventArgs e) { pictureBox1.Focus(); pictureBox1.Refresh(); if (LastMode.Mode == MsgSetEditorMode.MODE_TERRAIN) { key_down_mode_terrain(e); } } private void PictureBox1_KeyUp(object sender, KeyEventArgs e) { pictureBox1.Focus(); pictureBox1.Refresh(); } private void key_down_mode_terrain(KeyEventArgs e) { if (e.KeyCode == Keys.PageUp) { LastBrush.Size++; LastBrush.Size = Math.Max(1, LastBrush.Size); rsp_RspTerrainBrushChanged(); } else if (e.KeyCode == Keys.PageDown) { LastBrush.Size--; LastBrush.Size = Math.Max(1, LastBrush.Size); rsp_RspTerrainBrushChanged(); } } private Vector2 pic_lastMouesDown; private Vector2 pic_lastMouesPos; private Vector2 pic_lastCameraPos; private EditorObject pic_lastPickObj; private Vector2 pic_lastPickObjOffset; private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { pictureBox1.Focus(); pic_lastMouesPos = new Vector2(e.X, e.Y); if (e.Button == System.Windows.Forms.MouseButtons.Right) { pic_lastMouesDown = new Vector2(e.X, e.Y); pic_lastCameraPos = new Vector2(world.CameraX, world.CameraY); } else if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (LastMode.Mode == MsgSetEditorMode.MODE_OBJECT) { float wx = world.screenToWorldX(e.X); float wy = world.screenToWorldY(e.Y); if (ShowPoint && CommonFroms.Keyboard.IsCtrlDown & CommonFroms.Keyboard.IsAltDown) { do_add_and_link_point(wx, wy); } else if (ShowPoint && CommonFroms.Keyboard.IsCtrlDown) { do_add_point(wx, wy); } else if (ShowPoint && CommonFroms.Keyboard.IsAltDown) { do_link_point(wx, wy); } else { pic_lastPickObj = world.PickObject(wx, wy); if (pic_lastPickObj != null) { pic_lastPickObjOffset = new Vector2( wx - pic_lastPickObj.X, wy - pic_lastPickObj.Y); } } } else if (LastMode.Mode == MsgSetEditorMode.MODE_TERRAIN) { mouse_fill_terrain(e); } } pictureBox1.Refresh(); } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { pic_lastMouesPos = new Vector2(e.X, e.Y); if (e.Button == System.Windows.Forms.MouseButtons.Right) { if (pic_lastMouesDown != null) { float x = pic_lastCameraPos.X + world.screenToWorldSizeX(pic_lastMouesDown.X - e.X); float y = pic_lastCameraPos.Y + world.screenToWorldSizeY(pic_lastMouesDown.Y - e.Y); world.setCamera(x, y); rsp_CameraChanged(); } } else if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (LastMode.Mode == MsgSetEditorMode.MODE_OBJECT) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (pic_lastPickObj != null) { float wx = world.screenToWorldX(e.X); float wy = world.screenToWorldY(e.Y); pic_lastPickObj.SetPos( wx - pic_lastPickObjOffset.X, wy - pic_lastPickObjOffset.Y); rsp_ObjectPositionChanged(pic_lastPickObj); } } } else if (LastMode.Mode == MsgSetEditorMode.MODE_TERRAIN) { mouse_fill_terrain(e); } } else { if (LastMode.Mode == MsgSetEditorMode.MODE_OBJECT) { if (CommonFroms.Keyboard.IsCtrlDown) { var selected = world.SelectedObject; if (selected != null) { float wx = world.screenToWorldX(e.X); float wy = world.screenToWorldY(e.Y); selected.Direction = (MathVector.getDegree(wx - selected.X, wy - selected.Y)); rsp_RspObjectDirectionChanged(selected); } } else if (CommonFroms.Keyboard.IsShiftDown) { var selected = world.SelectedObject; if (selected != null) { float wx = world.screenToWorldX(e.X); float wy = world.screenToWorldY(e.Y); selected.SetPos(wx, wy); rsp_ObjectPositionChanged(selected); } } } } pictureBox1.Refresh(); } private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { pic_lastMouesDown = null; pic_lastCameraPos = null; pic_lastPickObj = null; pic_lastPickObjOffset = null; rsp_FillTerrain(); pictureBox1.Refresh(); } private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { try { int d = CMath.getDirect(e.Delta); if (d > 0) { float newD = world.getCameraScale() * 1.1f; world.setCameraScale(newD, newD); rsp_CameraChanged(); } else if (d < 0) { float newD = world.getCameraScale() / 1.1f; world.setCameraScale(newD, newD); rsp_CameraChanged(); } } catch (Exception err) { Console.WriteLine(err.Message); } pictureBox1.Refresh(); } private void do_add_point(float wx, float wy) { var add = CallAddObjectData((t) => { t.X = wx; t.Y = wy; }); if (add != null) { world.PickObject(add.Name); } } private void do_link_point(float wx, float wy) { if (world.SelectedObject is EditorPoint) { var next = world.TryPickObject(wx, wy); if (next != null) { var selected = CallResetObjectData(world.SelectedObject.Name, (prev) => { if (next.Name != prev.Name) { if (prev.NextNames.Contains(next.Name)) { prev.NextNames.Remove(next.Name); } else { prev.NextNames.Add(next.Name); } } }); world.PickObject(next.Name); } } } private void do_add_and_link_point(float wx, float wy) { var prev = world.SelectedObject; var add = CallAddObjectData((t) => { t.X = wx; t.Y = wy; }); if (add != null) { if (prev is EditorPoint) { CallResetObjectData(prev.Name, (p) => { p.NextNames.Add(add.Name); }); } world.PickObject(add.Name); } } private void mouse_fill_terrain(MouseEventArgs e) { int value = LastBrush.ARGB; if (CommonFroms.Keyboard.IsShiftDown) { value = 0; } float wx = world.screenToWorldX(e.X); float wy = world.screenToWorldY(e.Y); if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Round) { world.FillTerrainRound(wx, wy, LastBrush.Size, value); } else if (LastBrush.Brush == MsgSetTerrainBrush.BrushType.Rectangle) { world.FillTerrainRectangle(wx, wy, LastBrush.Size, LastBrush.Size, value); } rsp_FillTerrain(); } #endregion //--------------------------------------------------------------------------- } }