• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FreeTrainの進化系を目指す


Commit MetaInfo

Revision33 (tree)
Time2015-03-29 00:04:48
Authorc477

Log Message

調査ツール実装、それに絡んで各種イベントハンドラなどの実装、関連クラスの再設計

Change Summary

Incremental Difference

--- trunk/plugins/system/plugin.xml (revision 32)
+++ trunk/plugins/system/plugin.xml (revision 33)
@@ -97,6 +97,7 @@
9797 <item mid="EXIT|EXIT" caption="終了(&amp;X)">ゲームを終了します。</item>
9898 </item>
9999 <item mid="VIEW" caption="表示(&amp;V)">
100+ <item mid="TOOL|INSPECTOR" caption="調査ツール"/>
100101 </item>
101102 <item mid="BUILD" caption="建設(&amp;B)">
102103 </item>
@@ -283,6 +284,17 @@
283284 <command type="ModalForm" menupath="FILE\GAME|NEWMAP" />
284285 </contribution>
285286
287+ <!--<contribution type="SubForm" id="InspectorTool">
288+ <name>調査ツール</name>
289+ <class name="nft.ui.core.InspectorTool" codebase=".UI"/>
290+ <options>permanent</options>
291+ </contribution>-->
292+ <contribution type="Command" id="C_InspectorTool">
293+ <name>調査ツール</name>
294+ <class name="nft.ui.core.InspectorTool" codebase=".UI"/>
295+ <command type="SubForm" menupath="VIEW\TOOL|INSPECTOR" />
296+ </contribution>
297+
286298 <contribution type="TerrainGenerator" id="FlatTerrainGenerator">
287299 <name>シンプル平坦マップ</name>
288300 <description>真っ平らな地形を生成します</description>
--- trunk/core/impl/game/TerrainPiecePair.cs (revision 32)
+++ trunk/core/impl/game/TerrainPiecePair.cs (revision 33)
@@ -189,5 +189,69 @@
189189 yield break;
190190 }
191191
192+ public ArrangedTerrainPieces GetTerrainPieces(InterCardinalDirection viewUpper) {
193+ ITerrainPiece p1,p2;
194+ TerrainPieceTemplate.TerrainPolygonSet T1,T2;
195+ if (revOrder[Direction.ToZeroBaseIndex(viewUpper)]) {
196+ p1 = P1;
197+ p2 = P2;
198+ } else {
199+ p2 = P1;
200+ p1 = P2;
201+ }
202+ T1 = p1.Template.GetPolygons(viewUpper);
203+ T2 = p2.Template.GetPolygons(viewUpper);
204+ ArrangedTerrainPieces set = new ArrangedTerrainPieces();
205+
206+ set.Pieces = new ITerrainPiece[] { p1, p2 };
207+ set.PolygonSets = new TerrainPieceTemplate.TerrainPolygonSet[] { T1, T2 };
208+ SetPieceForCliffPolygons(ref set, 0, T1);
209+ SetPieceForCliffPolygons(ref set, 1, T2);
210+ return set;
211+ }
212+
213+ protected void SetPieceForCliffPolygons(ref ArrangedTerrainPieces store, int index, TerrainPieceTemplate.TerrainPolygonSet tps) {
214+ ViewDirection8 diagSide = tps.Ground.DiagonalSide;
215+ if (diagSide == ViewDirection8.FRONT) {
216+ store.Index4DiagonalCliff = index;
217+ } else {
218+ if (diagSide != ViewDirection8.LEFT) {
219+ store.Index4LeftCliff = index;
220+ }
221+ if (diagSide != ViewDirection8.RIGHT) {
222+ store.Index4RightCliff = index;
223+ }
224+ }
225+ }
226+
227+ public class ArrangedTerrainPieces {
228+ public ITerrainPiece[] Pieces;
229+ public TerrainPieceTemplate.TerrainPolygonSet[] PolygonSets;
230+ public int Index4DiagonalCliff;
231+ public int Index4LeftCliff;
232+ public int Index4RightCliff;
233+
234+ #region shortcut properties
235+ public CliffPolygon CliffDiagonal {
236+ get { return PolygonSets[Index4DiagonalCliff].CliffDiagonal; }
237+ }
238+ public CliffPolygon CliffLeft {
239+ get { return PolygonSets[Index4LeftCliff].CliffLeft; }
240+ }
241+ public CliffPolygon CliffRight {
242+ get { return PolygonSets[Index4RightCliff].CliffRight; }
243+ }
244+
245+ public int BaseHeightDiagonal {
246+ get { return Pieces[Index4DiagonalCliff].BaseHeight; }
247+ }
248+ public int BaseHeightLeft{
249+ get { return Pieces[Index4LeftCliff].BaseHeight; }
250+ }
251+ public int BaseHeightRight {
252+ get { return Pieces[Index4RightCliff].BaseHeight; }
253+ }
254+ #endregion
255+ }
192256 }
193257 }
--- trunk/core/impl/game/GameImpl.cs (revision 32)
+++ trunk/core/impl/game/GameImpl.cs (revision 33)
@@ -14,12 +14,13 @@
1414 [Serializable]
1515 public class GameImpl : IGame
1616 {
17+ public event EventHandler Closing;
18+
1719 protected Calendar calender;
1820 protected Clock clock;
1921
2022 protected string name;
2123 protected TerrainMapImpl terrains;
22- protected IPointerHandler activeHandler;
2324 protected ViewCollection views;
2425 protected bool modified;
2526 protected bool closed;
@@ -60,7 +61,12 @@
6061
6162 public virtual void Close()
6263 {
63- closed = true;
64+ if (!closed) {
65+ closed = true;
66+ if (Closing != null) {
67+ Closing(this, new EventArgs());
68+ }
69+ }
6470 calender = null;
6571 clock = null;
6672 if (terrains != null) {
@@ -120,19 +126,6 @@
120126 set{ name = value; }
121127 }
122128
123- public IPointerHandler ActiveController {
124- get {
125- return activeHandler;
126- }
127- set {
128- if (activeHandler != null) {
129- activeHandler.OnDetach(this);
130- }
131- activeHandler = value;
132- activeHandler.OnAttach(this);
133- }
134- }
135-
136129 public ViewCollection Views {
137130 get {
138131 return views;
--- trunk/core/impl/view/SelectionInfo.cs (nonexistent)
+++ trunk/core/impl/view/SelectionInfo.cs (revision 33)
@@ -0,0 +1,42 @@
1+using nft.core.game;
2+using nft.core.geometry;
3+using nft.core.view;
4+using nft.framework.drawing;
5+using System;
6+using System.Collections.Generic;
7+using System.Drawing;
8+using System.Text;
9+using Geocon = nft.core.geometry.GeometricConstants;
10+
11+namespace nft.impl.view {
12+ public class SelectionInfo {
13+ public readonly IGame Game;
14+ public readonly SceneBuilder SceneBuilder;
15+ public readonly Point ScreenPosition; // position of mouse cursor.
16+
17+ public SelectionInfo(IGame game, SceneBuilder builder, Point screen) {
18+ this.Game = game;
19+ this.SceneBuilder = builder;
20+ this.ScreenPosition = screen;
21+ }
22+
23+ // Fields that indicates current selection --
24+ public PointF3D WorldPosition; // simple 2D/3D conversion of coordination.
25+ public Location Location; // in grid unit
26+ public Point Offset;
27+ public UInt32 HitTestValue;
28+ public ITerrainPiece TerrainPiece;
29+ public ITerrainPolygon Polygon;
30+ public object Object;
31+ // -- End of fields
32+
33+ public ISurface Surface {
34+ get { return SceneBuilder.surface; }
35+ }
36+
37+ public ITerrainMap TerrainMap {
38+ get { return SceneBuilder.game.TerrainMap; }
39+ }
40+
41+ }
42+}
--- trunk/core/impl/view/DrawIndexUtil.cs (revision 32)
+++ trunk/core/impl/view/DrawIndexUtil.cs (revision 33)
@@ -49,32 +49,37 @@
4949 }
5050
5151
52- internal static bool ResolveTerrain(SceneBuilder sb, Point mousePos, out ITerrainPolygon pol, out PointF3D p3dv) {
53- pol = null;
52+ internal static bool ResolveTerrain(ref SelectionInfo info) {
53+ Point mousePos = info.ScreenPosition;
5454 //mousePos.Y++;
5555 Debug.Write("ResolveTerrain: mouse=(" + mousePos.X + "," + mousePos.Y + ")");
56- p3dv = sb.surface.ToWorldPosition(mousePos);
57- UInt32 idx = sb.surface.HitTestAt(mousePos.X, mousePos.Y);
58- TerrainMapImpl map = sb.game.TerrainMap;
56+ PointF3D p3dv = info.Surface.ToWorldPosition(mousePos);
57+ UInt32 idx = info.Surface.HitTestAt(mousePos.X, mousePos.Y);
58+ info.HitTestValue = idx;
59+ TerrainMapImpl map = info.TerrainMap as TerrainMapImpl;
5960 if (AdjustPointForGround(ref p3dv, idx)) {
61+ info.WorldPosition = p3dv;
6062 int gx = (int)Math.Round(p3dv.X / Geocon.UnitWidthPixel);
6163 int gy = (int)Math.Round(p3dv.Y / Geocon.UnitWidthPixel);
64+ PointF3D p3d = new PointF3D(gx * Geocon.UnitWidthPixel, gy * Geocon.UnitWidthPixel, 0);
65+ Point rep = info.Surface.ToScreenPosition(p3d);
66+ int xoff = mousePos.X - rep.X;
67+ int yoff = mousePos.Y - rep.Y;
6268 Debug.Write(":Ground->(" + p3dv.X + "," + p3dv.Y + ") : grid[" + gx + "," + gy + "]");
63- Location l = sb.cdUtil.IsometricGridToLocation(gx, gy, 0);
64- foreach (ITerrainPiece p in map[l.X, l.Y, sb.upperDir]) {
65- TerrainPieceTemplate.TerrainPolygonSet tpset = p.Template.GetPolygons(sb.upperDir);
69+ Location l = info.SceneBuilder.cdUtil.IsometricGridToLocation(gx, gy, 0);
70+ InterCardinalDirection updir = info.SceneBuilder.upperDir;
71+ foreach (ITerrainPiece p in map[l.X, l.Y, updir]) {
72+ TerrainPieceTemplate.TerrainPolygonSet tpset = p.Template.GetPolygons(updir);
6673 if (tpset.Ground.IsVisible) {
67- PointF3D p3d = new PointF3D(gx * Geocon.UnitWidthPixel, gy * Geocon.UnitWidthPixel, 0);
68- Point rep = sb.surface.ToScreenPosition(p3d);
69- int xoff = mousePos.X - rep.X;
70- int yoff = mousePos.Y - rep.Y;
7174 int h1 = p.BaseHeight * Geocon.UnitHeightPixel;
72- yoff += h1;
73- //Debug.Write("!");
74- if (TerrainUtil.IsInnerPoint2D(tpset.Ground.GetVerticis(sb.scaler), new Point(xoff, yoff))) {
75+ Point offset = new Point(xoff, yoff+h1);
76+ if (TerrainUtil.IsInnerPoint2D(tpset.Ground.GetVerticis(info.SceneBuilder.scaler), offset)) {
7577 Debug.WriteLine("+(" + xoff + "," + yoff + ")");
76- pol = tpset.Ground;
77- sb.CreateMarker(gx, gy, SceneBuilder.TrMk_Ground);
78+ info.TerrainPiece = p;
79+ info.Polygon = tpset.Ground;
80+ info.Offset = offset;
81+ info.Location = new Location(l.X, l.Y, p.BaseHeight);
82+ info.SceneBuilder.CreateMarker(gx, gy, SceneBuilder.TrMk_Ground);
7883 break;
7984 //} else if (pol == null) {
8085 // pol = tpset.Ground;
@@ -82,32 +87,51 @@
8287 }
8388 }
8489 //Debug.WriteLineIf(pol == null, "WTF!?");
85- return pol != null;
90+ return info.Polygon != null;
8691 } else if (AdjustPointForCliff(ref p3dv, idx)) {
92+ info.WorldPosition = p3dv;
8793 int gx = (int)Math.Round(p3dv.X / Geocon.UnitWidthPixel);
8894 int gy = (int)Math.Round(p3dv.Y / Geocon.UnitWidthPixel);
95+ PointF3D p3d = new PointF3D(gx * Geocon.UnitWidthPixel, gy * Geocon.UnitWidthPixel, 0);
96+ Point rep = info.Surface.ToScreenPosition(p3d);
97+ int xoff = mousePos.X - rep.X;
98+ int yoff = mousePos.Y - rep.Y;
8999 Debug.Write(":Cliff->(" + p3dv.X + "," + p3dv.Y + ") : grid[" + gx + "," + gy + "]");
90- Location l = sb.cdUtil.IsometricGridToLocation(gx, gy, 0);
91- foreach (ITerrainPiece p in map[l.X, l.Y, sb.upperDir]) {
100+ Location l = info.SceneBuilder.cdUtil.IsometricGridToLocation(gx, gy, 0);
101+ InterCardinalDirection updir = info.SceneBuilder.upperDir;
102+ UInt32 testval = (idx & Mask_CliffPolygon_D);
103+ TerrainPiecePair pair = map[l.X, l.Y];
104+ if (pair != null) {
105+ TerrainPiecePair.ArrangedTerrainPieces atp = pair.GetTerrainPieces(updir);
92106 //if (p.BaseHeight < p3dv.Z) continue;
93- TerrainPieceTemplate.TerrainPolygonSet tpset = p.Template.GetPolygons(sb.upperDir);
94- UInt32 testval = (idx & Mask_CliffPolygon_D);
95107 if (testval == Mask_CliffPolygon_D) {
96108 Debug.WriteLine(":Diagonal");
97- pol = tpset.CliffDiagonal;
98- sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffDiag);
109+ info.Polygon = atp.CliffDiagonal;
110+ info.TerrainPiece = atp.Pieces[atp.Index4DiagonalCliff];
111+ info.Location = new Location(l.X, l.Y, info.TerrainPiece.BaseHeight);
112+ int h1 = info.TerrainPiece.BaseHeight * Geocon.UnitHeightPixel;
113+ info.Offset = new Point(xoff, yoff + h1);
114+ info.SceneBuilder.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffDiag);
99115 } else if (testval == Mask_CliffPolygon_R) {
100116 Debug.WriteLine(":Right");
101- pol = tpset.CliffRight;
102- sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffRight);
117+ info.Polygon = atp.CliffRight;
118+ info.TerrainPiece = atp.Pieces[atp.Index4RightCliff];
119+ info.Location = new Location(l.X, l.Y, info.TerrainPiece.BaseHeight);
120+ int h1 = info.TerrainPiece.BaseHeight * Geocon.UnitHeightPixel;
121+ info.Offset = new Point(xoff, yoff + h1);
122+ info.SceneBuilder.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffRight);
103123 } else {
104124 Debug.WriteLine(":Left");
105- pol = tpset.CliffLeft;
106- sb.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffLeft);
125+ info.Polygon = atp.CliffLeft;
126+ info.TerrainPiece = atp.Pieces[atp.Index4LeftCliff];
127+ info.Location = new Location(l.X, l.Y, info.TerrainPiece.BaseHeight);
128+ int h1 = info.TerrainPiece.BaseHeight * Geocon.UnitHeightPixel;
129+ info.Offset = new Point(xoff, yoff + h1);
130+ info.SceneBuilder.CreateMarker(gx, gy, SceneBuilder.TrMk_CliffLeft);
107131 }
132+ //Debug.WriteLineIf(pol == null, "WTF2!?");
133+ return info.TerrainPiece != null;
108134 }
109- //Debug.WriteLineIf(pol == null, "WTF2!?");
110- return pol != null;
111135 }
112136 //Debug.WriteLine("--");
113137 return false;
--- trunk/core/impl/view/GameViewPanel.cs (revision 32)
+++ trunk/core/impl/view/GameViewPanel.cs (revision 33)
@@ -27,15 +27,39 @@
2727 renderPanel.OnSurfacePrepared += new EventHandler(SurfaceReady);
2828 }
2929
30+ #region Internal event handlers
31+ protected PointerEventArgs MakeArg(MouseEventArgs e) {
32+ return new PointerEventArgs(e, builder.game, builder.surface);
33+ }
3034 void EventTarget_MouseMove(object sender, MouseEventArgs e) {
3135 if (prepared) {
36+ if (MouseCursorMove != null) MouseCursorMove(MakeArg(e));
3237 //UInt32 u = renderPanel.Surface.HitTestAt(e.X, e.Y);
33- object o = builder.GetObjectAt(e.Location);
38+ //object o = builder.GetObjectAt(e.Location);
3439 renderPanel.Refresh();
3540 }
3641 }
3742
43+ void EventTarget_MouseDown(object sender, MouseEventArgs e) {
44+ if (MouseButtonDown != null) MouseButtonDown(MakeArg(e));
45+ }
46+ void EventTarget_MouseUp(object sender, MouseEventArgs e) {
47+ if (MouseButtonUp != null) MouseButtonUp(MakeArg(e));
48+ }
49+ void Parent_LostFocus(object sender, EventArgs e) {
50+ if (Activated != null) Activated(new ViewEventArgs(this));
51+ }
52+
53+ void Parent_GotFocus(object sender, EventArgs e) {
54+ // Do nothing
55+ }
56+ #endregion
57+
3858 #region IView implementations
59+ public ISurface Surface {
60+ get { return renderPanel.Surface; }
61+ }
62+
3963 public SceneBuilder SceneBuilder {
4064 get { return builder; }
4165 }
@@ -55,6 +79,10 @@
5579
5680 public event ViewEventHandler OnClose;
5781 public event ViewQueryEventHandler QueryClose;
82+ public event ViewEventHandler Activated;
83+ public event PointerEventHandler MouseCursorMove;
84+ public event PointerEventHandler MouseButtonDown;
85+ public event PointerEventHandler MouseButtonUp;
5886 #endregion
5987
6088 void OnTouchPanelScroll(object sender, ScrollEventArgs e) {
@@ -73,7 +101,11 @@
73101 Size szu = new Size(Geocon.UnitWidthPixel, Geocon.HalfOf_UnitWidthPixel);
74102 Size szc = builder.ContentSize;
75103 InitScroll(szc, szu);
76- renderPanel.EventTarget.MouseMove += new MouseEventHandler(EventTarget_MouseMove);
104+ renderPanel.EventTarget.MouseMove += EventTarget_MouseMove;
105+ renderPanel.EventTarget.MouseDown += EventTarget_MouseDown;
106+ renderPanel.EventTarget.MouseUp += EventTarget_MouseUp;
107+ Parent.GotFocus += Parent_GotFocus;
108+ Parent.LostFocus += Parent_LostFocus;
77109 SetupCloseConfirmation();
78110 this.ResumeLayout(false);
79111 }
@@ -220,6 +252,7 @@
220252 }
221253 #endregion
222254
255+
223256 }
224257
225258 /// <summary>
--- trunk/core/impl/view/SceneBuilder.cs (revision 32)
+++ trunk/core/impl/view/SceneBuilder.cs (revision 33)
@@ -103,7 +103,6 @@
103103 }
104104
105105 Stopwatch watch0 = new Stopwatch();
106- int xxx = 0;
107106 public IEnumerator<I3DObject> GetEnumerator() {
108107 InterCardinalDirection dir = upperDir;
109108 TerrainMapImpl map = game.TerrainMap;
@@ -209,6 +208,84 @@
209208 Debug.WriteLine(string.Format("time={0}ms", watch0.ElapsedMilliseconds));
210209 }
211210
211+ public IEnumerable<I3DObject> GetTerrainsAt(int gridX, int gridY) {
212+ // 概ね GetEnumerator() のループ内と同じだが、崖のチェックをしない(必ず描画)
213+ InterCardinalDirection dir = UpperDirection;
214+ TerrainMapImpl map = game.TerrainMap;
215+ Size3D sz = map.Size;
216+ // terrain assembl loop
217+
218+ Point3DV pv = new Point3DV(gridX * Geocon.UnitWidthPixel, gridY * Geocon.UnitWidthPixel, 0);
219+ Location l = cdUtil.IsometricGridToLocation(gridX, gridY, 0);
220+ int x = l.X;
221+ int y = l.Y;
222+ if (x < 0 || y < 0 || x >= sz.sx || y >= sz.sy) {
223+ // out of map
224+ yield break;
225+ }
226+ TerrainPiecePair pair = map[x, y];
227+ if (pair == null) {
228+ yield break;
229+ }
230+ TerrainPiecePair.ArrangedTerrainPieces atp = pair.GetTerrainPieces(UpperDirection);
231+ ITerrainPlate plate;
232+ int hgap = 0;
233+ for (int i = 0; i < atp.Pieces.Length; i++) {
234+ ITerrainPiece p = atp.Pieces[i];
235+ TerrainPieceTemplate.TerrainPolygonSet tpset = atp.PolygonSets[i];
236+ pv.VZ = p.BaseHeight * Geocon.UnitHeightPixel;
237+ if (tpset.Ground.IsVisible) {
238+ plate = apparents.DefaultLandTexture.Get(l, tpset.Ground, pv);
239+ plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ);
240+ yield return plate;
241+ }
242+ }
243+ CliffPolygon cp;
244+ // Process Left Cliff
245+ cp = atp.CliffLeft;
246+ hgap = atp.BaseHeightLeft * Geocon.UnitHeightPixel;
247+ pv.VZ = 0;
248+ if (cp == null && hgap > 0) {
249+ cp = CliffPolygon.LeftUnitCliff;
250+ hgap -= Geocon.TerrainStepHeightInUnit;
251+ pv.VZ -= Geocon.TerrainStepHeightInUnit;
252+ }
253+ if (cp != null) {
254+ plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv);
255+ plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ);
256+ yield return plate;
257+ }
258+ // Process Right Cliff
259+ cp = atp.CliffRight;
260+ hgap = atp.BaseHeightRight * Geocon.UnitHeightPixel;
261+ pv.VZ = 0;
262+ if (cp == null && hgap > 0) {
263+ cp = CliffPolygon.RightUnitCliff;
264+ hgap -= Geocon.TerrainStepHeightInUnit;
265+ pv.VZ -= Geocon.TerrainStepHeightInUnit;
266+ }
267+ if (cp != null) {
268+ plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv);
269+ plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ);
270+ yield return plate;
271+ }
272+ // Process Diagonal Cliff
273+ cp = atp.CliffDiagonal;
274+ hgap = atp.BaseHeightDiagonal * Geocon.UnitHeightPixel;
275+ pv.VZ = 0;
276+ if (cp == null && hgap > 0) {
277+ cp = CliffPolygon.DiagonalUnitCliff;
278+ hgap -= Geocon.TerrainStepHeightInUnit;
279+ pv.VZ -= Geocon.TerrainStepHeightInUnit;
280+ }
281+ if (cp != null) {
282+ plate = apparents.DefaultCliffTexture.Get(cp, hgap, pv);
283+ plate.Location = new PointF3D(pv.VX, pv.VY, pv.VZ);
284+ yield return plate;
285+ }
286+
287+ }
288+
212289 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
213290 return GetEnumerator(); //???
214291 }
@@ -280,13 +357,14 @@
280357 return new Point(isx - d, isy - d);
281358 }
282359
283- public object GetObjectAt(Point spos) {
360+ public SelectionInfo GetObjectAt(Point spos) {
284361 ITerrainPolygon pol;
285362 PointF3D p3dv;
286363 marker0 = null;
287- if (DrawIndexUtil.ResolveTerrain(this, spos, out pol, out p3dv)) {
364+ SelectionInfo info = new SelectionInfo(game, this, spos);
365+ if (DrawIndexUtil.ResolveTerrain(ref info)) {
288366
289- return pol;
367+ return info;
290368 }
291369 return null;
292370 }
@@ -427,5 +505,6 @@
427505 return cliff;
428506 }
429507
508+
430509 }
431510 }
--- trunk/core/contributions/game/CtbGameTool.cs (nonexistent)
+++ trunk/core/contributions/game/CtbGameTool.cs (revision 33)
@@ -0,0 +1,28 @@
1+using System;
2+using System.Collections;
3+using System.Diagnostics;
4+using System.Drawing;
5+using System.Reflection;
6+using System.Xml;
7+using nft.framework;
8+using nft.framework.plugin;
9+using nft.core.game;
10+using nft.util;
11+using System.Windows.Forms;
12+using nft.contributions.ui;
13+
14+namespace nft.contributions.game
15+{
16+ /// <summary>
17+ /// CommandEntityContributuion の概要の説明です。
18+ /// </summary>
19+ public class CtbGameTool : CtbSubform
20+ {
21+ public CtbGameTool(Plugin p, ParamsReader e)
22+ : base(p, e)
23+ {
24+
25+ }
26+ }
27+
28+}
--- trunk/core/core/game/IGame.cs (revision 32)
+++ trunk/core/core/game/IGame.cs (revision 33)
@@ -15,13 +15,15 @@
1515 void Start();
1616 void Close();
1717 bool Closed {get;}
18- // if false, no need to save the game.
18+
19+ event EventHandler Closing;
20+ // if false, no need to save the game.
1921 bool Modified {get;}
2022 Clock Clock {get;}
2123 IClimateController ClimateController {get;}
2224 string Name {get;set;}
23- IPointerHandler ActiveController {get; set;}
24- //World world {get;}
25+
26+ //World world {get;}
2527 ViewCollection Views {get;}
2628 //Return if prepare for close the game.
2729 bool ConfirmClose();
--- trunk/core/core/game/GameManager.cs (revision 32)
+++ trunk/core/core/game/GameManager.cs (revision 33)
@@ -32,19 +32,25 @@
3232 protected MainFrame theFrame;
3333 protected IGameMode _curMode;
3434 protected IGame _curGame;
35+ protected ToolCollection tools;
3536 /// <summary>
3637 /// Fired after a new world is loaded/created.
3738 /// </summary>
38- public event EventHandler OnNewGame;
39+ public event GameEventHandler OnGameStart;
40+ public event GameEventHandler OnGameClose;
3941
4042 protected GameManager(MainFrame mainFrame)
4143 {
4244 this.theFrame = mainFrame;
45+ this.tools = new ToolCollection(this);
4346 theFrame.ActiveViewChanged += new EventHandler<EventArgs>(theFrame_ActiveViewChanged);
4447 }
4548
4649 public IGameMode CurrentMode { get{ return _curMode; } }
4750 public IGame CurrentGame { get{ return _curGame; } }
51+
52+ public ToolCollection Tools { get { return tools; } }
53+
4854 [Obsolete]
4955 public void SetGame(IGame newgame, IGameMode mode, bool prompt){}
5056
@@ -54,19 +60,18 @@
5460
5561 public virtual void NewGameFromMap(string name, ITerrainMap map, Calendar cal, IGameMode mode, bool prompt)
5662 {
57- IGame newgame = CreateGame(name, map, cal);
5863 if(_curGame != null)
5964 {
60- if( prompt )
61- if( !ConfirmCloseGame() ) return;
62- else
63- _curGame.Close();
65+ if (prompt) {
66+ if (!ConfirmCloseGame()) return;
67+ } else {
68+ DetachCurrentGame();
69+ }
70+
6471 }
65- _curGame = newgame;
72+ IGame newgame = CreateGame(name, map, cal);
73+ AttachCurrentGame(newgame);
6674 _curMode = mode;
67- //theFrame.SetSubTitle( );
68- _curGame.Views.OpenNew();
69- _curGame.Start();
7075 }
7176
7277 protected virtual IGame CreateGame(string name, ITerrainMap map, Calendar cal) {
@@ -74,6 +79,32 @@
7479 return new GameImpl(name, map, cal);
7580 }
7681
82+ protected virtual void AttachCurrentGame(IGame gm) {
83+ _curGame = gm;
84+ _curGame.Closing += Game_Closing;
85+ _curGame.Start();
86+ if (OnGameStart != null) {
87+ OnGameStart(new GameEventArgs(_curGame));
88+ }
89+ _curGame.Views.OpenNew();
90+ }
91+
92+ void Game_Closing(object sender, EventArgs e) {
93+ if (_curGame == sender) {
94+ DetachCurrentGame();
95+ }
96+ }
97+ protected virtual void DetachCurrentGame() {
98+ if (!_curGame.Closed) {
99+ _curGame.Closing -= Game_Closing;
100+ _curGame.Close();
101+ }
102+ if (OnGameClose != null) {
103+ OnGameClose(new GameEventArgs(_curGame));
104+ }
105+ _curGame = null;
106+ }
107+
77108 public event EventHandler ActiveViewChanged;
78109
79110 /// 使われてない.
--- trunk/core/core/game/ViewCollection.cs (revision 32)
+++ trunk/core/core/game/ViewCollection.cs (revision 33)
@@ -13,14 +13,17 @@
1313 return GlobalModules.GetModule(typeof(IGameViewFactory)) as IGameViewFactory;
1414 }
1515 }
16-
16+
17+
1718 protected List<IView> views;
1819 protected IGame game;
1920 protected IView current;
21+ protected IEnumerable<IPointerHandler> awakeTools;
2022
2123 public ViewCollection(IGame _game) {
2224 game = _game;
2325 views = new List<IView>();
26+ awakeTools = new ToolEnumerator();
2427 }
2528
2629 public IGame Game {
@@ -88,16 +91,42 @@
8891 }
8992
9093 protected virtual IView CreateView() {
91- IView v = ViewFactory.Create(game, Location.UNPLACED);
92- v.OnClose += new ViewEventHandler(OnViewClose);
93- v.QueryClose += new ViewQueryEventHandler(QueryViewClose);
94+ IView v = ViewFactory.Create(game, Location.UNPLACED);
95+ v.MouseCursorMove += ViewMouseMove;
96+ v.MouseButtonDown += ViewMouseBtnDown;
97+ v.MouseButtonUp += ViewMouseBtnUp;
98+ v.Activated += ViewActivated;
99+ v.OnClose += OnViewClose;
100+ v.QueryClose += QueryViewClose;
94101 return v;
95102 }
96103
104+ void ViewActivated(ViewEventArgs ea) {
105+ SetActive(ea.View);
106+ }
107+
108+ void ViewMouseBtnUp(PointerEventArgs pe) {
109+ foreach (IPointerHandler h in awakeTools) {
110+ h.OnMouseButtonUp(pe);
111+ }
112+ }
113+
114+ void ViewMouseBtnDown(PointerEventArgs pe) {
115+ foreach (IPointerHandler h in awakeTools) {
116+ h.OnMouseButtonDown(pe);
117+ }
118+ }
119+
120+ void ViewMouseMove(PointerEventArgs pe) {
121+ foreach (IPointerHandler h in awakeTools) {
122+ h.OnMouseMove(pe);
123+ }
124+ }
125+
97126 protected virtual void OnViewClose(ViewEventArgs ea) {
98127 IView v = ea.View;
99- v.OnClose -= new ViewEventHandler(OnViewClose);
100- v.QueryClose -= new ViewQueryEventHandler(OnViewClose);
128+ v.OnClose -= OnViewClose;
129+ v.QueryClose -= OnViewClose;
101130 if (PrimaryView == v && !game.Closed) {
102131 game.Close();
103132 }
@@ -123,5 +152,16 @@
123152 return GetEnumerator();
124153 }
125154 #endregion
155+
156+ class ToolEnumerator : IEnumerable<IPointerHandler> {
157+
158+ public IEnumerator<IPointerHandler> GetEnumerator() {
159+ return GameManager.theInstance.Tools.EnumAwakeTools();
160+ }
161+
162+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
163+ return GetEnumerator();
164+ }
165+ }
126166 }
127167 }
--- trunk/core/core/game/GameEventHandler.cs (nonexistent)
+++ trunk/core/core/game/GameEventHandler.cs (revision 33)
@@ -0,0 +1,15 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+
5+namespace nft.core.game {
6+ public delegate void GameEventHandler(GameEventArgs args);
7+
8+ public class GameEventArgs : EventArgs{
9+ public readonly IGame Game;
10+ public GameEventArgs(IGame game) {
11+ this.Game = game;
12+ }
13+ }
14+
15+}
--- trunk/core/core/game/ToolCollection.cs (nonexistent)
+++ trunk/core/core/game/ToolCollection.cs (revision 33)
@@ -0,0 +1,106 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Text;
4+using nft.core.view;
5+using nft.core.geometry;
6+using nft.framework;
7+using System.Windows.Forms;
8+
9+namespace nft.core.game {
10+ public class ToolCollection : IEnumerable<IPointerHandler>{
11+
12+ protected List<IPointerHandler> modelesses;
13+ protected List<IPointerHandler> modals;
14+ protected IPointerHandler current;
15+ protected GameManager manager;
16+
17+ public ToolCollection(GameManager gm) {
18+ manager = gm;
19+ modals = new List<IPointerHandler>();
20+ modelesses = new List<IPointerHandler>();
21+ current = null;
22+ manager.OnGameStart += ManagerOnGameStart;
23+ manager.OnGameClose += ManagerOnGameClose;
24+ }
25+
26+ protected virtual void ManagerOnGameStart(GameEventArgs args) {
27+ IGame g = args.Game;
28+ foreach (IPointerHandler h in this) {
29+ h.OnAttach(g);
30+ }
31+ }
32+
33+ protected virtual void ManagerOnGameClose(GameEventArgs args) {
34+ IGame g = args.Game;
35+ foreach (IPointerHandler h in this) {
36+ h.OnDetach(g);
37+ }
38+ }
39+
40+ public virtual IPointerHandler ActiveTool {
41+ get {
42+ return current;
43+ }
44+ set {
45+ if (value != null && modals.Contains(value)) {
46+ current = value;
47+ } else {
48+ current = null;
49+ }
50+ }
51+ }
52+
53+ public void Add(IPointerHandler h) {
54+ this.Add(h, true);
55+ }
56+
57+ public void Add(IPointerHandler h, bool modal) {
58+ if (modal) {
59+ modals.Add(h);
60+ } else {
61+ modelesses.Add(h);
62+ }
63+ }
64+
65+ public void Remove(IPointerHandler h) {
66+ this.Remove(h, true);
67+ }
68+
69+ public void Remove(IPointerHandler h, bool modal) {
70+ if (modal) {
71+ modals.Remove(h);
72+ } else {
73+ modelesses.Remove(h);
74+ }
75+ }
76+
77+ public IList<IPointerHandler> ModalTools {
78+ get { return new List<IPointerHandler>(modals); }
79+ }
80+
81+ public IList<IPointerHandler> ModelessTools {
82+ get { return new List<IPointerHandler>(modelesses); }
83+ }
84+
85+ public IEnumerator<IPointerHandler> EnumAwakeTools() {
86+ if (current != null) {
87+ yield return current;
88+ }
89+ foreach (IPointerHandler h in modelesses) yield return h;
90+ }
91+
92+
93+ #region IEnumerable implementation
94+ public IEnumerator<IPointerHandler> GetEnumerator()
95+ {
96+ foreach (IPointerHandler h in modals) yield return h;
97+ foreach (IPointerHandler h in modelesses) yield return h;
98+ }
99+
100+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
101+ {
102+ return GetEnumerator();
103+ }
104+ #endregion
105+ }
106+}
--- trunk/core/core/game/PointerEventArgs.cs (revision 32)
+++ trunk/core/core/game/PointerEventArgs.cs (revision 33)
@@ -10,7 +10,8 @@
1010 protected IGame game;
1111 protected ISurface surface;
1212
13- public PointerEventArgs(IGame gm, ISurface surf) {
13+ public PointerEventArgs(MouseEventArgs org, IGame gm, ISurface surf) {
14+ this.eventOrg = org;
1415 this.game = gm;
1516 this.surface = surf;
1617 }
--- trunk/core/core/view/IView.cs (revision 32)
+++ trunk/core/core/view/IView.cs (revision 33)
@@ -3,14 +3,25 @@
33 using System.Text;
44 using nft.impl.view;
55 using nft.core.geometry;
6+using nft.core.game;
7+using nft.framework.drawing;
68
79 namespace nft.core.view {
810 public delegate void ViewEventHandler(ViewEventArgs ea);
911 public delegate void ViewQueryEventHandler(ViewQueryEventArgs ea);
12+ public delegate void PointerEventHandler(PointerEventArgs pe);
1013 public interface IView {
1114 event ViewEventHandler OnClose;
1215 event ViewQueryEventHandler QueryClose;
16+ event ViewEventHandler Activated;
17+ event PointerEventHandler MouseCursorMove;
18+ event PointerEventHandler MouseButtonDown;
19+ event PointerEventHandler MouseButtonUp;
1320
21+ ISurface Surface {
22+ get;
23+ }
24+
1425 SceneBuilder SceneBuilder {
1526 get;
1627 }
--- trunk/framework/nftfw.resource.xml (revision 32)
+++ trunk/framework/nftfw.resource.xml (revision 33)
@@ -3,9 +3,9 @@
33 <properties name="framework">
44 <properties name="Directories">
55 <property name="Directory '{0}' is not exist. Do you want to create?">{0}は存在しません。
6- 作成しますか?</property>
6+作成しますか?</property>
77 <property name="Failed to create a directory '{0}'. Use default path instead.">{0}は作成できませんでした。
8- 標準の設定を使用します。</property>
8+標準の設定を使用します。</property>
99 </properties>
1010 <properties name="PluginListDialog">
1111 <property name="Uncheck to forbid cpu using this plug-in.">コンピューターに使わせたくないプラグインは、
@@ -13,36 +13,31 @@
1313 <property name="This contribution cannot invalidate.">このコントリビューションは無効化できません。</property>
1414 </properties>
1515 <properties name="nft.framework.plugin">
16- <property name="Too many plug-in load errors! Check out remaining errors in the 'Plug-in List'.">
17- プラグインロードエラーが多すぎます。以降のエラーは省略します。
18- エラーの発生したプラグインを確認するには、プラグイン一覧をご覧下さい。
16+ <property name="Too many plug-in load errors! Check out remaining errors in the 'Plug-in List'.">プラグインロードエラーが多すぎます。以降のエラーは省略します。
17+エラーの発生したプラグインを確認するには、プラグイン一覧をご覧下さい。
1918 </property>
20- <property name="Dependent plug-in:{1} (required for the plug-in:{0}) is not found.">
21- プラグイン{0}に必要な
22- プラグイン{1}が見つかりません。
19+ <property name="Dependent plug-in:{1} (required for the plug-in:{0}) is not found.">プラグイン{0}に必要な
20+プラグイン{1}が見つかりません。
2321 </property>
24- <property name="Failed to load contribution[{1}] (ID={2}) from the file '{0}'.">
25- ファイル{0}
26- からのコントリビューション[{1}]のロードに失敗しました。
27- ID={2}
22+ <property name="Failed to load contribution[{1}] (ID={2}) from the file '{0}'.">ファイル {0}
23+からのコントリビューション[{1}]のロードに失敗しました。
24+ ID={2}
2825 </property>
2926 <property name="Failed to load plug-in:{0}.">プラグイン{0}がロードできませんでした。</property>
30- <property name="Failed to initialize contribution[{1}] in the plug-in:{0}.">
31- プラグイン{0}内のコントリビューション[{1}]が初期化できませんでした。
32- ID={2}
27+ <property name="Failed to initialize contribution[{1}] in the plug-in:{0}.">プラグイン{0}内のコントリビューション[{1}]が初期化できませんでした。
28+ ID={2}
3329 </property>
34- <property name="Failed to create CommandEntity[type={0}, class={1}, method={2}].">
35- コマンドコントリビューションを初期化できません。
36- Type={0}
37- Class={1}
38- Method={2}
30+ <property name="Failed to create CommandEntity[type={0}, class={1}, method={2}].">コマンドコントリビューションを初期化できません。
31+ Type={0}
32+ Class={1}
33+ Method={2}
3934 </property>
4035 <property name="An attribute '{1}' is required for the node '{0}'.">XMLノード[{0}]には[{1}]属性が必要です。
41- ソース:{2}</property>
36+ ソース:{2}</property>
4237 <property name="Failed to create an instance of the class '{0}'.">指定されたクラス[{0}]のインスタンス作成に失敗しました。
43- ソース:{1}</property>
38+ ソース:{1}</property>
4439 <property name="Cannot cast the class'{0}' to the class'{1}'.">クラス[{0}]を[{1}]にキャストできません。
45- ソース:{2}</property>
40+ ソース:{2}</property>
4641 </properties>
4742 <properties name="GlobalModules">
4843 <property name="ERROR while loading a core module.">コア・モジュール読み込みエラー</property>
--- trunk/framework/framework/plugin/PluginUtil.cs (revision 32)
+++ trunk/framework/framework/plugin/PluginUtil.cs (revision 33)
@@ -98,12 +98,14 @@
9898 public static Type loadTypeFromManifest( ParamsReader e ) {
9999 string typeName = e["name"].InnerText;
100100 Assembly a;
101+ string s;
101102 ParamsReader cb = e["codebase"];
102103 if( cb.IsNull ) {
103104 // load the class from the FreeTrain.Main.dll
104105 a = Assembly.GetExecutingAssembly();
106+ s = a.ManifestModule.Name;
105107 } else {
106- string s = cb.InnerText;
108+ s = cb.InnerText;
107109 // if start with '.', it's abbreviation of nft.XXX.dll
108110 // at the application base directory.
109111 if(s.StartsWith("."))
@@ -117,7 +119,16 @@
117119 }
118120 PluginSerializationBinder.registerAssembly(a);
119121 //Debug.Assert(typeName != null);
120- return a.GetType(typeName,true);
122+ try
123+ {
124+ return a.GetType(typeName, true);
125+ }
126+ catch (TypeLoadException te)
127+ {
128+ string msg = string.Format("[{1}]にクラス名='{0}'が見つかりませんでした。表記を確認してください。", typeName, s);
129+ Debug.WriteLine(msg);
130+ throw new FormatException(msg, te);
131+ }
121132 }
122133
123134 public static Type loadTypeFromManifest(ParamsReader e, Type required) {
--- trunk/framework/framework/I18n.cs (revision 32)
+++ trunk/framework/framework/I18n.cs (revision 33)
@@ -56,7 +56,7 @@
5656 /// <returns></returns>
5757 public static string F(string name, params object[] args) {
5858 string ret = _T1(name, ToGroupCandidates(1), true);
59- return String.Format(ret,ToString(args));
59+ return String.Format(ret,args);
6060 }
6161
6262 /// <summary>
--- trunk/framework/ui/command/SubformCommand.cs (revision 32)
+++ trunk/framework/ui/command/SubformCommand.cs (revision 33)
@@ -6,30 +6,14 @@
66 using WeifenLuo.WinFormsUI.Docking;
77 using nft.ui.mainframe;
88 using nft.framework.plugin;
9+using nft.ui.docking;
910
1011 namespace nft.ui.command {
1112 /// <summary>
1213 ///
1314 /// </summary>
14- public class SubformCommand : ICommandEntity_Old {
15- static SubformCommand() {
16- ((MainFrame)Main.mainFrame).DockingManager.RegisterResolver(ResolveDockContent);
17- }
15+ public class SubformCommand : ICommandEntity_Old, IDockContentFactory {
1816
19- public static DockContent ResolveDockContent(string persist) {
20- int n = persist.IndexOf(CtbSubform.SepalatorPersist);
21- string id = persist.Substring(0, n);
22- string nam = persist.Substring(n + CtbSubform.SepalatorPersist.Length);
23- CtbCommandEntity ctb = PluginManager.theInstance.GetContribution(id) as CtbCommandEntity;
24- if (ctb != null) {
25- SubformCommand sc = ctb.CommandEntity as SubformCommand;
26- if (sc != null) {
27- return sc.innerCtb.GetContent(nam, true).Parent as DockContent;
28- }
29- }
30- return null;
31- }
32-
3317 readonly CtbSubform innerCtb;
3418
3519 public SubformCommand(ParamsReader e) {
@@ -39,5 +23,9 @@
3923 public void CommandExecuted(CommandUI_Old cmdUI, object sender) {
4024 innerCtb.Show("");
4125 }
26+
27+ public DockContent CreateDockContent(string subkey) {
28+ return innerCtb.GetContent(subkey, true).Parent as DockContent;
29+ }
4230 }
4331 }
--- trunk/framework/ui/docking/DockingManagerEx.cs (revision 32)
+++ trunk/framework/ui/docking/DockingManagerEx.cs (revision 33)
@@ -26,6 +26,8 @@
2626 resolvers = new List<ContentsResolver>();
2727 DockPanelCustomizer.SetupFactories(dockPanel);
2828 deserializeDockContent = new DeserializeDockContent(GetContentFromPersistString);
29+ // Regsiter default resolver which find from contributions.
30+ RegisterResolver(new ContentsResolver(DockContentContributionResolver.ResolveDockContent));
2931 }
3032
3133 protected static String LayoutFilePath {
@@ -33,7 +35,7 @@
3335 }
3436
3537 public void RegisterResolver(ContentsResolver cr) {
36- resolvers.Add(cr);
38+ resolvers.Insert(0,cr); // latest order
3739 }
3840
3941 public void SaveLayout(){
@@ -55,7 +57,7 @@
5557 }
5658
5759 public void LoadLayout() {
58- dockPanel.LoadFromXml(LayoutFilePath, deserializeDockContent);
60+ dockPanel.LoadFromXml(LayoutFilePath, deserializeDockContent);
5961 }
6062
6163 internal protected DockPanel DockPanel { get { return dockPanel; } }
--- trunk/framework/ui/docking/SubformHolder.cs (revision 32)
+++ trunk/framework/ui/docking/SubformHolder.cs (revision 33)
@@ -20,6 +20,14 @@
2020 public enum StyleOption : int { Default = 0, NoShrink = 1, NoClose = 2, Tempolaly = 4, NoSaveLayout = 8 }
2121
2222 public abstract class SubformHolder {
23+ protected static List<SubformHolder> all_holders = new List<SubformHolder>();
24+
25+ public static IList<SubformHolder> LiveHolders {
26+ get {
27+ return all_holders;
28+ }
29+ }
30+
2331 /// <summary> Fired when the content is closed by the user. </summary>
2432 public event EventHandler OnHidden;
2533 /// <summary> Fired when the content is shown by the user.</summary>
@@ -114,6 +122,7 @@
114122 }
115123
116124 void cmpDocking_Disposed(object sender, EventArgs e) {
125+ all_holders.Remove(this);
117126 if (OnDisposed != null) OnDisposed(this, e);
118127 content = null;
119128 cmpDocking = null;
@@ -133,6 +142,9 @@
133142 setupDockComponent();
134143 SetContent();
135144 }
145+ if (!all_holders.Contains(this)) {
146+ all_holders.Add(this);
147+ }
136148 cmpDocking.Show(getDockPanel());
137149 /* 何で必要だったか忘れた…
138150 if (cmpDocking.DockState == DockState.Hidden || cmpDocking.DockState == DockState.Unknown) {
--- trunk/framework/ui/docking/IDockContentFactory.cs (nonexistent)
+++ trunk/framework/ui/docking/IDockContentFactory.cs (revision 33)
@@ -0,0 +1,27 @@
1+using nft.framework.plugin;
2+using System;
3+using System.Collections.Generic;
4+using System.Text;
5+using WeifenLuo.WinFormsUI.Docking;
6+
7+namespace nft.ui.docking {
8+ public interface IDockContentFactory {
9+ DockContent CreateDockContent(string subkey);
10+ }
11+
12+ public class DockContentContributionResolver {
13+ public static readonly string SepalatorPersist = "::";
14+ public static DockContent ResolveDockContent(string persist) {
15+ int n = persist.IndexOf(SepalatorPersist);
16+ string id = persist.Substring(0, n);
17+ string nam = persist.Substring(n + SepalatorPersist.Length);
18+ Contribution ctb = PluginManager.theInstance.GetContribution(id);
19+ IDockContentFactory fct = ctb as IDockContentFactory;
20+ if (fct != null) {
21+ return fct.CreateDockContent(nam);
22+ } else {
23+ return null;
24+ }
25+ }
26+ }
27+}
--- trunk/framework/ui/form/IxControl.cs (revision 32)
+++ trunk/framework/ui/form/IxControl.cs (revision 33)
@@ -11,10 +11,20 @@
1111 bool Visible { get; set; }
1212 }
1313
14- public interface IxControl<T> : IxControl
14+ public delegate bool Validator<T>(T testVal, T prevVal);
15+
16+ public interface IxInput<T> : IxControl
1517 {
1618 T Value { get; set; }
1719 bool IsValid(); // return true if the value is valid.
20+ Validator<T> validator { get; set; }
1821 event XFormEvent ValueChanged;
1922 }
23+
24+ public interface IxControlGroup : IxControl
25+ {
26+ IxControl this[string name] {get;}
27+ IxInput<T> Get<T>(string name);
28+ IEnumerator<IxControl> EnumChildren();
29+ }
2030 }
--- trunk/framework/ui/form/IxForm.cs (revision 32)
+++ trunk/framework/ui/form/IxForm.cs (revision 33)
@@ -6,12 +6,8 @@
66 {
77 public delegate bool XFormEvent(IxForm sender, IxControl related);
88
9- public interface IxForm
9+ public interface IxForm : IxControlGroup
1010 {
11- string Name { get; }
12- IxControl Find(string name);
13- IEnumerator<IxControl> EnumControls();
14- bool Visible { get; set; }
1511
1612 event XFormEvent OnOpen;
1713 event XFormEvent OnClose;
--- trunk/framework/util/ConfigureService.cs (revision 32)
+++ trunk/framework/util/ConfigureService.cs (revision 33)
@@ -58,10 +58,14 @@
5858 // }
5959 infoText.Append("Operating System", Environment.OSVersion.ToString());
6060 GlobalMemoryInfo info = new GlobalMemoryInfo();
61+ string proctxt = string.Format("{0} (Cores={1})", Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")
62+ ,Environment.ProcessorCount);
63+ infoText.Append("Processor", proctxt);
6164 string memtext = string.Format("Physical {0:#,##0,,}MB/{1:#,##0,,}MB, Virtual {2:#,##0,,}MB/{3:#,##0,,}MB",
6265 info.PhysicalMemAvailable,info.PhysicalMemTotal,
6366 info.VirtualMemAvailable,info.VirtualMemTotal);
6467 infoText.Append("System Memory", memtext);
68+ infoText.Append("Process Context Memory", string.Format("{0:#,##,,}MB", Environment.WorkingSet));
6569 if (OnSystemInfoRequested != null) {
6670 Delegate[] delegates = OnSystemInfoRequested.GetInvocationList();
6771 foreach (Delegate d in delegates) {
--- trunk/framework/contributions/ui/CtbCommandEntity.cs (revision 32)
+++ trunk/framework/contributions/ui/CtbCommandEntity.cs (revision 33)
@@ -6,6 +6,8 @@
66 using nft.framework;
77 using nft.framework.plugin;
88 using nft.util;
9+using nft.ui.docking;
10+using WeifenLuo.WinFormsUI.Docking;
911
1012 namespace nft.contributions.ui
1113 {
@@ -12,7 +14,7 @@
1214 /// <summary>
1315 /// CtbCommandEntity の概要の説明です。
1416 /// </summary>
15- public class CtbCommandEntity : Contribution
17+ public class CtbCommandEntity : Contribution, IDockContentFactory
1618 {
1719 protected enum MethodType { Static, Instance, Constructor };
1820 protected readonly string commandType;
@@ -104,5 +106,16 @@
104106 throw new Exception(string.Format(templ,targetType.FullName,path),e);
105107 }
106108 }
109+
110+ /// <summary>
111+ /// Called from DockManagerEx as a owner of SubFrom command.
112+ /// </summary>
113+ /// <param name="subkey"></param>
114+ /// <returns></returns>
115+ public DockContent CreateDockContent(string subkey) {
116+ IDockContentFactory factory = entity as IDockContentFactory;
117+ return factory!=null ? factory.CreateDockContent(subkey) : null;
118+ }
119+
107120 }
108121 }
--- trunk/framework/contributions/ui/CtbSubform.cs (revision 32)
+++ trunk/framework/contributions/ui/CtbSubform.cs (revision 33)
@@ -19,7 +19,7 @@
1919 /// sub-form can float or docking. (can auto-shrink or no-shrink while docking).
2020 /// you can forbid some of style to each form by specifing several options.
2121 /// </summary>
22- public class CtbSubform : Contribution
22+ public class CtbSubform : Contribution, IDockContentFactory
2323 {
2424 public static class PredefinedOptions {
2525 public static readonly string Multiple = "multiple";
@@ -30,23 +30,7 @@
3030 }
3131
3232 public static readonly string SepalatorPersist = "::";
33-
34- static CtbSubform() {
35- ((MainFrame)Main.mainFrame).DockingManager.RegisterResolver(ResolveDockContent);
36- }
37-
38- public static DockContent ResolveDockContent(string persist) {
39- int n = persist.IndexOf(SepalatorPersist);
40- string id = persist.Substring(0, n);
41- string nam = persist.Substring(n + SepalatorPersist.Length);
42- CtbSubform ctb = PluginManager.theInstance.GetContribution(id) as CtbSubform;
43- if (ctb != null) {
44- return ctb.GetContent(nam, true).Parent as DockContent;
45- } else {
46- return null;
47- }
48- }
49-
33+
5034 /// <summary>
5135 ///
5236 /// </summary>
@@ -112,7 +96,7 @@
11296 return GetContent(name, true);
11397 }
11498
115- internal protected SubformHolder GetHolder(string name, bool create) {
99+ internal protected virtual SubformHolder GetHolder(string name, bool create) {
116100 string key = IsSingleton ? "" : name;
117101 SubformHolder holder;
118102 if (!contentMap.TryGetValue(key, out holder) && create) {
@@ -128,8 +112,12 @@
128112 Control c = (Control)Activator.CreateInstance(windowType);
129113 c.Name = name;
130114 return c;
131- }
115+ }
132116
117+ public DockContent CreateDockContent(string subkey) {
118+ return GetContent(subkey, true).Parent as DockContent;
119+ }
120+
133121 protected IList<string> options;
134122 /// <summary>
135123 /// enumerate all option strings
@@ -182,7 +170,7 @@
182170 /// Show sub-form window.
183171 /// </summary>
184172 /// <param name="name">key for muliple forms (ignored for singleton)</param>
185- public void Show(string name) {
173+ public virtual void Show(string name) {
186174 SubformHolder h = GetHolder(name, true);
187175 h.Show();
188176 }
@@ -191,7 +179,7 @@
191179 /// Hide sub-form window. 'Suicidal' form will be disposed.
192180 /// </summary>
193181 /// <param name="name">key for muliple forms (ignored for singleton)</param>
194- public void Hide(string name) {
182+ public virtual void Hide(string name) {
195183 SubformHolder h = GetHolder(name, false);
196184 if (h != null) {
197185 h.Hide();
@@ -237,6 +225,7 @@
237225 }
238226
239227 public class CtbFormHolder : SubformHolder {
228+
240229 public static CtbFormHolder Create(CtbSubform ctb, string key) {
241230 LayoutState state = LayoutState.Right;
242231 LayoutStyle style = LayoutStyle.AllSide | LayoutStyle.Float;
@@ -258,5 +247,6 @@
258247 }
259248
260249 }
261- }
250+
251+ }
262252 }
--- trunk/Win32Util/GlobalMemoryInfo.cs (revision 32)
+++ trunk/Win32Util/GlobalMemoryInfo.cs (revision 33)
@@ -1,4 +1,5 @@
11 using System;
2+using System.Diagnostics;
23 using System.Runtime.InteropServices;
34
45 namespace nft.win32util
@@ -9,36 +10,41 @@
910 /// </summary>
1011 public class GlobalMemoryInfo
1112 {
13+ [return: MarshalAs(UnmanagedType.Bool)]
14+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
15+ extern static bool GlobalMemoryStatusEx([In,Out] MemoryStatusEx lpBuffer);
16+
17+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
18+ public class MemoryStatusEx {
19+ public uint dwLength;
20+ public uint dwMemoryLoad;
21+ public ulong ullTotalPhys; // physical memory total
22+ public ulong ullAvailPhys; // physical memory available
23+ public ulong ullTotalPageFile; // page files total
24+ public ulong ullAvailPageFile; // page files available
25+ public ulong ullTotalVirtual; // virtual memory total
26+ public ulong ullAvailVirtual; // virtual memory available
27+ public ulong ullAvailExtendedVirtual;
28+ public MemoryStatusEx() {
29+ this.dwLength = (uint)Marshal.SizeOf(typeof(MemoryStatusEx));
30+ }
31+ }
1232
13- [DllImport("kernel32.dll")]
14- extern static void GlobalMemoryStatus(ref MemoryStatus lpBuffer) ;
33+ private readonly MemoryStatusEx msinfo;
1534
16- struct MemoryStatus
17- {
18- public int dwLength ;
19- public int dwMemoryLoad ;
20- public int dwTotalPhys ; // physical memory total
21- public int dwAvailPhys ; // physical memory available
22- public int dwTotalPageFile ; // page files total
23- public int dwAvailPageFile ; // page files available
24- public int dwTotalVirtual ; // virtual memory total
25- public int dwAvailVirtual ; // virtual memory available
26- }
27-
28- private readonly MemoryStatus msinfo;
29-
3035 public GlobalMemoryInfo()
3136 {
32- msinfo = new MemoryStatus();
33- msinfo.dwLength = Marshal.SizeOf(msinfo);
34- GlobalMemoryStatus(ref msinfo);
37+ msinfo = new MemoryStatusEx();
38+ if (!GlobalMemoryStatusEx(msinfo)) {
39+ Debug.WriteLine(Marshal.GetLastWin32Error());
40+ }
3541 }
3642
37- public int PhysicalMemTotal { get { return msinfo.dwTotalPhys; } }
38- public int PhysicalMemAvailable { get { return msinfo.dwAvailPhys; } }
39- public int PageFileTotal { get { return msinfo.dwTotalPageFile; } }
40- public int PageFileAvailable { get { return msinfo.dwAvailPageFile; } }
41- public int VirtualMemTotal { get { return msinfo.dwTotalVirtual; } }
42- public int VirtualMemAvailable { get { return msinfo.dwAvailVirtual; } }
43+ public ulong PhysicalMemTotal { get { return msinfo.ullTotalPhys; } }
44+ public ulong PhysicalMemAvailable { get { return msinfo.ullAvailPhys; } }
45+ public ulong PageFileTotal { get { return msinfo.ullTotalPageFile; } }
46+ public ulong PageFileAvailable { get { return msinfo.ullAvailPageFile; } }
47+ public ulong VirtualMemTotal { get { return msinfo.ullTotalVirtual; } }
48+ public ulong VirtualMemAvailable { get { return msinfo.ullAvailVirtual; } }
4349 }
4450 }
--- trunk/ui_jp/ui/WinFormWrapper.cs (revision 32)
+++ trunk/ui_jp/ui/WinFormWrapper.cs (revision 33)
@@ -47,20 +47,30 @@
4747 }
4848 }
4949
50- public IxControl Find(string name) {
51- IxControl c;
52- if (!ctrCache.TryGetValue(name, out c)) {
53- Control c0 = entity.Controls[name];
54- if (c0 != null) {
55- c = CreateWrapperFor(c0);
56- ctrCache.Add(name, c);
50+ public IxControl this[string name] {
51+ get
52+ {
53+ IxControl c;
54+ if (!ctrCache.TryGetValue(name, out c))
55+ {
56+ Control c0 = entity.Controls[name];
57+ if (c0 != null)
58+ {
59+ c = CreateWrapperFor(c0);
60+ ctrCache.Add(name, c);
61+ }
5762 }
63+ return c;
5864 }
59- return c;
6065 }
6166
67+ public IxInput<T> Get<T>(string name)
68+ {
69+ return this[name] as IxInput<T>;
70+ }
71+
6272 protected IxControl Find(Control c) {
63- return Find(c.Name);
73+ return this[c.Name];
6474 }
6575
6676 protected WinControlWrapper CreateWrapperFor(Control c) {
@@ -69,7 +79,7 @@
6979 return w;
7080 }
7181
72- public IEnumerator<IxControl> EnumControls() {
82+ public IEnumerator<IxControl> EnumChildren() {
7383 return new ControlEnumerator(this).GetEnumerator();
7484 }
7585
@@ -93,6 +103,19 @@
93103 }
94104 }
95105
106+
107+ public bool Enabled
108+ {
109+ get
110+ {
111+ throw new NotImplementedException();
112+ }
113+ set
114+ {
115+ throw new NotImplementedException();
116+ }
117+ }
118+
96119 public bool Visible {
97120 get {
98121 return entity.Visible;
@@ -111,5 +134,6 @@
111134 public event XFormEvent ControlValuesChanged;
112135
113136 public event XFormEvent OnApply;
137+
114138 }
115139 }
--- trunk/ui_jp/ui/core/InspectorTool.Designer.cs (nonexistent)
+++ trunk/ui_jp/ui/core/InspectorTool.Designer.cs (revision 33)
@@ -0,0 +1,71 @@
1+namespace nft.ui.core
2+{
3+ partial class InspectorTool
4+ {
5+ /// <summary>
6+ /// 必要なデザイナー変数です。
7+ /// </summary>
8+ private System.ComponentModel.IContainer components = null;
9+
10+ /// <summary>
11+ /// 使用中のリソースをすべてクリーンアップします。
12+ /// </summary>
13+ /// <param name="disposing">マネージ リソースが破棄される場合 true、破棄されない場合は false です。</param>
14+ protected override void Dispose(bool disposing)
15+ {
16+ if (disposing && (components != null))
17+ {
18+ components.Dispose();
19+ }
20+ base.Dispose(disposing);
21+ }
22+
23+ #region コンポーネント デザイナーで生成されたコード
24+
25+ /// <summary>
26+ /// デザイナー サポートに必要なメソッドです。このメソッドの内容を
27+ /// コード エディターで変更しないでください。
28+ /// </summary>
29+ private void InitializeComponent()
30+ {
31+ this.lbStatus = new System.Windows.Forms.Label();
32+ this.renderViewPanel = new nft.framework.drawing.RenderViewPanel();
33+ this.SuspendLayout();
34+ //
35+ // lbStatus
36+ //
37+ this.lbStatus.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
38+ this.lbStatus.Dock = System.Windows.Forms.DockStyle.Bottom;
39+ this.lbStatus.Location = new System.Drawing.Point(0, 166);
40+ this.lbStatus.Name = "lbStatus";
41+ this.lbStatus.Size = new System.Drawing.Size(200, 74);
42+ this.lbStatus.TabIndex = 3;
43+ this.lbStatus.Text = "...";
44+ //
45+ // renderViewPanel
46+ //
47+ this.renderViewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
48+ this.renderViewPanel.Location = new System.Drawing.Point(0, 0);
49+ this.renderViewPanel.Name = "renderViewPanel";
50+ this.renderViewPanel.Size = new System.Drawing.Size(200, 240);
51+ this.renderViewPanel.SurfaceUsage = nft.framework.drawing.SurfaceUsage.Normal;
52+ this.renderViewPanel.TabIndex = 2;
53+ //
54+ // InspectorTool
55+ //
56+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
57+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
58+ this.Controls.Add(this.lbStatus);
59+ this.Controls.Add(this.renderViewPanel);
60+ this.Name = "InspectorTool";
61+ this.Size = new System.Drawing.Size(200, 240);
62+ this.ResumeLayout(false);
63+
64+ }
65+
66+ #endregion
67+
68+ private System.Windows.Forms.Label lbStatus;
69+ private framework.drawing.RenderViewPanel renderViewPanel;
70+ }
71+}
--- trunk/ui_jp/ui/core/InspectorTool.cs (nonexistent)
+++ trunk/ui_jp/ui/core/InspectorTool.cs (revision 33)
@@ -0,0 +1,88 @@
1+using System;
2+using System.Collections.Generic;
3+using System.ComponentModel;
4+using System.Drawing;
5+using System.Data;
6+using System.Text;
7+using System.Windows.Forms;
8+using nft.core.game;
9+using nft.core.view;
10+using nft.impl.view;
11+using nft.framework.drawing;
12+using nft.impl.game;
13+using Geocon = nft.core.geometry.GeometricConstants;
14+
15+namespace nft.ui.core
16+{
17+ public partial class InspectorTool : UserControl, IPointerHandler
18+ {
19+ public InspectorTool()
20+ {
21+ InitializeComponent();
22+ }
23+
24+ protected override void OnLoad(EventArgs e)
25+ {
26+ base.OnLoad(e);
27+ GameManager.theInstance.Tools.Add(this, false);
28+ }
29+
30+ #region IPointerHandler implementation
31+ protected IGame game;
32+ public void OnAttach(IGame g)
33+ {
34+ this.game = g;
35+ }
36+
37+ public void OnDetach(IGame g)
38+ {
39+ this.game = null;
40+ }
41+
42+ public void OnMouseButtonDown(PointerEventArgs args)
43+ {
44+ }
45+
46+ public void OnMouseButtonUp(PointerEventArgs args)
47+ {
48+ }
49+
50+ public void OnMouseMove(PointerEventArgs args)
51+ {
52+ IView view = args.Game.Views.ActiveView;
53+ Point pos = args.OriginalEventArgs.Location;
54+ SelectionInfo si = view.SceneBuilder.GetObjectAt(pos);
55+ if (si != null) {
56+ if (si.Polygon != null) {
57+ lbStatus.Text = String.Format("HT={0:X6},PID={1:X6}", si.HitTestValue, si.Polygon.ID);
58+ } else {
59+ lbStatus.Text = String.Format("HT={0:X6},PID=N/A", si.HitTestValue);
60+ }
61+ this.renderViewPanel.Surface.Objects = ToRenderObjects(si);
62+ } else {
63+ lbStatus.Text = "N/A";
64+ }
65+ }
66+
67+ protected IEnumerable<I3DObject> ToRenderObjects(SelectionInfo si) {
68+ if (si.TerrainPiece != null) {
69+ int x = si.Location.X;
70+ int y = si.Location.Y;
71+ int h = si.TerrainPiece.BaseHeight * Geocon.UnitHeightPixel;
72+ IEnumerable<I3DObject> terrains = si.SceneBuilder.GetTerrainsAt(x, y);
73+ x *= Geocon.UnitWidthPixel;
74+ y *= Geocon.UnitWidthPixel;
75+ PointF3D pt;
76+ foreach (I3DObject obj in terrains) {
77+ ITerrainPlate p = obj as ITerrainPlate;
78+ pt = p.Location;
79+ p.Location = new PointF3D(pt.X - x, pt.Y - y, pt.Z - h);
80+ yield return p;
81+ }
82+
83+ }
84+ yield break;
85+ }
86+ #endregion
87+ }
88+}
--- trunk/ui_jp/ui/core/InspectToolForm.Designer.cs (revision 32)
+++ trunk/ui_jp/ui/core/InspectToolForm.Designer.cs (revision 33)
@@ -25,19 +25,10 @@
2525 /// the contents of this method with the code editor.
2626 /// </summary>
2727 private void InitializeComponent() {
28+ this.lbStatus = new System.Windows.Forms.Label();
2829 this.renderViewPanel = new nft.framework.drawing.RenderViewPanel();
29- this.lbStatus = new System.Windows.Forms.Label();
3030 this.SuspendLayout();
3131 //
32- // renderViewPanel
33- //
34- this.renderViewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
35- this.renderViewPanel.Location = new System.Drawing.Point(0, 0);
36- this.renderViewPanel.Name = "renderViewPanel";
37- this.renderViewPanel.Size = new System.Drawing.Size(232, 268);
38- this.renderViewPanel.SurfaceUsage = nft.framework.drawing.SurfaceUsage.Normal;
39- this.renderViewPanel.TabIndex = 0;
40- //
4132 // lbStatus
4233 //
4334 this.lbStatus.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
@@ -48,6 +39,15 @@
4839 this.lbStatus.TabIndex = 1;
4940 this.lbStatus.Text = "...";
5041 //
42+ // renderViewPanel
43+ //
44+ this.renderViewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
45+ this.renderViewPanel.Location = new System.Drawing.Point(0, 0);
46+ this.renderViewPanel.Name = "renderViewPanel";
47+ this.renderViewPanel.Size = new System.Drawing.Size(232, 268);
48+ this.renderViewPanel.SurfaceUsage = nft.framework.drawing.SurfaceUsage.Normal;
49+ this.renderViewPanel.TabIndex = 0;
50+ //
5151 // InspectToolForm
5252 //
5353 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);