OSDN Git Service

c1b06fdeb494a5fa1a7c2de4900b5acfc703d341
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 05.選曲 / CActSelectPopupMenu.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Diagnostics;\r
4 using System.Globalization;\r
5 using System.Text;\r
6 using System.Runtime.InteropServices;\r
7 using System.Drawing;\r
8 using System.IO;\r
9 using FDK;\r
10 \r
11 \r
12 namespace DTXMania\r
13 {\r
14         internal class CActSelectPopupMenu : CActivity\r
15         {\r
16 \r
17                 // プロパティ\r
18 \r
19 \r
20                 public int GetIndex(int pos)\r
21                 {\r
22                         return lciMenuItems[pos].cItem.GetIndex();\r
23                 }\r
24                 public object GetObj現在値(int pos)\r
25                 {\r
26                         return lciMenuItems[pos].cItem.obj現在値();\r
27                 }\r
28                 public bool bGotoDetailConfig\r
29                 {\r
30                         get;\r
31                         internal set;\r
32                 }\r
33 \r
34                 /// <summary>\r
35                 /// ソートメニュー機能を使用中かどうか。外部からこれをtrueにすると、ソートメニューが出現する。falseにすると消える。\r
36                 /// </summary>\r
37                 public bool bIsActivePopupMenu\r
38                 {\r
39                         get;\r
40                         private set;\r
41                 }\r
42                 public virtual void tActivatePopupMenu(E楽器パート einst)\r
43                 {\r
44                         nItemSelecting = -1;            // #24757 2011.4.1 yyagi: Clear sorting status in each stating menu.\r
45                         this.eInst = einst;\r
46                         this.bIsActivePopupMenu = true;\r
47                         this.bIsSelectingIntItem = false;\r
48                         this.bGotoDetailConfig = false;\r
49                 }\r
50                 public virtual void tDeativatePopupMenu()\r
51                 {\r
52                         this.bIsActivePopupMenu = false;\r
53                 }\r
54 \r
55 \r
56                 public void Initialize(List<CItemBase> menulist, bool showAllItems, string title)\r
57                 {\r
58                         Initialize(menulist, showAllItems, title, 0);\r
59                 }\r
60 \r
61                 public void Initialize(List<CItemBase> menulist, bool showAllItems, string title, int defaultPos)\r
62                 {\r
63 \r
64                         prvFont = new CPrivateFastFont(CSkin.Path(@"Graphics\fonts\mplus-1p-heavy.ttf"), (int)(18 * Scale.Y));\r
65 \r
66                         stqMenuTitle = new stQuickMenuItem();\r
67                         stqMenuTitle.cItem = new CItemBase();\r
68                         stqMenuTitle.cItem.str項目名 = title;\r
69                         stqMenuTitle.txName = TextureFactory.tテクスチャの生成(prvFont.DrawPrivateFont(title, Color.White, Color.Black), false);\r
70                         stqMenuTitle.rectName = prvFont.RectStrings;\r
71                         lciMenuItems = new stQuickMenuItem[menulist.Count];\r
72                         for (int i = 0; i < menulist.Count; i++)\r
73                         {\r
74                                 stQuickMenuItem stqm = new stQuickMenuItem();\r
75                                 stqm.cItem = menulist[i];\r
76                                 stqm.txName = TextureFactory.tテクスチャの生成(prvFont.DrawPrivateFont(menulist[i].str項目名, Color.White, Color.Black), false);\r
77                                 stqm.rectName = prvFont.RectStrings;\r
78                                 lciMenuItems[i] = stqm;\r
79                         }\r
80 \r
81                         bShowAllItems = showAllItems;\r
82                         n現在の選択行 = defaultPos;\r
83                 }\r
84 \r
85 \r
86                 public void tEnter押下()\r
87                 {\r
88                         if (this.bキー入力待ち)\r
89                         {\r
90                                 CDTXMania.Instance.Skin.sound決定音.t再生する();\r
91 \r
92                                 if (this.n現在の選択行 != lciMenuItems.Length - 1)\r
93                                 {\r
94                                         if (lciMenuItems[n現在の選択行].cItem.e種別 == CItemBase.E種別.リスト ||\r
95                                                  lciMenuItems[n現在の選択行].cItem.e種別 == CItemBase.E種別.ONorOFFトグル ||\r
96                                                  lciMenuItems[n現在の選択行].cItem.e種別 == CItemBase.E種別.ONorOFFor不定スリーステート)\r
97                                         {\r
98                                                 lciMenuItems[n現在の選択行].cItem.t項目値を次へ移動();\r
99                                         }\r
100                                         else if (lciMenuItems[n現在の選択行].cItem.e種別 == CItemBase.E種別.整数)\r
101                                         {\r
102                                                 bIsSelectingIntItem = !bIsSelectingIntItem;             // 選択状態/選択解除状態を反転する\r
103                                         }\r
104                                         else if (lciMenuItems[n現在の選択行].cItem.e種別 == CItemBase.E種別.切替リスト)\r
105                                         {\r
106                                                 // 特に何もしない\r
107                                         }\r
108                                         else\r
109                                         {\r
110                                                 throw new ArgumentException();\r
111                                         }\r
112                                         nItemSelecting = n現在の選択行;\r
113                                 }\r
114                                 tEnter押下Main((int)lciMenuItems[n現在の選択行].cItem.GetIndex());\r
115 \r
116                                 this.bキー入力待ち = true;\r
117                         }\r
118                 }\r
119 \r
120                 /// <summary>\r
121                 /// Decide押下時の処理を、継承先で記述する。\r
122                 /// </summary>\r
123                 /// <param name="val">CItemBaseの現在の設定値のindex</param>\r
124                 public virtual void tEnter押下Main(int val)\r
125                 {\r
126                 }\r
127                 /// <summary>\r
128                 /// Cancel押下時の追加処理があれば、継承先で記述する。\r
129                 /// </summary>\r
130                 public virtual void tCancel()\r
131                 {\r
132                 }\r
133                 /// <summary>\r
134                 /// 追加の描画処理。必要に応じて、継承先で記述する。\r
135                 /// </summary>\r
136                 public virtual void t進行描画sub()\r
137                 {\r
138                 }\r
139 \r
140 \r
141                 public void t次に移動()\r
142                 {\r
143                         if (this.bキー入力待ち)\r
144                         {\r
145                                 CDTXMania.Instance.Skin.soundカーソル移動音.t再生する();\r
146                                 if (bIsSelectingIntItem)\r
147                                 {\r
148                                         lciMenuItems[n現在の選択行].cItem.t項目値を前へ移動();            // 項目移動と数値上下は方向が逆になるので注意\r
149                                 }\r
150                                 else\r
151                                 {\r
152                                         if (++this.n現在の選択行 >= this.lciMenuItems.Length)\r
153                                         {\r
154                                                 this.n現在の選択行 = 0;\r
155                                         }\r
156                                 }\r
157                         }\r
158                 }\r
159                 public void t前に移動()\r
160                 {\r
161                         if (this.bキー入力待ち)\r
162                         {\r
163                                 CDTXMania.Instance.Skin.soundカーソル移動音.t再生する();\r
164                                 if (bIsSelectingIntItem)\r
165                                 {\r
166                                         lciMenuItems[n現在の選択行].cItem.t項目値を次へ移動();            // 項目移動と数値上下は方向が逆になるので注意\r
167                                 }\r
168                                 else\r
169                                 {\r
170                                         if (--this.n現在の選択行 < 0)\r
171                                         {\r
172                                                 this.n現在の選択行 = this.lciMenuItems.Length - 1;\r
173                                         }\r
174                                 }\r
175                         }\r
176                 }\r
177 \r
178                 // CActivity 実装\r
179 \r
180                 public override void On活性化()\r
181                 {\r
182                         //              this.n現在の選択行 = 0;\r
183                         this.bキー入力待ち = true;\r
184                         for (int i = 0; i < 4; i++)\r
185                         {\r
186                                 this.ctキー反復用[i] = new CCounter(0, 0, 0, CDTXMania.Instance.Timer);\r
187                         }\r
188                         base.b活性化してない = true;\r
189 \r
190                         this.bIsActivePopupMenu = false;\r
191                         //                      this.font = new CActDFPFont();\r
192                         //                      base.list子Activities.Add( this.font );\r
193                         nItemSelecting = -1;\r
194 \r
195 \r
196                         base.On活性化();\r
197                 }\r
198                 public override void On非活性化()\r
199                 {\r
200                         if (!base.b活性化してない)\r
201                         {\r
202                                 //                              base.list子Activities.Remove( this.font );\r
203                                 //                              this.font.On非活性化();\r
204                                 //                              this.font = null;\r
205 \r
206                                 TextureFactory.tテクスチャの解放(ref this.txCursor);\r
207                                 TextureFactory.tテクスチャの解放(ref this.txPopupMenuBackground);\r
208                                 for (int i = 0; i < 4; i++)\r
209                                 {\r
210                                         this.ctキー反復用[i] = null;\r
211                                 }\r
212 \r
213                                 // 解放はGCに任せてみる\r
214                                 //if ( lciMenuItems != null )\r
215                                 //{\r
216                                 //    for ( int i = 0; i < lciMenuItems.Length; i++ )\r
217                                 //    {\r
218                                 //        lciMenuItems[ i ].cItem = null;\r
219                                 //        TextureFactory.tテクスチャの解放( ref lciMenuItems[ i ].txName );\r
220                                 //        lciMenuItems[ i ].txName = null;\r
221                                 //    }\r
222                                 //    lciMenuItems = null;\r
223                                 //}\r
224                                 //TextureFactory.tテクスチャの解放( ref txMenuTitle );\r
225 \r
226                                 base.On非活性化();\r
227                         }\r
228                 }\r
229                 public override void OnManagedリソースの作成()\r
230                 {\r
231                         if (!base.b活性化してない)\r
232                         {\r
233                                 string pathCursor = CSkin.Path(@"Graphics\ScreenConfig menu cursor.png"); ;\r
234                                 string pathPopupMenuBackground = CSkin.Path(@"Graphics\ScreenSelect sort menu background.png");\r
235                                 if (File.Exists(pathCursor))\r
236                                 {\r
237                                         this.txCursor = TextureFactory.tテクスチャの生成(pathCursor, false);\r
238                                 }\r
239                                 if (File.Exists(pathPopupMenuBackground))\r
240                                 {\r
241                                         this.txPopupMenuBackground = TextureFactory.tテクスチャの生成(pathPopupMenuBackground, false);\r
242                                 }\r
243                                 base.OnManagedリソースの作成();\r
244                         }\r
245                 }\r
246                 public override void OnManagedリソースの解放()\r
247                 {\r
248                         if (!base.b活性化してない)\r
249                         {\r
250                                 TextureFactory.tテクスチャの解放(ref this.txPopupMenuBackground);\r
251                                 TextureFactory.tテクスチャの解放(ref this.txCursor);\r
252                         }\r
253                         base.OnManagedリソースの解放();\r
254                 }\r
255 \r
256                 public override int On進行描画()\r
257                 {\r
258                         throw new InvalidOperationException("t進行描画(bool)のほうを使用してください。");\r
259                 }\r
260 \r
261                 public int t進行描画()\r
262                 {\r
263                         if (!base.b活性化してない && this.bIsActivePopupMenu)\r
264                         {\r
265                                 if (this.bキー入力待ち)\r
266                                 {\r
267                                         #region [ Shift-F1: CONFIG画面 ]\r
268                                         if ((CDTXMania.Instance.Input管理.Keyboard.bキーが押されている((int)SlimDX.DirectInput.Key.RightShift) || CDTXMania.Instance.Input管理.Keyboard.bキーが押されている((int)SlimDX.DirectInput.Key.LeftShift)) &&\r
269                                                 CDTXMania.Instance.Input管理.Keyboard.bキーが押された((int)SlimDX.DirectInput.Key.F1))\r
270                                         {       // [SHIFT] + [F1] CONFIG\r
271                                                 CDTXMania.Instance.Skin.sound取消音.t再生する();\r
272                                                 tCancel();\r
273                                                 this.bGotoDetailConfig = true;\r
274                                         }\r
275                                         #endregion\r
276                                         #region [ キー入力: キャンセル ]\r
277                                         else if (CDTXMania.Instance.Input管理.Keyboard.bキーが押された((int)SlimDX.DirectInput.Key.Escape)\r
278                                                 || CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.FT)\r
279                                                 || CDTXMania.Instance.Pad.b押されたGB(Eパッド.Cancel))\r
280                                         {       // キャンセル\r
281                                                 CDTXMania.Instance.Skin.sound取消音.t再生する();\r
282                                                 tCancel();\r
283                                                 this.bIsActivePopupMenu = false;\r
284                                         }\r
285                                         #endregion\r
286 \r
287                                         #region [ キー入力: 決定 ]\r
288                                         // E楽器パート eInst = E楽器パート.UNKNOWN;\r
289                                         ESortAction eAction = ESortAction.END;\r
290                                         if (CDTXMania.Instance.Pad.b押された(E楽器パート.GUITAR, Eパッド.Decide))\r
291                                         {\r
292                                                 eInst = E楽器パート.GUITAR;\r
293                                                 eAction = ESortAction.Decide;\r
294                                         }\r
295                                         else if (CDTXMania.Instance.Pad.b押された(E楽器パート.BASS, Eパッド.Decide))\r
296                                         {\r
297                                                 eInst = E楽器パート.BASS;\r
298                                                 eAction = ESortAction.Decide;\r
299                                         }\r
300                                         else if (\r
301                                                 CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.Decide) // #24756 2011.4.1 yyagi: Add condition "Drum-Decide" to enable CY in Sort Menu.\r
302                                                 || CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.RD)\r
303                                                 || CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.LC)\r
304                                                 || (CDTXMania.Instance.ConfigIni.bEnterがキー割り当てのどこにも使用されていない && CDTXMania.Instance.Input管理.Keyboard.bキーが押された((int)SlimDX.DirectInput.Key.Return)))\r
305                                         {\r
306                                                 eInst = E楽器パート.DRUMS;\r
307                                                 eAction = ESortAction.Decide;\r
308                                         }\r
309                                         if (eAction == ESortAction.Decide)      // 決定\r
310                                         {\r
311                                                 this.tEnter押下();\r
312                                         }\r
313                                         #endregion\r
314                                         #region [ キー入力: 前に移動 ]\r
315                                         this.ctキー反復用.Up.tキー反復(CDTXMania.Instance.Input管理.Keyboard.bキーが押されている((int)SlimDX.DirectInput.Key.UpArrow), new CCounter.DGキー処理(this.t前に移動));\r
316                                         this.ctキー反復用.R.tキー反復(CDTXMania.Instance.Pad.b押されているGB(Eパッド.R), new CCounter.DGキー処理(this.t前に移動));\r
317                                         if (CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.SD))\r
318                                         {\r
319                                                 this.t前に移動();\r
320                                         }\r
321                                         #endregion\r
322                                         #region [ キー入力: 次に移動 ]\r
323                                         this.ctキー反復用.Down.tキー反復(CDTXMania.Instance.Input管理.Keyboard.bキーが押されている((int)SlimDX.DirectInput.Key.DownArrow), new CCounter.DGキー処理(this.t次に移動));\r
324                                         this.ctキー反復用.B.tキー反復(CDTXMania.Instance.Pad.b押されているGB(Eパッド.B), new CCounter.DGキー処理(this.t次に移動));\r
325                                         if (CDTXMania.Instance.Pad.b押された(E楽器パート.DRUMS, Eパッド.LT))\r
326                                         {\r
327                                                 this.t次に移動();\r
328                                         }\r
329                                         #endregion\r
330                                 }\r
331                                 #region [ ポップアップメニュー 背景描画 ]\r
332                                 if (this.txPopupMenuBackground != null)\r
333                                 {\r
334                                         this.txPopupMenuBackground.t2D描画(CDTXMania.Instance.Device, 160 * Scale.X, 10 * Scale.Y);\r
335                                 }\r
336                                 #endregion\r
337                                 #region [ ソートメニュータイトル描画 ]\r
338                                 int x = (int)(240 * Scale.X), y = (int)(16 * Scale.Y);\r
339                                 stqMenuTitle.txName.t2D描画(CDTXMania.Instance.Device, x, y);                                         //font.t文字列描画( x, y, strMenuTitle, false, 1.0f );\r
340                                 #endregion\r
341                                 #region [ カーソル描画 ]\r
342                                 if (this.txCursor != null)\r
343                                 {\r
344                                         int height = stqMenuTitle.rectName.Height;\r
345                                         int curX = (int)(180 * Scale.X);\r
346                                         int curY = (int)(16 * Scale.Y) + (height / 4 - 6) + (height * (this.n現在の選択行 + 1));\r
347                                         this.txCursor.t2D描画(CDTXMania.Instance.Device, curX, curY, new Rectangle(0, 0, (int)(16 * Scale.X), (int)(32 * Scale.Y)));\r
348                                         curX += (int)(0x10 * Scale.X);\r
349                                         Rectangle rectangle = new Rectangle((int)(8 * Scale.X), 0, (int)(0x10 * Scale.X), (int)(0x20 * Scale.Y));\r
350                                         for (int j = 0; j < 16 + 3; j++)\r
351                                         {\r
352                                                 this.txCursor.t2D描画(CDTXMania.Instance.Device, curX, curY, rectangle);\r
353                                                 curX += (int)(16 * Scale.Y);\r
354                                         }\r
355                                         this.txCursor.t2D描画(CDTXMania.Instance.Device, curX, curY, new Rectangle((int)(0x10 * Scale.X), 0, (int)(16 * Scale.X), (int)(32 * Scale.Y)));\r
356                                 }\r
357                                 #endregion\r
358                                 #region [ ソート候補文字列描画 ]\r
359                                 for (int i = 0; i < lciMenuItems.Length; i++)\r
360                                 {\r
361                                         bool bItemBold = (i == nItemSelecting && !bShowAllItems) ? true : false;\r
362                                         //font.t文字列描画( 190, 80 + i * 32, lciMenuItems[i].cItem.str項目名, bItemBold, 1.0f );\r
363                                         if (lciMenuItems[i].txName != null)\r
364                                         {\r
365                                                 int height = lciMenuItems[i].rectName.Height;\r
366                                                 lciMenuItems[i].txName.t2D描画(CDTXMania.Instance.Device, 190 * Scale.X, (50 * Scale.Y) + i * height);\r
367                                         }\r
368 \r
369                                         bool bValueBold = (bItemBold || (i == nItemSelecting && bIsSelectingIntItem)) ? true : false;\r
370                                         if (bItemBold || bShowAllItems)\r
371                                         {\r
372                                                 string s;\r
373                                                 switch (lciMenuItems[i].cItem.str項目名)\r
374                                                 {\r
375                                                         case "PlaySpeed":\r
376                                                                 {\r
377                                                                         double d = (double)((int)lciMenuItems[i].cItem.obj現在値() / 20.0);\r
378                                                                         s = "x" + d.ToString("0.000");\r
379                                                                 }\r
380                                                                 break;\r
381                                                         case "ScrollSpeed":\r
382                                                                 {\r
383                                                                         double d = (double)((((int)lciMenuItems[i].cItem.obj現在値()) + 1) / 2.0);\r
384                                                                         s = "x" + d.ToString("0.0");\r
385                                                                 }\r
386                                                                 break;\r
387 \r
388                                                         default:\r
389                                                                 s = lciMenuItems[i].cItem.obj現在値().ToString();\r
390                                                                 break;\r
391                                                 }\r
392                                                 //font.t文字列描画( (int)(340 * Scale.X), (int)(80 + i * 32), s, bValueBold, 1.0f * Scale.Y);\r
393                                                 Bitmap bmpStr = bValueBold ?\r
394                                                         prvFont.DrawPrivateFont(s, Color.White, Color.Black, Color.Yellow, Color.OrangeRed) :\r
395                                                         prvFont.DrawPrivateFont(s, Color.White, Color.Black);\r
396                                                 CTexture ctStr = TextureFactory.tテクスチャの生成(bmpStr, false);\r
397                                                 ctStr.t2D描画(CDTXMania.Instance.Device, 340 * Scale.X, (50 * Scale.Y) + i * prvFont.RectStrings.Height);\r
398                                                 TextureFactory.tテクスチャの解放(ref ctStr);\r
399                                         }\r
400                                 }\r
401                                 #endregion\r
402                                 t進行描画sub();\r
403                         }\r
404                         return 0;\r
405                 }\r
406 \r
407 \r
408                 // その他\r
409 \r
410                 #region [ private ]\r
411                 //-----------------\r
412 \r
413                 private bool bキー入力待ち;\r
414 \r
415                 internal int n現在の選択行;\r
416                 internal E楽器パート eInst = E楽器パート.UNKNOWN;\r
417 \r
418                 private CTexture txPopupMenuBackground;\r
419                 private CTexture txCursor;\r
420                 //private CActDFPFont font;\r
421 \r
422                 internal struct stQuickMenuItem\r
423                 {\r
424                         internal CItemBase cItem;\r
425                         internal CTexture txName;\r
426                         internal Rectangle rectName;\r
427                 }\r
428                 private stQuickMenuItem[] lciMenuItems;\r
429                 CPrivateFastFont prvFont;\r
430 \r
431                 private stQuickMenuItem stqMenuTitle;\r
432                 private bool bShowAllItems;\r
433                 private bool bIsSelectingIntItem;\r
434 \r
435                 [StructLayout(LayoutKind.Sequential)]\r
436                 private struct STキー反復用カウンタ\r
437                 {\r
438                         public CCounter Up;\r
439                         public CCounter Down;\r
440                         public CCounter R;\r
441                         public CCounter B;\r
442                         public CCounter this[int index]\r
443                         {\r
444                                 get\r
445                                 {\r
446                                         switch (index)\r
447                                         {\r
448                                                 case 0:\r
449                                                         return this.Up;\r
450 \r
451                                                 case 1:\r
452                                                         return this.Down;\r
453 \r
454                                                 case 2:\r
455                                                         return this.R;\r
456 \r
457                                                 case 3:\r
458                                                         return this.B;\r
459                                         }\r
460                                         throw new IndexOutOfRangeException();\r
461                                 }\r
462                                 set\r
463                                 {\r
464                                         switch (index)\r
465                                         {\r
466                                                 case 0:\r
467                                                         this.Up = value;\r
468                                                         return;\r
469 \r
470                                                 case 1:\r
471                                                         this.Down = value;\r
472                                                         return;\r
473 \r
474                                                 case 2:\r
475                                                         this.R = value;\r
476                                                         return;\r
477 \r
478                                                 case 3:\r
479                                                         this.B = value;\r
480                                                         return;\r
481                                         }\r
482                                         throw new IndexOutOfRangeException();\r
483                                 }\r
484                         }\r
485                 }\r
486                 private STキー反復用カウンタ ctキー反復用;\r
487 \r
488                 private enum ESortAction : int\r
489                 {\r
490                         Cancel, Decide, Previous, Next, END\r
491                 }\r
492                 private int nItemSelecting;             // 「n現在の選択行」とは別に設ける。sortでメニュー表示直後にアイテムの中身を表示しないようにするため\r
493                 //-----------------\r
494                 #endregion\r
495         }\r
496 }\r