/// <summary> /// 指定したサーフェスIDについて、alias定義を辿り、実際のサーフェスIDを取得 /// </summary> /// <param name="targetCharacter">対象のキャラクタ (sakura, kero, char2, char3, ...)</param> public virtual int FindActualSurfaceId(string targetCharacter, int surfaceId) { // alias定義が存在し、その中に指定したIDと対応する定義があるかどうかチェック var name = string.Format("{0}.surface.alias", targetCharacter); if (Scopes.ContainsKey(name)) { var entry = Scopes[name].Entries.FirstOrDefault(e => e.Item1 == surfaceId.ToString()); if (entry != null) { // エイリアス先IDを取得 var targetIds = entry.Item2.Trim(new[] { '[', ']' }).Split(','); // 1件以上存在し、かつ先頭が数値であれば、そのエイリアス先IDを返す int targetSurfaceId; if (targetIds.Any() && int.TryParse(targetIds[0], out targetSurfaceId)) { return(targetSurfaceId); } } } // 上記で対応するalias定義が見つからなければ、指定したサーフェスIDをそのまま返す return(surfaceId); }
/// <summary> /// surfaces.txt を読み込む /// </summary> public virtual void Load() { var charsetPattern = new Regex(@"charset\s,\s*(.+?)\s*\z"); // 既存の値はクリア Scopes.Clear(); // ファイル更新日時セット LastWriteTime = File.GetLastWriteTime(Path); // まずはエンコーディングの判定を行うために、対象ファイルの内容を1行ずつ読み込む var sjis = Encoding.GetEncoding(932); var encoding = sjis; var preLines = File.ReadLines(Path, encoding: sjis); foreach (var line in preLines) { // charset行が見つかった場合は、文字コードを設定してループ終了 var matched = charsetPattern.Match(line); if (matched.Success) { var charset = matched.Groups[1].Value; encoding = Encoding.GetEncoding(charset); break; } // 空行でない行が見つかった場合は、文字コードを設定せずにループ終了 if (!string.IsNullOrEmpty(line.Trim())) { break; } } // エンコーディングが確定したら、読み込みメイン処理 var lines = File.ReadLines(Path, encoding: encoding); string preTrimmedLine = null; // 前行 string currentScope = null; // 現在のスコープ var valueSeparators = new[] { ',' }; foreach (var line in lines) { var trimmedLine = line.Trim(); // コメントは無視 (仕様にはないが、行の途中からコメントが始まっている場合も許容) if (trimmedLine.Contains("//")) { trimmedLine = trimmedLine.Remove(trimmedLine.IndexOf("//")).Trim(); } if (string.IsNullOrEmpty(trimmedLine)) // 空行 { // 空行の場合はスキップ continue; } else if (trimmedLine == "{") // 開きブレス処理 { // 直前行がない場合は不正としてスキップ if (preTrimmedLine == null) { continue; } // スコープを設定 currentScope = preTrimmedLine; // 直前行の記載内容をスコープ名とする continue; } else if (trimmedLine.EndsWith("{")) // 開きブレス かつスコープ名がある場合の処理 (仕様上は不正) { // スコープを設定 currentScope = trimmedLine.Replace("{", "").Trim(); // ブレスを削除し、前後の空白を削除した後の結果をスコープ名とする continue; } else if (trimmedLine == "}") // 閉じブレス { // スコープ内にいない場合は不正としてスキップ if (currentScope == null) { continue; } // スコープをクリア currentScope = null; continue; } else if (trimmedLine.Contains(",")) // 上記以外でカンマを含む { var pair = trimmedLine.Split(valueSeparators, 2); // スコープ内にいれば、対象スコープの値として追加 if (currentScope != null) { if (!Scopes.ContainsKey(currentScope)) { Scopes[currentScope] = new Scope(); } Scopes[currentScope].Entries.Add(Tuple.Create(pair[0].Trim(), pair[1].Trim())); // 仕様上は不正と思われるが、たまに大文字混じりでキーを指定しているケースがあるためdowncase } } // 前行として保存 preTrimmedLine = trimmedLine; } }
public SwitchRadio() { Loaded += (sender, e) => { if (HostWindow != null) { return; } //HostWindow = Window.GetWindow(this); HostWindow = this.GetParentObject(typeof(Page), typeof(Window)); }; Checked += (sender, e) => { if (HostWindow == null) { return; } if (!string.IsNullOrWhiteSpace(Scope) && Scopes.ContainsKey(Scope)) { var others = Scopes[Scope].Where(k => k != this); foreach (var switchRadio in others) { switchRadio.IsChecked = false; } } if (string.IsNullOrWhiteSpace(TargetFrameControl)) { return; } if (HostWindow.FindName(TargetFrameControl) is Frame frame) { var ui = (UIElement)frame.Content; if (ui != null) { Storyboard.SetTarget(Da2, ui); FadeoutSb.Completed += OnSbOnCompleted; FadeoutSb.Begin(); void OnSbOnCompleted(object obj, EventArgs args) { Navigate(frame); //ui.BeginAnimation(OpacityProperty, null); //var removeSb = new RemoveStoryboard { BeginStoryboardName = FadeoutSb.Name }; FadeoutSb.Completed -= OnSbOnCompleted; } } else { Navigate(frame); } //var n = NavigationService.GetNavigationService(frame); //frame.NavigationService.Navigate(new Uri($"{TargetPageType}?ExtraData={TargetPageData}", UriKind.Relative), TargetPageData); } }; }