OSDN Git Service

#36043 CDTXMania 内の app 以外の static メンバをインスタンスメンバにし、appを介してアクセスするように変更。CChipのメンバの多くをpr...
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 05.選曲 / CActSelect曲リスト.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Globalization;\r
5 using System.Runtime.InteropServices;\r
6 using System.Drawing;\r
7 using System.Drawing.Imaging;\r
8 using System.Diagnostics;\r
9 using System.Drawing.Text;\r
10 \r
11 using SlimDX;\r
12 using FDK;\r
13 \r
14 namespace DTXMania\r
15 {\r
16         internal class CActSelect曲リスト : CActivity\r
17         {\r
18                 // プロパティ\r
19 \r
20                 public bool bIsEnumeratingSongs\r
21                 {\r
22                         get;\r
23                         set;\r
24                 }\r
25                 public bool bスクロール中\r
26                 {\r
27                         get\r
28                         {\r
29                                 if (this.n目標のスクロールカウンタ == 0)\r
30                                 {\r
31                                         return (this.n現在のスクロールカウンタ != 0);\r
32                                 }\r
33                                 return true;\r
34                         }\r
35                 }\r
36                 public int n現在のアンカ難易度レベル\r
37                 {\r
38                         get;\r
39                         private set;\r
40                 }\r
41                 public int n現在選択中の曲の現在の難易度レベル\r
42                 {\r
43                         get\r
44                         {\r
45                                 return this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(this.r現在選択中の曲);\r
46                         }\r
47                 }\r
48                 public Cスコア r現在選択中のスコア\r
49                 {\r
50                         get\r
51                         {\r
52                                 if (this.r現在選択中の曲 != null)\r
53                                 {\r
54                                         return this.r現在選択中の曲.arスコア[this.n現在選択中の曲の現在の難易度レベル];\r
55                                 }\r
56                                 return null;\r
57                         }\r
58                 }\r
59                 public C曲リストノード r現在選択中の曲\r
60                 {\r
61                         get;\r
62                         private set;\r
63                 }\r
64 \r
65                 public int nスクロールバー相対y座標\r
66                 {\r
67                         get;\r
68                         private set;\r
69                 }\r
70 \r
71                 // t選択曲が変更された()内で使う、直前の選曲の保持\r
72                 // (前と同じ曲なら選択曲変更に掛かる再計算を省略して高速化するため)\r
73                 private C曲リストノード song_last = null;\r
74 \r
75 \r
76                 // コンストラクタ\r
77 \r
78                 public CActSelect曲リスト()\r
79                 {\r
80                         this.r現在選択中の曲 = null;\r
81                         this.n現在のアンカ難易度レベル = 0;\r
82                         base.b活性化してない = true;\r
83                         this.bIsEnumeratingSongs = false;\r
84                 }\r
85 \r
86 \r
87                 // メソッド\r
88 \r
89                 public int n現在のアンカ難易度レベルに最も近い難易度レベルを返す(C曲リストノード song)\r
90                 {\r
91                         // 事前チェック。\r
92 \r
93                         if (song == null)\r
94                                 return this.n現在のアンカ難易度レベル;      // 曲がまったくないよ\r
95 \r
96                         if (song.arスコア[this.n現在のアンカ難易度レベル] != null)\r
97                                 return this.n現在のアンカ難易度レベル;      // 難易度ぴったりの曲があったよ\r
98 \r
99                         if ((song.eノード種別 == C曲リストノード.Eノード種別.BOX) || (song.eノード種別 == C曲リストノード.Eノード種別.BACKBOX))\r
100                                 return 0;                                                               // BOX と BACKBOX は関係無いよ\r
101 \r
102 \r
103                         // 現在のアンカレベルから、難易度上向きに検索開始。\r
104 \r
105                         int n最も近いレベル = this.n現在のアンカ難易度レベル;\r
106 \r
107                         for (int i = 0; i < 5; i++)\r
108                         {\r
109                                 if (song.arスコア[n最も近いレベル] != null)\r
110                                         break;  // 曲があった。\r
111 \r
112                                 n最も近いレベル = (n最も近いレベル + 1) % 5;      // 曲がなかったので次の難易度レベルへGo。(5以上になったら0に戻る。)\r
113                         }\r
114 \r
115 \r
116                         // 見つかった曲がアンカより下のレベルだった場合……\r
117                         // アンカから下向きに検索すれば、もっとアンカに近い曲があるんじゃね?\r
118 \r
119                         if (n最も近いレベル < this.n現在のアンカ難易度レベル)\r
120                         {\r
121                                 // 現在のアンカレベルから、難易度下向きに検索開始。\r
122 \r
123                                 n最も近いレベル = this.n現在のアンカ難易度レベル;\r
124 \r
125                                 for (int i = 0; i < 5; i++)\r
126                                 {\r
127                                         if (song.arスコア[n最も近いレベル] != null)\r
128                                                 break;  // 曲があった。\r
129 \r
130                                         n最も近いレベル = ((n最も近いレベル - 1) + 5) % 5;        // 曲がなかったので次の難易度レベルへGo。(0未満になったら4に戻る。)\r
131                                 }\r
132                         }\r
133 \r
134                         return n最も近いレベル;\r
135                 }\r
136                 public C曲リストノード r指定された曲が存在するリストの先頭の曲(C曲リストノード song)\r
137                 {\r
138                         List<C曲リストノード> songList = GetSongListWithinMe(song);\r
139                         return (songList == null) ? null : songList[0];\r
140                 }\r
141                 public C曲リストノード r指定された曲が存在するリストの末尾の曲(C曲リストノード song)\r
142                 {\r
143                         List<C曲リストノード> songList = GetSongListWithinMe(song);\r
144                         return (songList == null) ? null : songList[songList.Count - 1];\r
145                 }\r
146 \r
147                 private List<C曲リストノード> GetSongListWithinMe(C曲リストノード song)\r
148                 {\r
149                         if (song.r親ノード == null)                                 // root階層のノートだったら\r
150                         {\r
151                                 return CDTXMania.app.Songs管理.list曲ルート;      // rootのリストを返す\r
152                         }\r
153                         else\r
154                         {\r
155                                 if ((song.r親ノード.list子リスト != null) && (song.r親ノード.list子リスト.Count > 0))\r
156                                 {\r
157                                         return song.r親ノード.list子リスト;\r
158                                 }\r
159                                 else\r
160                                 {\r
161                                         return null;\r
162                                 }\r
163                         }\r
164                 }\r
165 \r
166 \r
167                 public delegate void DGSortFunc(List<C曲リストノード> songList, E楽器パート eInst, int order, params object[] p);\r
168                 /// <summary>\r
169                 /// 主にCSong管理.cs内にあるソート機能を、delegateで呼び出す。\r
170                 /// </summary>\r
171                 /// <param name="sf">ソート用に呼び出すメソッド</param>\r
172                 /// <param name="eInst">ソート基準とする楽器</param>\r
173                 /// <param name="order">-1=降順, 1=昇順</param>\r
174                 public void t曲リストのソート(DGSortFunc sf, E楽器パート eInst, int order, params object[] p)\r
175                 {\r
176                         List<C曲リストノード> songList = GetSongListWithinMe(this.r現在選択中の曲);\r
177                         if (songList == null)\r
178                         {\r
179                                 // 何もしない;\r
180                         }\r
181                         else\r
182                         {\r
183                                 //                              CDTXMania.app.Songs管理.t曲リストのソート3_演奏回数の多い順( songList, eInst, order );\r
184                                 sf(songList, eInst, order, p);\r
185                                 //                              this.r現在選択中の曲 = CDTXMania.app.\r
186                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
187                         }\r
188                 }\r
189 \r
190                 public bool tBOXに入る()\r
191                 {\r
192                         //Trace.TraceInformation( "box enter" );\r
193                         //Trace.TraceInformation( "Skin現在Current : " + CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName( false ) );\r
194                         //Trace.TraceInformation( "Skin現在System  : " + CSkin.strSystemSkinSubfolderFullName );\r
195                         //Trace.TraceInformation( "Skin現在BoxDef  : " + CSkin.strBoxDefSkinSubfolderFullName );\r
196                         //Trace.TraceInformation( "Skin現在: " + CSkin.GetSkinName( CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName( false ) ) );\r
197                         //Trace.TraceInformation( "Skin現pt: " + CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName( false ) );\r
198                         //Trace.TraceInformation( "Skin指定: " + CSkin.GetSkinName( this.r現在選択中の曲.strSkinPath ) );\r
199                         //Trace.TraceInformation( "Skinpath: " + this.r現在選択中の曲.strSkinPath );\r
200                         bool ret = false;\r
201                         if (CSkin.GetSkinName(CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false)) != CSkin.GetSkinName(this.r現在選択中の曲.strSkinPath)\r
202                                 && CSkin.bUseBoxDefSkin)\r
203                         {\r
204                                 ret = true;\r
205                                 // BOXに入るときは、スキン変更発生時のみboxdefスキン設定の更新を行う\r
206                                 CDTXMania.app.Skin.SetCurrentSkinSubfolderFullName(this.r現在選択中の曲.strSkinPath, false);\r
207                         }\r
208 \r
209                         //Trace.TraceInformation( "Skin変更: " + CSkin.GetSkinName( CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName( false ) ) );\r
210                         //Trace.TraceInformation( "Skin変更Current : " + CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName( false ) );\r
211                         //Trace.TraceInformation( "Skin変更System  : " + CSkin.strSystemSkinSubfolderFullName );\r
212                         //Trace.TraceInformation( "Skin変更BoxDef  : " + CSkin.strBoxDefSkinSubfolderFullName );\r
213 \r
214                         if ((this.r現在選択中の曲.list子リスト != null) && (this.r現在選択中の曲.list子リスト.Count > 0))\r
215                         {\r
216                                 this.r現在選択中の曲 = this.r現在選択中の曲.list子リスト[0];\r
217                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
218                                 this.t選択曲が変更された(false);                                                                       // #27648 項目数変更を反映させる\r
219                         }\r
220                         return ret;\r
221                 }\r
222                 public bool tBOXを出る()\r
223                 {\r
224                         //Trace.TraceInformation( "box exit" );\r
225                         //Trace.TraceInformation( "Skin現在Current : " + CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false) );\r
226                         //Trace.TraceInformation( "Skin現在System  : " + CSkin.strSystemSkinSubfolderFullName );\r
227                         //Trace.TraceInformation( "Skin現在BoxDef  : " + CSkin.strBoxDefSkinSubfolderFullName );\r
228                         //Trace.TraceInformation( "Skin現在: " + CSkin.GetSkinName( CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false) ) );\r
229                         //Trace.TraceInformation( "Skin現pt: " + CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false) );\r
230                         //Trace.TraceInformation( "Skin指定: " + CSkin.GetSkinName( this.r現在選択中の曲.strSkinPath ) );\r
231                         //Trace.TraceInformation( "Skinpath: " + this.r現在選択中の曲.strSkinPath );\r
232                         bool ret = false;\r
233                         if (CSkin.GetSkinName(CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false)) != CSkin.GetSkinName(this.r現在選択中の曲.strSkinPath)\r
234                                 && CSkin.bUseBoxDefSkin)\r
235                         {\r
236                                 ret = true;\r
237                         }\r
238                         // スキン変更が発生しなくても、boxdef圏外に出る場合は、boxdefスキン設定の更新が必要\r
239                         // (ユーザーがboxdefスキンをConfig指定している場合への対応のために必要)\r
240                         // tBoxに入る()とは処理が微妙に異なるので注意\r
241                         CDTXMania.app.Skin.SetCurrentSkinSubfolderFullName(\r
242                                 (this.r現在選択中の曲.strSkinPath == "") ? "" : CDTXMania.app.Skin.GetSkinSubfolderFullNameFromSkinName(CSkin.GetSkinName(this.r現在選択中の曲.strSkinPath)), false);\r
243                         //Trace.TraceInformation( "SKIN変更: " + CSkin.GetSkinName( CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false) ) );\r
244                         //Trace.TraceInformation( "SKIN変更Current : "+  CDTXMania.app.Skin.GetCurrentSkinSubfolderFullName(false) );\r
245                         //Trace.TraceInformation( "SKIN変更System  : "+  CSkin.strSystemSkinSubfolderFullName );\r
246                         //Trace.TraceInformation( "SKIN変更BoxDef  : "+  CSkin.strBoxDefSkinSubfolderFullName );\r
247                         if (this.r現在選択中の曲.r親ノード != null)\r
248                         {\r
249                                 this.r現在選択中の曲 = this.r現在選択中の曲.r親ノード;\r
250                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
251                                 this.t選択曲が変更された(false);                                                                       // #27648 項目数変更を反映させる\r
252                         }\r
253                         return ret;\r
254                 }\r
255                 public void t現在選択中の曲を元に曲バーを再構成する()\r
256                 {\r
257                         this.tバーの初期化();\r
258                         for (int i = 0; i < 13; i++)\r
259                         {\r
260                                 this.t曲名バーの生成(i, this.stバー情報[i].strタイトル文字列, this.stバー情報[i].col文字色);\r
261                         }\r
262                 }\r
263                 public void t次に移動()\r
264                 {\r
265                         if (this.r現在選択中の曲 != null)\r
266                         {\r
267                                 this.n目標のスクロールカウンタ += 100;\r
268                         }\r
269                 }\r
270                 public void t前に移動()\r
271                 {\r
272                         if (this.r現在選択中の曲 != null)\r
273                         {\r
274                                 this.n目標のスクロールカウンタ -= 100;\r
275                         }\r
276                 }\r
277                 public void t難易度レベルをひとつ進める()\r
278                 {\r
279                         if ((this.r現在選択中の曲 == null) || (this.r現在選択中の曲.nスコア数 <= 1))\r
280                                 return;         // 曲にスコアが0~1個しかないなら進める意味なし。\r
281 \r
282 \r
283                         // 難易度レベルを+1し、現在選曲中のスコアを変更する。\r
284 \r
285                         this.n現在のアンカ難易度レベル = this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(this.r現在選択中の曲);\r
286 \r
287                         for (int i = 0; i < 5; i++)\r
288                         {\r
289                                 this.n現在のアンカ難易度レベル = (this.n現在のアンカ難易度レベル + 1) % 5;      // 5以上になったら0に戻る。\r
290                                 if (this.r現在選択中の曲.arスコア[this.n現在のアンカ難易度レベル] != null)        // 曲が存在してるならここで終了。存在してないなら次のレベルへGo。\r
291                                         break;\r
292                         }\r
293 \r
294 \r
295                         // 曲毎に表示しているスキル値を、新しい難易度レベルに合わせて取得し直す。(表示されている13曲全部。)\r
296 \r
297                         C曲リストノード song = this.r現在選択中の曲;\r
298                         for (int i = 0; i < 5; i++)\r
299                                 song = this.r前の曲(song);\r
300 \r
301                         for (int i = this.n現在の選択行 - 5; i < ((this.n現在の選択行 - 5) + 13); i++)\r
302                         {\r
303                                 int index = (i + 13) % 13;\r
304                                 for (int m = 0; m < 3; m++)\r
305                                 {\r
306                                         this.stバー情報[index].nスキル値[m] = (int)song.arスコア[this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(song)].譜面情報.最大スキル[m];\r
307                                 }\r
308                                 song = this.r次の曲(song);\r
309                         }\r
310 \r
311 \r
312                         // 選曲ステージに変更通知を発出し、関係Activityの対応を行ってもらう。\r
313 \r
314                         CDTXMania.app.stage選曲.t選択曲変更通知();\r
315                 }\r
316 \r
317 \r
318                 /// <summary>\r
319                 /// 曲リストをリセットする\r
320                 /// </summary>\r
321                 /// <param name="cs"></param>\r
322                 public void Refresh(CSongs管理 cs, bool bRemakeSongTitleBar)          // #26070 2012.2.28 yyagi\r
323                 {\r
324                         //                      this.On非活性化();\r
325 \r
326                         if (cs != null && cs.list曲ルート.Count > 0)        // 新しい曲リストを検索して、1曲以上あった\r
327                         {\r
328                                 CDTXMania.app.Songs管理 = cs;\r
329 \r
330                                 if (this.r現在選択中の曲 != null)                        // r現在選択中の曲==null とは、「最初songlist.dbが無かった or 検索したが1曲もない」\r
331                                 {\r
332                                         this.r現在選択中の曲 = searchCurrentBreadcrumbsPosition(CDTXMania.app.Songs管理.list曲ルート, this.r現在選択中の曲.strBreadcrumbs);\r
333                                         if (bRemakeSongTitleBar)                                        // 選曲画面以外に居るときには再構成しない (非活性化しているときに実行すると例外となる)\r
334                                         {\r
335                                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
336                                         }\r
337 #if false                       // list子リストの中まではmatchしてくれないので、検索ロジックは手書きで実装 (searchCurrentBreadcrumbs())\r
338                                         string bc = this.r現在選択中の曲.strBreadcrumbs;\r
339                                         Predicate<C曲リストノード> match = delegate( C曲リストノード c )\r
340                                         {\r
341                                                 return ( c.strBreadcrumbs.Equals( bc ) );\r
342                                         };\r
343                                         int nMatched = CDTXMania.app.Songs管理.list曲ルート.FindIndex( match );\r
344 \r
345                                         this.r現在選択中の曲 = ( nMatched == -1 ) ? null : CDTXMania.app.Songs管理.list曲ルート[ nMatched ];\r
346                                         this.t現在選択中の曲を元に曲バーを再構成する();\r
347 #endif\r
348                                         return;\r
349                                 }\r
350                         }\r
351                         this.On非活性化();\r
352                         this.r現在選択中の曲 = null;\r
353                         this.On活性化();\r
354                 }\r
355 \r
356 \r
357                 /// <summary>\r
358                 /// 現在選曲している位置を検索する\r
359                 /// (曲一覧クラスを新しいものに入れ替える際に用いる)\r
360                 /// </summary>\r
361                 /// <param name="ln">検索対象のList</param>\r
362                 /// <param name="bc">検索するパンくずリスト(文字列)</param>\r
363                 /// <returns></returns>\r
364                 private C曲リストノード searchCurrentBreadcrumbsPosition(List<C曲リストノード> ln, string bc)\r
365                 {\r
366                         foreach (C曲リストノード n in ln)\r
367                         {\r
368                                 if (n.strBreadcrumbs == bc)\r
369                                 {\r
370                                         return n;\r
371                                 }\r
372                                 else if (n.list子リスト != null && n.list子リスト.Count > 0)    // 子リストが存在するなら、再帰で探す\r
373                                 {\r
374                                         C曲リストノード r = searchCurrentBreadcrumbsPosition(n.list子リスト, bc);\r
375                                         if (r != null) return r;\r
376                                 }\r
377                         }\r
378                         return null;\r
379                 }\r
380 \r
381                 /// <summary>\r
382                 /// BOXのアイテム数と、今何番目を選択しているかをセットする\r
383                 /// </summary>\r
384                 public void t選択曲が変更された(bool bForce)   // #27648\r
385                 {\r
386                         C曲リストノード song = CDTXMania.app.stage選曲.r現在選択中の曲;\r
387                         if (song == null)\r
388                                 return;\r
389                         if (song == song_last && bForce == false)\r
390                                 return;\r
391 \r
392                         song_last = song;\r
393                         List<C曲リストノード> list = (song.r親ノード != null) ? song.r親ノード.list子リスト : CDTXMania.app.Songs管理.list曲ルート;\r
394                         int index = list.IndexOf(song) + 1;\r
395                         if (index <= 0)\r
396                         {\r
397                                 nCurrentPosition = nNumOfItems = 0;\r
398                         }\r
399                         else\r
400                         {\r
401                                 nCurrentPosition = index;\r
402                                 nNumOfItems = list.Count;\r
403                         }\r
404                 }\r
405 \r
406                 // CActivity 実装\r
407 \r
408                 public override void On活性化()\r
409                 {\r
410                         if (this.b活性化してる)\r
411                                 return;\r
412 \r
413                         this.e楽器パート = E楽器パート.DRUMS;\r
414                         this.b登場アニメ全部完了 = false;\r
415                         this.n目標のスクロールカウンタ = 0;\r
416                         this.n現在のスクロールカウンタ = 0;\r
417                         this.nスクロールタイマ = -1;\r
418 \r
419                         // フォント作成。\r
420                         // 曲リスト文字は2倍(面積4倍)でテクスチャに描画してから縮小表示するので、フォントサイズは2倍とする。\r
421 \r
422                         FontStyle regular = FontStyle.Regular;\r
423                         if (CDTXMania.app.ConfigIni.b選曲リストフォントを斜体にする) regular |= FontStyle.Italic;\r
424                         if (CDTXMania.app.ConfigIni.b選曲リストフォントを太字にする) regular |= FontStyle.Bold;\r
425                         this.ft曲リスト用フォント = new Font(\r
426                                 CDTXMania.app.ConfigIni.str選曲リストフォント,\r
427                                 (float)(CDTXMania.app.ConfigIni.n選曲リストフォントのサイズdot * 2 * Scale.Y),             // 後でScale.Yを掛けないように直すこと(Config.ini初期値変更)\r
428                                 regular,\r
429                                 GraphicsUnit.Pixel\r
430                         );\r
431 \r
432 \r
433                         // 現在選択中の曲がない(=はじめての活性化)なら、現在選択中の曲をルートの先頭ノードに設定する。\r
434 \r
435                         if ((this.r現在選択中の曲 == null) && (CDTXMania.app.Songs管理.list曲ルート.Count > 0))\r
436                                 this.r現在選択中の曲 = CDTXMania.app.Songs管理.list曲ルート[0];\r
437 \r
438 \r
439                         // バー情報を初期化する。\r
440 \r
441                         this.tバーの初期化();\r
442 \r
443                         base.On活性化();\r
444 \r
445                         this.t選択曲が変更された(true);                // #27648 2012.3.31 yyagi 選曲画面に入った直後の 現在位置/全アイテム数 の表示を正しく行うため\r
446                 }\r
447                 public override void On非活性化()\r
448                 {\r
449                         if (this.b活性化してない)\r
450                                 return;\r
451 \r
452                         TextureFactory.t安全にDisposeする(ref this.ft曲リスト用フォント);\r
453 \r
454                         for (int i = 0; i < 13; i++)\r
455                                 this.ct登場アニメ用[i] = null;\r
456 \r
457                         base.On非活性化();\r
458                 }\r
459                 public override void OnManagedリソースの作成()\r
460                 {\r
461                         if (this.b活性化してない)\r
462                                 return;\r
463 \r
464                         this.tx曲名バー.Score = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar score.png"), false);\r
465                         this.tx曲名バー.Box = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar box.png"), false);\r
466                         this.tx曲名バー.Other = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar other.png"), false);\r
467 \r
468                         this.tx選曲バー.Score = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar score selected.png"), false);\r
469                         this.tx選曲バー.Box = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar box selected.png"), false);\r
470                         this.tx選曲バー.Other = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect bar other selected.png"), false);\r
471 \r
472                         this.txスキル数字 = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect skill number on list.png"), false);\r
473                         for (int i = 0; i < 13; i++)\r
474                                 this.t曲名バーの生成(i, this.stバー情報[i].strタイトル文字列, this.stバー情報[i].col文字色);\r
475 \r
476                         int c = (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ? 0 : 1;\r
477                         #region [ Songs not found画像 ]\r
478                         try\r
479                         {\r
480                                 using (Bitmap image = new Bitmap(SampleFramework.GameWindowSize.Width, (int)(128 * Scale.Y)))\r
481                                 using (Graphics graphics = Graphics.FromImage(image))\r
482                                 {\r
483                                         string[] s1 = { "曲データが見つかりません。", "Songs not found." };\r
484                                         string[] s2 = { "曲データをDTXManiaGR.exe以下の", "You need to install songs." };\r
485                                         string[] s3 = { "フォルダにインストールして下さい。", "" };\r
486                                         graphics.DrawString(s1[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float)(2f * Scale.X), (float)(2f * Scale.Y));\r
487                                         graphics.DrawString(s1[c], this.ft曲リスト用フォント, Brushes.White, (float)0f, (float)0f);\r
488                                         graphics.DrawString(s2[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float)(2f * Scale.X), (float)(44f * Scale.Y));\r
489                                         graphics.DrawString(s2[c], this.ft曲リスト用フォント, Brushes.White, (float)0f, (float)(42f * Scale.Y));\r
490                                         graphics.DrawString(s3[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float)(2f * Scale.X), (float)(86f * Scale.Y));\r
491                                         graphics.DrawString(s3[c], this.ft曲リスト用フォント, Brushes.White, (float)0f, (float)(84f * Scale.Y));\r
492 \r
493                                         this.txSongNotFound = new CTexture(CDTXMania.app.Device, image, CDTXMania.app.TextureFormat);\r
494 \r
495                                         this.txSongNotFound.vc拡大縮小倍率 = new Vector3(0.5f, 0.5f, 1f); // 半分のサイズで表示する。\r
496                                 }\r
497                         }\r
498                         catch (CTextureCreateFailedException)\r
499                         {\r
500                                 Trace.TraceError("SoungNotFoundテクスチャの作成に失敗しました。");\r
501                                 this.txSongNotFound = null;\r
502                         }\r
503                         #endregion\r
504                         #region [ "曲データを検索しています"画像 ]\r
505                         try\r
506                         {\r
507                                 using (Bitmap image = new Bitmap(SampleFramework.GameWindowSize.Width, (int)(96 * Scale.Y)))\r
508                                 using (Graphics graphics = Graphics.FromImage(image))\r
509                                 {\r
510                                         string[] s1 = { "曲データを検索しています。", "Now enumerating songs." };\r
511                                         string[] s2 = { "そのまましばらくお待ち下さい。", "Please wait..." };\r
512                                         graphics.DrawString(s1[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float)(2f * Scale.X), (float)(2f * Scale.Y));\r
513                                         graphics.DrawString(s1[c], this.ft曲リスト用フォント, Brushes.White, (float)0f, (float)0f);\r
514                                         graphics.DrawString(s2[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float)(2f * Scale.X), (float)(44f * Scale.Y));\r
515                                         graphics.DrawString(s2[c], this.ft曲リスト用フォント, Brushes.White, (float)0f, (float)(42f * Scale.Y));\r
516 \r
517                                         this.txEnumeratingSongs = new CTexture(CDTXMania.app.Device, image, CDTXMania.app.TextureFormat);\r
518 \r
519                                         this.txEnumeratingSongs.vc拡大縮小倍率 = new Vector3(0.5f, 0.5f, 1f);     // 半分のサイズで表示する。\r
520                                 }\r
521                         }\r
522                         catch (CTextureCreateFailedException)\r
523                         {\r
524                                 Trace.TraceError("txEnumeratingSongsテクスチャの作成に失敗しました。");\r
525                                 this.txEnumeratingSongs = null;\r
526                         }\r
527                         #endregion\r
528                         #region [ 曲数表示 ]\r
529                         this.txアイテム数数字 = TextureFactory.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenSelect skill number on gauge etc.png"), false);\r
530                         #endregion\r
531                         base.OnManagedリソースの作成();\r
532                 }\r
533                 public override void OnManagedリソースの解放()\r
534                 {\r
535                         if (this.b活性化してない)\r
536                                 return;\r
537 \r
538                         TextureFactory.t安全にDisposeする(ref this.txアイテム数数字);\r
539 \r
540                         for (int i = 0; i < 13; i++)\r
541                                 TextureFactory.t安全にDisposeする(ref this.stバー情報[i].txタイトル名);\r
542 \r
543                         TextureFactory.t安全にDisposeする(ref this.txスキル数字);\r
544                         TextureFactory.t安全にDisposeする(ref this.txEnumeratingSongs);\r
545                         TextureFactory.t安全にDisposeする(ref this.txSongNotFound);\r
546                         TextureFactory.t安全にDisposeする(ref this.tx曲名バー.Score);\r
547                         TextureFactory.t安全にDisposeする(ref this.tx曲名バー.Box);\r
548                         TextureFactory.t安全にDisposeする(ref this.tx曲名バー.Other);\r
549                         TextureFactory.t安全にDisposeする(ref this.tx選曲バー.Score);\r
550                         TextureFactory.t安全にDisposeする(ref this.tx選曲バー.Box);\r
551                         TextureFactory.t安全にDisposeする(ref this.tx選曲バー.Other);\r
552 \r
553                         base.OnManagedリソースの解放();\r
554                 }\r
555                 public override int On進行描画()\r
556                 {\r
557                         if (this.b活性化してない)\r
558                                 return 0;\r
559 \r
560                         #region [ 初めての進行描画 ]\r
561                         //-----------------\r
562                         if (this.b初めての進行描画)\r
563                         {\r
564                                 for (int i = 0; i < 13; i++)\r
565                                         this.ct登場アニメ用[i] = new CCounter(-i * 10, 100, 3, CDTXMania.app.Timer);\r
566 \r
567                                 this.nスクロールタイマ = CSound管理.rc演奏用タイマ.n現在時刻;\r
568                                 CDTXMania.app.stage選曲.t選択曲変更通知();\r
569 \r
570                                 base.b初めての進行描画 = false;\r
571                         }\r
572                         //-----------------\r
573                         #endregion\r
574 \r
575 \r
576                         // まだ選択中の曲が決まってなければ、曲ツリールートの最初の曲にセットする。\r
577 \r
578                         if ((this.r現在選択中の曲 == null) && (CDTXMania.app.Songs管理.list曲ルート.Count > 0))\r
579                                 this.r現在選択中の曲 = CDTXMania.app.Songs管理.list曲ルート[0];\r
580 \r
581 \r
582                         // 本ステージは、(1)登場アニメフェーズ → (2)通常フェーズ と二段階にわけて進む。\r
583                         // 2つしかフェーズがないので CStage.eフェーズID を使ってないところがまた本末転倒。\r
584 \r
585 \r
586                         // 進行。\r
587 \r
588                         if (!this.b登場アニメ全部完了)\r
589                         {\r
590                                 #region [ (1) 登場アニメフェーズの進行。]\r
591                                 //-----------------\r
592                                 for (int i = 0; i < 13; i++)    // パネルは全13枚。\r
593                                 {\r
594                                         this.ct登場アニメ用[i].t進行();\r
595 \r
596                                         if (this.ct登場アニメ用[i].b終了値に達した)\r
597                                                 this.ct登場アニメ用[i].t停止();\r
598                                 }\r
599 \r
600                                 // 全部の進行が終わったら、this.b登場アニメ全部完了 を true にする。\r
601 \r
602                                 this.b登場アニメ全部完了 = true;\r
603                                 for (int i = 0; i < 13; i++)    // パネルは全13枚。\r
604                                 {\r
605                                         if (this.ct登場アニメ用[i].b進行中)\r
606                                         {\r
607                                                 this.b登場アニメ全部完了 = false;      // まだ進行中のアニメがあるなら false のまま。\r
608                                                 break;\r
609                                         }\r
610                                 }\r
611                                 //-----------------\r
612                                 #endregion\r
613                         }\r
614                         else\r
615                         {\r
616                                 #region [ (2) 通常フェーズの進行。]\r
617                                 //-----------------\r
618                                 long n現在時刻 = CSound管理.rc演奏用タイマ.n現在時刻;\r
619 \r
620                                 if (n現在時刻 < this.nスクロールタイマ)     // 念のため\r
621                                         this.nスクロールタイマ = n現在時刻;\r
622 \r
623                                 const int nアニメ間隔 = 2;\r
624                                 while ((n現在時刻 - this.nスクロールタイマ) >= nアニメ間隔)\r
625                                 {\r
626                                         int n加速度 = 1;\r
627                                         int n残距離 = Math.Abs((int)(this.n目標のスクロールカウンタ - this.n現在のスクロールカウンタ));\r
628 \r
629                                         #region [ 残距離が遠いほどスクロールを速くする(=n加速度を多くする)。]\r
630                                         //-----------------\r
631                                         if (n残距離 <= 100)\r
632                                         {\r
633                                                 n加速度 = 2;\r
634                                         }\r
635                                         else if (n残距離 <= 300)\r
636                                         {\r
637                                                 n加速度 = 3;\r
638                                         }\r
639                                         else if (n残距離 <= 500)\r
640                                         {\r
641                                                 n加速度 = 4;\r
642                                         }\r
643                                         else\r
644                                         {\r
645                                                 n加速度 = 8;\r
646                                         }\r
647                                         //-----------------\r
648                                         #endregion\r
649 \r
650                                         #region [ 加速度を加算し、現在のスクロールカウンタを目標のスクロールカウンタまで近づける。 ]\r
651                                         //-----------------\r
652                                         if (this.n現在のスクロールカウンタ < this.n目標のスクロールカウンタ)            // (A) 正の方向に未達の場合:\r
653                                         {\r
654                                                 this.n現在のスクロールカウンタ += n加速度;                                                               // カウンタを正方向に移動する。\r
655 \r
656                                                 if (this.n現在のスクロールカウンタ > this.n目標のスクロールカウンタ)\r
657                                                         this.n現在のスクロールカウンタ = this.n目標のスクロールカウンタ;        // 到着!スクロール停止!\r
658                                         }\r
659 \r
660                                         else if (this.n現在のスクロールカウンタ > this.n目標のスクロールカウンタ)       // (B) 負の方向に未達の場合:\r
661                                         {\r
662                                                 this.n現在のスクロールカウンタ -= n加速度;                                                               // カウンタを負方向に移動する。\r
663 \r
664                                                 if (this.n現在のスクロールカウンタ < this.n目標のスクロールカウンタ)    // 到着!スクロール停止!\r
665                                                         this.n現在のスクロールカウンタ = this.n目標のスクロールカウンタ;\r
666                                         }\r
667                                         //-----------------\r
668                                         #endregion\r
669 \r
670                                         if (this.n現在のスクロールカウンタ >= 100)          // 1行=100カウント。\r
671                                         {\r
672                                                 #region [ パネルを1行上にシフトする。]\r
673                                                 //-----------------\r
674 \r
675                                                 // 選択曲と選択行を1つ下の行に移動。\r
676 \r
677                                                 this.r現在選択中の曲 = this.r次の曲(this.r現在選択中の曲);\r
678                                                 this.n現在の選択行 = (this.n現在の選択行 + 1) % 13;\r
679 \r
680 \r
681                                                 // 選択曲から7つ下のパネル(=新しく最下部に表示されるパネル。消えてしまう一番上のパネルを再利用する)に、新しい曲の情報を記載する。\r
682 \r
683                                                 C曲リストノード song = this.r現在選択中の曲;\r
684                                                 for (int i = 0; i < 7; i++)\r
685                                                         song = this.r次の曲(song);\r
686 \r
687                                                 int index = (this.n現在の選択行 + 7) % 13;        // 新しく最下部に表示されるパネルのインデックス(0~12)。\r
688                                                 this.stバー情報[index].strタイトル文字列 = song.strタイトル;\r
689                                                 this.stバー情報[index].col文字色 = song.col文字色;\r
690                                                 this.t曲名バーの生成(index, this.stバー情報[index].strタイトル文字列, this.stバー情報[index].col文字色);\r
691 \r
692 \r
693                                                 // stバー情報[] の内容を1行ずつずらす。\r
694 \r
695                                                 C曲リストノード song2 = this.r現在選択中の曲;\r
696                                                 for (int i = 0; i < 5; i++)\r
697                                                         song2 = this.r前の曲(song2);\r
698 \r
699                                                 for (int i = 0; i < 13; i++)\r
700                                                 {\r
701                                                         int n = (((this.n現在の選択行 - 5) + i) + 13) % 13;\r
702                                                         this.stバー情報[n].eバー種別 = this.e曲のバー種別を返す(song2);\r
703                                                         song2 = this.r次の曲(song2);\r
704                                                 }\r
705 \r
706 \r
707                                                 // 新しく最下部に表示されるパネル用のスキル値を取得。\r
708 \r
709                                                 for (int i = 0; i < 3; i++)\r
710                                                         this.stバー情報[index].nスキル値[i] = (int)song.arスコア[this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(song)].譜面情報.最大スキル[i];\r
711 \r
712 \r
713                                                 // 1行(100カウント)移動完了。\r
714 \r
715                                                 this.n現在のスクロールカウンタ -= 100;\r
716                                                 this.n目標のスクロールカウンタ -= 100;\r
717 \r
718                                                 this.t選択曲が変更された(false);                               // スクロールバー用に今何番目を選択しているかを更新\r
719 \r
720                                                 if (this.n目標のスクロールカウンタ == 0)\r
721                                                         CDTXMania.app.stage選曲.t選択曲変更通知();             // スクロール完了=選択曲変更!\r
722 \r
723                                                 //-----------------\r
724                                                 #endregion\r
725                                         }\r
726                                         else if (this.n現在のスクロールカウンタ <= -100)\r
727                                         {\r
728                                                 #region [ パネルを1行下にシフトする。]\r
729                                                 //-----------------\r
730 \r
731                                                 // 選択曲と選択行を1つ上の行に移動。\r
732 \r
733                                                 this.r現在選択中の曲 = this.r前の曲(this.r現在選択中の曲);\r
734                                                 this.n現在の選択行 = ((this.n現在の選択行 - 1) + 13) % 13;\r
735 \r
736 \r
737                                                 // 選択曲から5つ上のパネル(=新しく最上部に表示されるパネル。消えてしまう一番下のパネルを再利用する)に、新しい曲の情報を記載する。\r
738 \r
739                                                 C曲リストノード song = this.r現在選択中の曲;\r
740                                                 for (int i = 0; i < 5; i++)\r
741                                                         song = this.r前の曲(song);\r
742 \r
743                                                 int index = ((this.n現在の選択行 - 5) + 13) % 13; // 新しく最上部に表示されるパネルのインデックス(0~12)。\r
744                                                 this.stバー情報[index].strタイトル文字列 = song.strタイトル;\r
745                                                 this.stバー情報[index].col文字色 = song.col文字色;\r
746                                                 this.t曲名バーの生成(index, this.stバー情報[index].strタイトル文字列, this.stバー情報[index].col文字色);\r
747 \r
748 \r
749                                                 // stバー情報[] の内容を1行ずつずらす。\r
750 \r
751                                                 C曲リストノード song2 = this.r現在選択中の曲;\r
752                                                 for (int i = 0; i < 5; i++)\r
753                                                         song2 = this.r前の曲(song2);\r
754 \r
755                                                 for (int i = 0; i < 13; i++)\r
756                                                 {\r
757                                                         int n = (((this.n現在の選択行 - 5) + i) + 13) % 13;\r
758                                                         this.stバー情報[n].eバー種別 = this.e曲のバー種別を返す(song2);\r
759                                                         song2 = this.r次の曲(song2);\r
760                                                 }\r
761 \r
762 \r
763                                                 // 新しく最上部に表示されるパネル用のスキル値を取得。\r
764 \r
765                                                 for (int i = 0; i < 3; i++)\r
766                                                         this.stバー情報[index].nスキル値[i] = (int)song.arスコア[this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(song)].譜面情報.最大スキル[i];\r
767 \r
768 \r
769                                                 // 1行(100カウント)移動完了。\r
770 \r
771                                                 this.n現在のスクロールカウンタ += 100;\r
772                                                 this.n目標のスクロールカウンタ += 100;\r
773 \r
774                                                 this.t選択曲が変更された(false);                               // スクロールバー用に今何番目を選択しているかを更新\r
775 \r
776                                                 if (this.n目標のスクロールカウンタ == 0)\r
777                                                         CDTXMania.app.stage選曲.t選択曲変更通知();             // スクロール完了=選択曲変更!\r
778                                                 //-----------------\r
779                                                 #endregion\r
780                                         }\r
781 \r
782                                         this.nスクロールタイマ += nアニメ間隔;\r
783                                 }\r
784                                 //-----------------\r
785                                 #endregion\r
786                         }\r
787 \r
788 \r
789                         // 描画。\r
790 \r
791                         if (this.r現在選択中の曲 == null)\r
792                         {\r
793                                 #region [ 曲が1つもないなら「Songs not found.」を表示してここで帰れ。]\r
794                                 //-----------------\r
795                                 if (bIsEnumeratingSongs)\r
796                                 {\r
797                                         if (this.txEnumeratingSongs != null)\r
798                                         {\r
799                                                 this.txEnumeratingSongs.t2D描画(\r
800                                                         CDTXMania.app.Device,\r
801                                                         320 * Scale.X,\r
802                                                         160 * Scale.Y\r
803                                                 );\r
804                                         }\r
805                                 }\r
806                                 else\r
807                                 {\r
808                                         if (this.txSongNotFound != null)\r
809                                                 this.txSongNotFound.t2D描画(\r
810                                                         CDTXMania.app.Device,\r
811                                                         320 * Scale.X,\r
812                                                         160 * Scale.Y\r
813                                                 );\r
814                                 }\r
815                                 //-----------------\r
816                                 #endregion\r
817 \r
818                                 return 0;\r
819                         }\r
820 \r
821                         if (!this.b登場アニメ全部完了)\r
822                         {\r
823                                 #region [ (1) 登場アニメフェーズの描画。]\r
824                                 //-----------------\r
825                                 for (int i = 0; i < 13; i++)    // パネルは全13枚。\r
826                                 {\r
827                                         if (this.ct登場アニメ用[i].n現在の値 >= 0)\r
828                                         {\r
829                                                 double db割合0to1 = ((double)this.ct登場アニメ用[i].n現在の値) / 100.0;\r
830                                                 double db回転率 = Math.Sin(Math.PI * 3 / 5 * db割合0to1);\r
831                                                 int nパネル番号 = (((this.n現在の選択行 - 5) + i) + 13) % 13;\r
832 \r
833                                                 if (i == 5)\r
834                                                 {\r
835                                                         // (A) 選択曲パネルを描画。\r
836 \r
837                                                         #region [ バーテクスチャを描画。]\r
838                                                         //-----------------\r
839                                                         int width = (int)((425.0 - 0.8f) * Scale.X / Math.Sin(Math.PI * 3 / 5));\r
840                                                         //int width = (int) ( ( (double) ( ( SampleFramework.GameWindowSize.Width - this.ptバーの基本座標[ i ].X ) + 1 ) ) / Math.Sin( Math.PI * 3 / 5 ) );\r
841                                                         int x = SampleFramework.GameWindowSize.Width - ((int)(width * db回転率));\r
842                                                         int y = 415;\r
843                                                         this.tバーの描画(x, y, this.stバー情報[nパネル番号].eバー種別, true);\r
844                                                         //-----------------\r
845                                                         #endregion\r
846                                                         #region [ タイトル名テクスチャを描画。]\r
847                                                         //-----------------\r
848                                                         if (this.stバー情報[nパネル番号].txタイトル名 != null)\r
849                                                                 this.stバー情報[nパネル番号].txタイトル名.t2D描画(\r
850                                                                         CDTXMania.app.Device,\r
851                                                                         (x + (int)(44 * Scale.X)) + (int)((16f + 0.5f) * Scale.X),\r
852                                                                         y + 35\r
853                                                                         //( y + (int) ( 0 * Scale.Y ) ) + (int) ( 16 * Scale.Y )\r
854                                                                         // ( y + (int) ( 5 * Scale.Y ) ) + (int) ( (16f-2f) * Scale.Y)\r
855                                                                 );\r
856                                                         //-----------------\r
857                                                         #endregion\r
858                                                         #region [ スキル値を描画。]\r
859                                                         //-----------------\r
860                                                         if ((this.stバー情報[nパネル番号].eバー種別 == Eバー種別.Score) && (this.e楽器パート != E楽器パート.UNKNOWN))\r
861                                                                 this.tスキル値の描画(x + (int)(28 * Scale.X), y + (int)(59), this.stバー情報[nパネル番号].nスキル値[(int)this.e楽器パート]);\r
862                                                         //-----------------\r
863                                                         #endregion\r
864                                                 }\r
865                                                 else\r
866                                                 {\r
867                                                         // (B) その他のパネルの描画。\r
868 \r
869                                                         #region [ バーテクスチャの描画。]\r
870                                                         //-----------------\r
871                                                         int width = (int)(((double)((SampleFramework.GameWindowSize.Width - this.ptバーの基本座標[i].X) + 1)) / Math.Sin(Math.PI * 3 / 5));\r
872                                                         int x = SampleFramework.GameWindowSize.Width - ((int)(width * db回転率));\r
873                                                         int y = this.ptバーの基本座標[i].Y;\r
874                                                         this.tバーの描画(x, y, this.stバー情報[nパネル番号].eバー種別, false);\r
875                                                         //-----------------\r
876                                                         #endregion\r
877                                                         #region [ タイトル名テクスチャを描画。]\r
878                                                         //-----------------\r
879                                                         if (this.stバー情報[nパネル番号].txタイトル名 != null)\r
880                                                                 this.stバー情報[nパネル番号].txタイトル名.t2D描画(\r
881                                                                         CDTXMania.app.Device,\r
882                                                                         x + (int)(44 * Scale.X),\r
883                                                                         y + 7\r
884                                                                 );\r
885                                                         //-----------------\r
886                                                         #endregion\r
887                                                         #region [ スキル値を描画。]\r
888                                                         //-----------------\r
889                                                         if ((this.stバー情報[nパネル番号].eバー種別 == Eバー種別.Score) && (this.e楽器パート != E楽器パート.UNKNOWN))\r
890                                                                 this.tスキル値の描画(x + (int)(14 * Scale.X), y + (int)(14 * Scale.Y), this.stバー情報[nパネル番号].nスキル値[(int)this.e楽器パート]);\r
891                                                         //-----------------\r
892                                                         #endregion\r
893                                                 }\r
894                                         }\r
895                                 }\r
896                                 //-----------------\r
897                                 #endregion\r
898                         }\r
899                         else\r
900                         {\r
901                                 #region [ (2) 通常フェーズの描画。]\r
902                                 //-----------------\r
903                                 for (int i = 0; i < 13; i++)    // パネルは全13枚。\r
904                                 {\r
905                                         if ((i == 0 && this.n現在のスクロールカウンタ > 0) ||               // 最上行は、上に移動中なら表示しない。\r
906                                                 (i == 12 && this.n現在のスクロールカウンタ < 0))            // 最下行は、下に移動中なら表示しない。\r
907                                                 continue;\r
908 \r
909                                         int nパネル番号 = (((this.n現在の選択行 - 5) + i) + 13) % 13;\r
910                                         int n見た目の行番号 = i;\r
911                                         int n次のパネル番号 = (this.n現在のスクロールカウンタ <= 0) ? ((i + 1) % 13) : (((i - 1) + 13) % 13);\r
912                                         int x = this.ptバーの基本座標[n見た目の行番号].X + ((int)((this.ptバーの基本座標[n次のパネル番号].X - this.ptバーの基本座標[n見た目の行番号].X) * (((double)Math.Abs(this.n現在のスクロールカウンタ)) / 100.0)));\r
913                                         int y = this.ptバーの基本座標[n見た目の行番号].Y + ((int)((this.ptバーの基本座標[n次のパネル番号].Y - this.ptバーの基本座標[n見た目の行番号].Y) * (((double)Math.Abs(this.n現在のスクロールカウンタ)) / 100.0)));\r
914 \r
915                                         if ((i == 5) && (this.n現在のスクロールカウンタ == 0))\r
916                                         {\r
917                                                 // (A) スクロールが停止しているときの選択曲バーの描画。\r
918 \r
919                                                 #region [ バーテクスチャを描画。]\r
920                                                 //-----------------\r
921                                                 this.tバーの描画((int)(216 * Scale.X), (int)(415), this.stバー情報[nパネル番号].eバー種別, true);\r
922                                                 //-----------------\r
923                                                 #endregion\r
924                                                 #region [ タイトル名テクスチャを描画。]\r
925                                                 //-----------------\r
926                                                 if (this.stバー情報[nパネル番号].txタイトル名 != null)\r
927                                                         this.stバー情報[nパネル番号].txタイトル名.t2D描画(\r
928                                                                 CDTXMania.app.Device,\r
929                                                                 //0x114 * Scale.X,\r
930                                                                 //(0xc9 - 1)* Scale.Y\r
931                                                                 (x + ((44f + 0.5f) * Scale.X)),\r
932                                                                 (y + 7)\r
933                                                         );\r
934                                                 //-----------------\r
935                                                 #endregion\r
936                                                 #region [ スキル値を描画。]\r
937                                                 //-----------------\r
938                                                 if ((this.stバー情報[nパネル番号].eバー種別 == Eバー種別.Score) && (this.e楽器パート != E楽器パート.UNKNOWN))\r
939                                                         this.tスキル値の描画(\r
940                                                                 (int)(0xf4 * Scale.X),\r
941                                                                 (int)(0xd3 * Scale.Y),\r
942                                                                 this.stバー情報[nパネル番号].nスキル値[(int)this.e楽器パート]\r
943                                                         );\r
944                                                 //-----------------\r
945                                                 #endregion\r
946                                         }\r
947                                         else\r
948                                         {\r
949                                                 // (B) スクロール中の選択曲バー、またはその他のバーの描画。\r
950 \r
951                                                 #region [ バーテクスチャを描画。]\r
952                                                 //-----------------\r
953                                                 this.tバーの描画(x, y, this.stバー情報[nパネル番号].eバー種別, false);\r
954                                                 //-----------------\r
955                                                 #endregion\r
956                                                 #region [ タイトル名テクスチャを描画。]\r
957                                                 //-----------------\r
958                                                 if (this.stバー情報[nパネル番号].txタイトル名 != null)\r
959                                                         this.stバー情報[nパネル番号].txタイトル名.t2D描画(\r
960                                                                 CDTXMania.app.Device,\r
961                                                                 x + (int)(44 * Scale.X),\r
962                                                                 y + 7\r
963                                                         );\r
964                                                 //-----------------\r
965                                                 #endregion\r
966                                                 #region [ スキル値を描画。]\r
967                                                 //-----------------\r
968                                                 if ((this.stバー情報[nパネル番号].eバー種別 == Eバー種別.Score) && (this.e楽器パート != E楽器パート.UNKNOWN))\r
969                                                         this.tスキル値の描画(x + (int)(14 * Scale.X), y + (int)(14 * Scale.Y), this.stバー情報[nパネル番号].nスキル値[(int)this.e楽器パート]);\r
970                                                 //-----------------\r
971                                                 #endregion\r
972                                         }\r
973                                 }\r
974                                 //-----------------\r
975                                 #endregion\r
976                         }\r
977                         #region [ スクロール地点の計算(描画はCActSelectShowCurrentPositionにて行う) #27648 ]\r
978                         int py;\r
979                         double d = 0;\r
980                         if (nNumOfItems > 1)\r
981                         {\r
982                                 d = ((int)(336 * Scale.Y) - 6 - 8) / (double)(nNumOfItems - 1);\r
983                                 py = (int)(d * (nCurrentPosition - 1));\r
984                         }\r
985                         else\r
986                         {\r
987                                 d = 0;\r
988                                 py = 0;\r
989                         }\r
990                         int delta = (int)(d * this.n現在のスクロールカウンタ / 100);\r
991                         if (py + delta <= (int)(336 * Scale.Y) - 6 - 8)\r
992                         {\r
993                                 this.nスクロールバー相対y座標 = py + delta;\r
994                         }\r
995                         #endregion\r
996 \r
997                         #region [ アイテム数の描画 #27648 ]\r
998                         tアイテム数の描画();\r
999                         #endregion\r
1000                         return 0;\r
1001                 }\r
1002 \r
1003 \r
1004                 // その他\r
1005 \r
1006                 #region [ private ]\r
1007                 //-----------------\r
1008                 private enum Eバー種別 { Score, Box, Other }\r
1009 \r
1010                 private struct STバー\r
1011                 {\r
1012                         public CTexture Score;\r
1013                         public CTexture Box;\r
1014                         public CTexture Other;\r
1015                         public CTexture this[int index]\r
1016                         {\r
1017                                 get\r
1018                                 {\r
1019                                         switch (index)\r
1020                                         {\r
1021                                                 case 0:\r
1022                                                         return this.Score;\r
1023 \r
1024                                                 case 1:\r
1025                                                         return this.Box;\r
1026 \r
1027                                                 case 2:\r
1028                                                         return this.Other;\r
1029                                         }\r
1030                                         throw new IndexOutOfRangeException();\r
1031                                 }\r
1032                                 set\r
1033                                 {\r
1034                                         switch (index)\r
1035                                         {\r
1036                                                 case 0:\r
1037                                                         this.Score = value;\r
1038                                                         return;\r
1039 \r
1040                                                 case 1:\r
1041                                                         this.Box = value;\r
1042                                                         return;\r
1043 \r
1044                                                 case 2:\r
1045                                                         this.Other = value;\r
1046                                                         return;\r
1047                                         }\r
1048                                         throw new IndexOutOfRangeException();\r
1049                                 }\r
1050                         }\r
1051                 }\r
1052 \r
1053                 private struct STバー情報\r
1054                 {\r
1055                         public CActSelect曲リスト.Eバー種別 eバー種別;\r
1056                         public string strタイトル文字列;\r
1057                         public CTexture txタイトル名;\r
1058                         public STDGBVALUE<int> nスキル値;\r
1059                         public Color col文字色;\r
1060                 }\r
1061 \r
1062                 private struct ST選曲バー\r
1063                 {\r
1064                         public CTexture Score;\r
1065                         public CTexture Box;\r
1066                         public CTexture Other;\r
1067                         public CTexture this[int index]\r
1068                         {\r
1069                                 get\r
1070                                 {\r
1071                                         switch (index)\r
1072                                         {\r
1073                                                 case 0:\r
1074                                                         return this.Score;\r
1075 \r
1076                                                 case 1:\r
1077                                                         return this.Box;\r
1078 \r
1079                                                 case 2:\r
1080                                                         return this.Other;\r
1081                                         }\r
1082                                         throw new IndexOutOfRangeException();\r
1083                                 }\r
1084                                 set\r
1085                                 {\r
1086                                         switch (index)\r
1087                                         {\r
1088                                                 case 0:\r
1089                                                         this.Score = value;\r
1090                                                         return;\r
1091 \r
1092                                                 case 1:\r
1093                                                         this.Box = value;\r
1094                                                         return;\r
1095 \r
1096                                                 case 2:\r
1097                                                         this.Other = value;\r
1098                                                         return;\r
1099                                         }\r
1100                                         throw new IndexOutOfRangeException();\r
1101                                 }\r
1102                         }\r
1103                 }\r
1104 \r
1105                 private bool b登場アニメ全部完了;\r
1106                 private Color color文字影 = Color.FromArgb(0x40, 10, 10, 10);\r
1107                 private CCounter[] ct登場アニメ用 = new CCounter[13];\r
1108                 private E楽器パート e楽器パート;\r
1109                 private Font ft曲リスト用フォント;\r
1110                 private long nスクロールタイマ;\r
1111                 private int n現在のスクロールカウンタ;\r
1112                 private int n現在の選択行;\r
1113                 private int n目標のスクロールカウンタ;\r
1114                 private readonly Point[] ptバーの基本座標 = new Point[] {\r
1115                         new Point( (int)(0x162 * Scale.X), (int)(20 * Scale.Y) ),\r
1116                         new Point( (int)(0x139 * Scale.X), (int)(0x36 * Scale.Y) ),\r
1117                         new Point( (int)(0x121 * Scale.X), (int)(0x58 * Scale.Y) ),\r
1118                         new Point( (int)(0x111 * Scale.X), (int)(0x7a * Scale.Y) ),\r
1119                         new Point( (int)(0x108 * Scale.X), (int)(0x9c * Scale.Y) ),\r
1120                         new Point( (int)(0xe8 * Scale.X), (int)(0xc5 * Scale.Y) ),\r
1121                         new Point( (int)(0x112 * Scale.X), (int)(0x102 * Scale.Y) ),\r
1122                         new Point( (int)(0x121 * Scale.X), (int)(0x124 * Scale.Y) ),\r
1123                         new Point( (int)(0x138 * Scale.X), (int)(0x146 * Scale.Y) ),\r
1124                         new Point( (int)(0x157 * Scale.X), (int)(360 * Scale.Y) ),\r
1125                         new Point( (int)(0x18a * Scale.X), (int)(0x18a * Scale.Y) ),\r
1126                         new Point( (int)(0x1f2 * Scale.X), (int)(0x1ac * Scale.Y) ),\r
1127                         new Point( (int)(640 * Scale.X), (int)(0x1ce * Scale.Y) )\r
1128                 };\r
1129                 private STバー情報[] stバー情報 = new STバー情報[13];\r
1130                 private CTexture txSongNotFound, txEnumeratingSongs;\r
1131                 private CTexture txスキル数字;\r
1132                 private CTexture txアイテム数数字;\r
1133                 private STバー tx曲名バー;\r
1134                 private ST選曲バー tx選曲バー;\r
1135 \r
1136                 private int nCurrentPosition = 0;\r
1137                 private int nNumOfItems = 0;\r
1138 \r
1139                 //private string strBoxDefSkinPath = "";\r
1140                 private Eバー種別 e曲のバー種別を返す(C曲リストノード song)\r
1141                 {\r
1142                         if (song != null)\r
1143                         {\r
1144                                 switch (song.eノード種別)\r
1145                                 {\r
1146                                         case C曲リストノード.Eノード種別.SCORE:\r
1147                                         case C曲リストノード.Eノード種別.SCORE_MIDI:\r
1148                                                 return Eバー種別.Score;\r
1149 \r
1150                                         case C曲リストノード.Eノード種別.BOX:\r
1151                                         case C曲リストノード.Eノード種別.BACKBOX:\r
1152                                                 return Eバー種別.Box;\r
1153                                 }\r
1154                         }\r
1155                         return Eバー種別.Other;\r
1156                 }\r
1157                 private C曲リストノード r次の曲(C曲リストノード song)\r
1158                 {\r
1159                         if (song == null)\r
1160                                 return null;\r
1161 \r
1162                         List<C曲リストノード> list = (song.r親ノード != null) ? song.r親ノード.list子リスト : CDTXMania.app.Songs管理.list曲ルート;\r
1163 \r
1164                         int index = list.IndexOf(song);\r
1165 \r
1166                         if (index < 0)\r
1167                                 return null;\r
1168 \r
1169                         if (index == (list.Count - 1))\r
1170                                 return list[0];\r
1171 \r
1172                         return list[index + 1];\r
1173                 }\r
1174                 private C曲リストノード r前の曲(C曲リストノード song)\r
1175                 {\r
1176                         if (song == null)\r
1177                                 return null;\r
1178 \r
1179                         List<C曲リストノード> list = (song.r親ノード != null) ? song.r親ノード.list子リスト : CDTXMania.app.Songs管理.list曲ルート;\r
1180 \r
1181                         int index = list.IndexOf(song);\r
1182 \r
1183                         if (index < 0)\r
1184                                 return null;\r
1185 \r
1186                         if (index == 0)\r
1187                                 return list[list.Count - 1];\r
1188 \r
1189                         return list[index - 1];\r
1190                 }\r
1191                 private void tスキル値の描画(int x, int y, int nスキル値)\r
1192                 {\r
1193                         if (nスキル値 <= 0 || nスキル値 > 100)          // スキル値 0 = 未プレイ なので表示しない。\r
1194                                 return;\r
1195 \r
1196                         int color = (nスキル値 == 100) ? 3 : (nスキル値 / 25);\r
1197 \r
1198                         int n百の位 = nスキル値 / 100;\r
1199                         int n十の位 = (nスキル値 % 100) / 10;\r
1200                         int n一の位 = (nスキル値 % 100) % 10;\r
1201 \r
1202 \r
1203                         // 百の位の描画。\r
1204 \r
1205                         if (n百の位 > 0)\r
1206                                 this.tスキル値の描画_1桁描画(x, y, n百の位, color);\r
1207 \r
1208 \r
1209                         // 十の位の描画。\r
1210 \r
1211                         if (n百の位 != 0 || n十の位 != 0)\r
1212                                 this.tスキル値の描画_1桁描画(x + (int)(8 * Scale.X), y, n十の位, color);\r
1213 \r
1214 \r
1215                         // 一の位の描画。\r
1216 \r
1217                         this.tスキル値の描画_1桁描画(x + (int)(16 * Scale.X), y, n一の位, color);\r
1218                 }\r
1219                 private void tスキル値の描画_1桁描画(int x, int y, int n数値, int color)\r
1220                 {\r
1221                         int dx = (n数値 % 5) * (int)(9 * Scale.X);\r
1222                         int dy = (n数値 / 5) * (int)(12 * Scale.Y);\r
1223 \r
1224                         switch (color)\r
1225                         {\r
1226                                 case 0:\r
1227                                         if (this.txスキル数字 != null)\r
1228                                                 this.txスキル数字.t2D描画(CDTXMania.app.Device, x, y, new Rectangle((int)(45 * Scale.X) + dx, (int)(24 * Scale.Y) + dy, (int)(9 * Scale.X), (int)(12 * Scale.Y)));\r
1229                                         break;\r
1230 \r
1231                                 case 1:\r
1232                                         if (this.txスキル数字 != null)\r
1233                                                 this.txスキル数字.t2D描画(CDTXMania.app.Device, x, y, new Rectangle((int)(45 * Scale.X) + dx, dy, (int)(9 * Scale.X), (int)(12 * Scale.Y)));\r
1234                                         break;\r
1235 \r
1236                                 case 2:\r
1237                                         if (this.txスキル数字 != null)\r
1238                                                 this.txスキル数字.t2D描画(CDTXMania.app.Device, x, y, new Rectangle(dx, (int)(24 * Scale.Y) + dy, (int)(9 * Scale.X), (int)(12 * Scale.Y)));\r
1239                                         break;\r
1240 \r
1241                                 case 3:\r
1242                                         if (this.txスキル数字 != null)\r
1243                                                 this.txスキル数字.t2D描画(CDTXMania.app.Device, x, y, new Rectangle(dx, dy, (int)(9 * Scale.X), (int)(12 * Scale.Y)));\r
1244                                         break;\r
1245                         }\r
1246                 }\r
1247                 private void tバーの初期化()\r
1248                 {\r
1249                         C曲リストノード song = this.r現在選択中の曲;\r
1250 \r
1251                         if (song == null)\r
1252                                 return;\r
1253 \r
1254                         for (int i = 0; i < 5; i++)\r
1255                                 song = this.r前の曲(song);\r
1256 \r
1257                         for (int i = 0; i < 13; i++)\r
1258                         {\r
1259                                 this.stバー情報[i].strタイトル文字列 = song.strタイトル;\r
1260                                 this.stバー情報[i].col文字色 = song.col文字色;\r
1261                                 this.stバー情報[i].eバー種別 = this.e曲のバー種別を返す(song);\r
1262 \r
1263                                 for (int j = 0; j < 3; j++)\r
1264                                         this.stバー情報[i].nスキル値[j] = (int)song.arスコア[this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す(song)].譜面情報.最大スキル[j];\r
1265 \r
1266                                 song = this.r次の曲(song);\r
1267                         }\r
1268 \r
1269                         this.n現在の選択行 = 5;\r
1270                 }\r
1271                 private void tバーの描画(int x, int y, Eバー種別 type, bool b選択曲)\r
1272                 {\r
1273                         if (x >= SampleFramework.GameWindowSize.Width || y >= SampleFramework.GameWindowSize.Height)\r
1274                                 return;\r
1275 \r
1276                         if (b選択曲)\r
1277                         {\r
1278                                 #region [ (A) 選択曲の場合 ]\r
1279                                 //-----------------\r
1280                                 if (this.tx選曲バー[(int)type] != null)\r
1281                                         this.tx選曲バー[(int)type].t2D描画(\r
1282                                                 CDTXMania.app.Device,\r
1283                                                 x,\r
1284                                                 y,\r
1285                                                 new Rectangle(\r
1286                                                         0,\r
1287                                                         0,\r
1288                                                         256,            //(int)(128 * Scale.X),\r
1289                                                         128                     //(int)(64 * Scale.Y)\r
1290                                                 )\r
1291                                         );      // ヘサキ\r
1292                                 x += this.tx選曲バー[(int)type].sz画像サイズ.Width;\r
1293 \r
1294                                 var rc = new Rectangle(\r
1295                                         128,                            //(int)(64 * Scale.X),\r
1296                                         0,\r
1297                                         128,                            //(int)(64 * Scale.X),\r
1298                                         128                                     //(int)(64 * Scale.Y)\r
1299                                 );\r
1300                                 while (x < SampleFramework.GameWindowSize.Width)\r
1301                                 {\r
1302                                         if (this.tx選曲バー[(int)type] != null)\r
1303                                                 this.tx選曲バー[(int)type].t2D描画(\r
1304                                                         CDTXMania.app.Device,\r
1305                                                         x,\r
1306                                                         y,\r
1307                                                         rc\r
1308                                                 );      // 胴体;64pxずつ横につなげていく。\r
1309                                         x += 128;               //(int)(64 * Scale.Y);\r
1310                                 }\r
1311                                 //-----------------\r
1312                                 #endregion\r
1313                         }\r
1314                         else\r
1315                         {\r
1316                                 #region [ (B) その他の場合 ]\r
1317                                 //-----------------\r
1318                                 if (this.tx曲名バー[(int)type] != null)\r
1319                                         this.tx曲名バー[(int)type].t2D描画(\r
1320                                                 CDTXMania.app.Device,\r
1321                                                 x,\r
1322                                                 y,\r
1323                                                 new Rectangle(\r
1324                                                         0,\r
1325                                                         0,\r
1326                                                         128,    //(int) ( 64 * Scale.X ),\r
1327                                                         69              //(int) ( 32 * Scale.Y )\r
1328                                                 //(int)(64 * Scale.X),\r
1329                                                 //(int)(32 * Scale.Y)\r
1330                                                 )\r
1331                                         );              // ヘサキ\r
1332                                 x += 64;                //(int) ( 64 * Scale.X );\r
1333 \r
1334                                 var rc = new Rectangle(\r
1335                                         64,\r
1336                                         0,\r
1337                                         64,\r
1338                                         69\r
1339                                         //0,\r
1340                                         //(int)(32 * Scale.Y),\r
1341                                         //(int)(64 * Scale.X),\r
1342                                         //(int)(32 * Scale.Y)\r
1343 \r
1344                                         //128,          //0,\r
1345                                         //0,            //(int)(32 * Scale.Y),\r
1346                                         //128,          //(int)(64 * Scale.X),\r
1347                                         //128                   //(int)(32 * Scale.Y)\r
1348                                 );\r
1349                                 while (x < SampleFramework.GameWindowSize.Width)\r
1350                                 {\r
1351                                         if (this.tx曲名バー[(int)type] != null)\r
1352                                                 this.tx曲名バー[(int)type].t2D描画(\r
1353                                                         CDTXMania.app.Device,\r
1354                                                         x,\r
1355                                                         y,\r
1356                                                         rc\r
1357                                                 );      // 胴体;64pxずつ横につなげていく。\r
1358                                         x += 64;        // (int) ( 64 * Scale.X );\r
1359                                 }\r
1360                                 //-----------------\r
1361                                 #endregion\r
1362                         }\r
1363                 }\r
1364                 private void t曲名バーの生成(int nバー番号, string str曲名, Color color)\r
1365                 {\r
1366                         if (nバー番号 < 0 || nバー番号 > 12)\r
1367                                 return;\r
1368 \r
1369                         try\r
1370                         {\r
1371                                 SizeF sz曲名;\r
1372 \r
1373                                 #region [ 曲名表示に必要となるサイズを取得する。]\r
1374                                 //-----------------\r
1375                                 using (var bmpDummy = new Bitmap(1, 1))\r
1376                                 {\r
1377                                         var g = Graphics.FromImage(bmpDummy);\r
1378                                         g.PageUnit = GraphicsUnit.Pixel;\r
1379                                         sz曲名 = g.MeasureString(str曲名, this.ft曲リスト用フォント);\r
1380                                 }\r
1381                                 //-----------------\r
1382                                 #endregion\r
1383 \r
1384                                 int n最大幅px = (int)(392 * Scale.Y);\r
1385                                 int height = (int)(25 * Scale.Y);\r
1386                                 int width = (int)((sz曲名.Width + 2) * 0.5f);\r
1387                                 if (width > (CDTXMania.app.Device.Capabilities.MaxTextureWidth / 2))\r
1388                                         width = CDTXMania.app.Device.Capabilities.MaxTextureWidth / 2;  // 右端断ち切れ仕方ないよね\r
1389 \r
1390                                 float f拡大率X = (width <= n最大幅px) ? 0.5f : (((float)n最大幅px / (float)width) * 0.5f);     // 長い文字列は横方向に圧縮。\r
1391 \r
1392                                 using (var bmp = new Bitmap(width * 2, height * 2, PixelFormat.Format32bppArgb))                // 2倍(面積4倍)のBitmapを確保。(0.5倍で表示する前提。)\r
1393                                 using (var g = Graphics.FromImage(bmp))\r
1394                                 {\r
1395                                         g.TextRenderingHint = TextRenderingHint.AntiAlias;\r
1396                                         float y = (((float)bmp.Height) / 2f) - ((CDTXMania.app.ConfigIni.n選曲リストフォントのサイズdot * Scale.Y * 2f) / 2f);\r
1397                                         g.DrawString(str曲名, this.ft曲リスト用フォント, new SolidBrush(this.color文字影), (float)2f, (float)(y + 2f));\r
1398                                         g.DrawString(str曲名, this.ft曲リスト用フォント, new SolidBrush(color), 0f, y);\r
1399 \r
1400                                         TextureFactory.t安全にDisposeする(ref this.stバー情報[nバー番号].txタイトル名);\r
1401 \r
1402                                         this.stバー情報[nバー番号].txタイトル名 = new CTexture(CDTXMania.app.Device, bmp, CDTXMania.app.TextureFormat);\r
1403                                         this.stバー情報[nバー番号].txタイトル名.vc拡大縮小倍率 = new Vector3(f拡大率X, 0.5f, 1f);\r
1404                                 }\r
1405                         }\r
1406                         catch (CTextureCreateFailedException)\r
1407                         {\r
1408                                 Trace.TraceError("曲名テクスチャの作成に失敗しました。[{0}]", str曲名);\r
1409                                 this.stバー情報[nバー番号].txタイトル名 = null;\r
1410                         }\r
1411                 }\r
1412                 private void tアイテム数の描画()\r
1413                 {\r
1414                         string s = nCurrentPosition.ToString() + "/" + nNumOfItems.ToString();\r
1415                         int x = (int)(SampleFramework.GameWindowSize.Width - (8 + 12) * Scale.X);\r
1416                         int y = (int)(362 * Scale.Y);\r
1417 \r
1418                         for (int p = s.Length - 1; p >= 0; p--)\r
1419                         {\r
1420                                 tアイテム数の描画_1桁描画(x, y, s[p]);\r
1421                                 x -= (int)(8 * Scale.X);\r
1422                         }\r
1423                 }\r
1424                 private void tアイテム数の描画_1桁描画(int x, int y, char s数値)\r
1425                 {\r
1426                         int dx, dy;\r
1427                         if (s数値 == '/')\r
1428                         {\r
1429                                 dx = (int)(48 * Scale.X);\r
1430                                 dy = 0;\r
1431                         }\r
1432                         else\r
1433                         {\r
1434                                 int n = (int)s数値 - (int)'0';\r
1435                                 dx = (n % 6) * (int)(8 * Scale.X);\r
1436                                 dy = (n / 6) * (int)(12 * Scale.Y);\r
1437                         }\r
1438                         if (this.txアイテム数数字 != null)\r
1439                         {\r
1440                                 this.txアイテム数数字.t2D描画(CDTXMania.app.Device, x, y, new Rectangle(dx, dy, (int)(8 * Scale.X), (int)(12 * Scale.Y)));\r
1441                         }\r
1442                 }\r
1443                 //-----------------\r
1444                 #endregion\r
1445         }\r
1446 }\r