/// <summary> /// 技術ツリーに発明イベントを追加する /// </summary> /// <param name="item">追加対象の項目</param> /// <param name="position">追加対象の位置</param> private void AddEventItem(TechEvent item, TechPosition position) { Label label = new Label { Location = new Point(DeviceCaps.GetScaledWidth(position.X), DeviceCaps.GetScaledHeight(position.Y)), BackColor = Color.Transparent, Tag = new TechLabelInfo { Item = item, Position = position }, Size = new Size(_eventLabelBitmap.Width, _eventLabelBitmap.Height), Region = _eventLabelRegion }; // ラベル画像を設定する if (ApplyItemStatus && (QueryItemStatus != null)) { QueryItemStatusEventArgs e = new QueryItemStatusEventArgs(item); QueryItemStatus(this, e); label.Image = e.Done ? _doneEventLabelBitmap : _eventLabelBitmap; } else { label.Image = _doneEventLabelBitmap; } label.Click += OnItemLabelClick; label.MouseClick += OnItemLabelMouseClick; label.MouseDown += OnItemLabelMouseDown; label.MouseUp += OnItemLabelMouseUp; label.MouseMove += OnItemLabelMouseMove; label.GiveFeedback += OnItemLabelGiveFeedback; _pictureBox.Controls.Add(label); }
/// <summary> /// 技術ツリーに項目ラベルを追加する /// </summary> /// <param name="item">追加対象の項目</param> /// <param name="position">追加対象の位置</param> public void AddItem(ITechItem item, TechPosition position) { TechItem tech = item as TechItem; if (tech != null) { AddTechItem(tech, position); return; } TechLabel label = item as TechLabel; if (label != null) { AddLabelItem(label, position); return; } TechEvent ev = item as TechEvent; if (ev != null) { AddEventItem(ev, position); } }
/// <summary> /// 技術ツリーの項目を更新する /// </summary> /// <param name="item">更新対象の項目</param> /// <param name="position">更新対象の座標</param> public void UpdateItem(ITechItem item, TechPosition position) { Control.ControlCollection labels = _pictureBox.Controls; foreach (Label label in labels) { TechLabelInfo info = label.Tag as TechLabelInfo; if (info == null) { continue; } if (info.Item != item) { continue; } // ラベルの位置を更新する if (info.Position == position) { label.Location = new Point(DeviceCaps.GetScaledWidth(position.X), DeviceCaps.GetScaledHeight(position.Y)); } // 項目ラベルの表示に項目の状態を反映しないならば座標変更のみ if (!ApplyItemStatus || (QueryItemStatus == null)) { continue; } if (item is TechItem) { // ラベル画像を設定する QueryItemStatusEventArgs e = new QueryItemStatusEventArgs(item); QueryItemStatus(this, e); label.Image = e.Done ? (e.Blueprint ? _blueprintDoneTechLabelBitmap : _doneTechLabelBitmap) : (e.Blueprint ? _blueprintTechLabelBitmap : _techLabelBitmap); } else if (item is TechEvent) { // ラベル画像を設定する QueryItemStatusEventArgs e = new QueryItemStatusEventArgs(item); QueryItemStatus(this, e); label.Image = e.Done ? _doneEventLabelBitmap : _eventLabelBitmap; } } }
/// <summary> /// 技術ツリーの項目を削除する /// </summary> /// <param name="item">削除対象の項目</param> /// <param name="position">削除対象の位置</param> public void RemoveItem(ITechItem item, TechPosition position) { Control.ControlCollection labels = _pictureBox.Controls; foreach (Label label in labels) { TechLabelInfo info = label.Tag as TechLabelInfo; if (info == null) { continue; } if (info.Item == item && info.Position == position) { _pictureBox.Controls.Remove(label); } } }
/// <summary> /// 技術ツリーに技術ラベルを追加する /// </summary> /// <param name="item">追加対象の項目</param> /// <param name="position">追加対象の位置</param> private void AddLabelItem(TechLabel item, TechPosition position) { Label label = new Label { Location = new Point(DeviceCaps.GetScaledWidth(position.X), DeviceCaps.GetScaledHeight(position.Y)), BackColor = Color.Transparent, Tag = new TechLabelInfo { Item = item, Position = position } }; label.Size = Graphics.FromHwnd(label.Handle).MeasureString(item.ToString(), label.Font).ToSize(); label.Click += OnItemLabelClick; label.MouseClick += OnItemLabelMouseClick; label.MouseDown += OnItemLabelMouseDown; label.MouseUp += OnItemLabelMouseUp; label.MouseMove += OnItemLabelMouseMove; label.GiveFeedback += OnItemLabelGiveFeedback; label.Paint += OnTechLabelPaint; _pictureBox.Controls.Add(label); }
/// <summary> /// posotionセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>座標データ</returns> private static TechPosition ParsePosition(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechPosition position = new TechPosition(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // x if (keyword.Equals("x")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // X座標 position.X = (int)(double)token.Value; continue; } // y if (keyword.Equals("y")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // Y座標 position.Y = (int)(double)token.Value; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(position); }
/// <summary> /// eventセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術イベントデータ</returns> private static TechEvent ParseEvent(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechEvent ev = new TechEvent(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術イベントID ev.Id = (int)(double)token.Value; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト ev.Positions.Add(position); continue; } // technology if (keyword.Equals("technology")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidSection(LogCategory, "technology", lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術ID ev.TechId = (int)(double)token.Value; continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(ev); }
/// <summary> /// labelセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術ラベルデータ</returns> private static TechLabel ParseLabel(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechLabel label = new TechLabel(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // tag if (keyword.Equals("tag")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // タグ名 label.Name = token.Value as string; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト label.Positions.Add(position); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(label); }
/// <summary> /// applicationセクションを構文解析する /// </summary> /// <param name="lexer">字句解析器</param> /// <returns>技術データ</returns> private static TechItem ParseApplication(TextLexer lexer) { // = Token token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); return(null); } // { token = lexer.GetToken(); if (token.Type != TokenType.OpenBrace) { Log.InvalidToken(LogCategory, token, lexer); return(null); } TechItem application = new TechItem(); while (true) { token = lexer.GetToken(); // ファイルの終端 if (token == null) { break; } // } (セクション終端) if (token.Type == TokenType.CloseBrace) { break; } // 無効なトークン if (token.Type != TokenType.Identifier) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } string keyword = token.Value as string; if (string.IsNullOrEmpty(keyword)) { continue; } keyword = keyword.ToLower(); // id if (keyword.Equals("id")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術ID application.Id = (int)(double)token.Value; continue; } // name if (keyword.Equals("name")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術名 application.Name = token.Value as string; // 短縮名 application.ShortName = "SHORT_" + application.Name; continue; } // desc if (keyword.Equals("desc")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Identifier && token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 技術説明 application.Desc = token.Value as string; continue; } // position if (keyword.Equals("position")) { TechPosition position = ParsePosition(lexer); if (position == null) { Log.InvalidSection(LogCategory, "position", lexer); continue; } // 座標リスト application.Positions.Add(position); continue; } // picture if (keyword.Equals("picture")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.String) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 画像ファイル名 application.PictureName = token.Value as string; continue; } // year if (keyword.Equals("year")) { // = token = lexer.GetToken(); if (token.Type != TokenType.Equal) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 無効なトークン token = lexer.GetToken(); if (token.Type != TokenType.Number) { Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); continue; } // 史実年 application.Year = (int)(double)token.Value; continue; } // component if (keyword.Equals("component")) { TechComponent component = ParseComponent(lexer); if (component == null) { Log.InvalidSection(LogCategory, "component", lexer); continue; } // 小研究 application.Components.Add(component); continue; } // required if (keyword.Equals("required")) { IEnumerable <int> ids = ParseRequired(lexer); if (ids == null) { Log.InvalidSection(LogCategory, "required", lexer); continue; } // 必要とする技術群(AND) foreach (int id in ids) { RequiredTech tech = new RequiredTech { Id = id }; application.AndRequiredTechs.Add(tech); } continue; } // or_required if (keyword.Equals("or_required")) { IEnumerable <int> ids = ParseRequired(lexer); if (ids == null) { Log.InvalidSection(LogCategory, "or_required", lexer); continue; } // 必要とする技術群(OR) foreach (int id in ids) { RequiredTech tech = new RequiredTech { Id = id }; application.OrRequiredTechs.Add(tech); } continue; } // effects if (keyword.Equals("effects")) { IEnumerable <Command> commands = ParseEffects(lexer); if (commands == null) { Log.InvalidSection(LogCategory, "effects", lexer); continue; } // 技術効果 application.Effects.AddRange(commands); continue; } // 無効なトークン Log.InvalidToken(LogCategory, token, lexer); lexer.SkipLine(); } return(application); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="item">技術項目</param> /// <param name="position">項目ラベルの位置</param> /// <param name="e">ドラッグアンドドロップイベントのパラメータ</param> public ItemDragEventArgs(ITechItem item, TechPosition position, DragEventArgs e) : base(e.Data, e.KeyState, e.X, e.Y, e.AllowedEffect, e.Effect) { Item = item; Position = position; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="item">技術項目</param> /// <param name="position">項目ラベルの位置</param> /// <param name="e">マウスイベントのパラメータ</param> public ItemMouseEventArgs(ITechItem item, TechPosition position, MouseEventArgs e) : base(e.Button, e.Clicks, e.X, e.Y, e.Delta) { Item = item; Position = position; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="item">技術項目</param> /// <param name="position">項目ラベルの位置</param> public ItemEventArgs(ITechItem item, TechPosition position) { Item = item; Position = position; }