private void UpdateUIFromObject(AnnoObject obj) { if (obj == null) { return; } // size textBoxWidth.Text = obj.Size.Width.ToString(); textBoxHeight.Text = obj.Size.Height.ToString(); // color colorPicker.SelectedColor = obj.Color; // label textBoxLabel.Text = obj.Label; // icon try { comboBoxIcon.SelectedItem = string.IsNullOrEmpty(obj.Icon) ? _noIconItem : comboBoxIcon.Items.Cast <IconImage>().Single(_ => _.Name == Path.GetFileNameWithoutExtension(obj.Icon)); } catch (Exception) { comboBoxIcon.SelectedItem = _noIconItem; } // radius textBoxRadius.Text = obj.Radius.ToString(); // flags //checkBoxLabel.IsChecked = !string.IsNullOrEmpty(obj.Label); checkBoxBorderless.IsChecked = obj.Borderless; checkBoxRoad.IsChecked = obj.Road; }
private void ApplyCurrentObject() { // parse user inputs and create new object AnnoObject obj = new AnnoObject { Size = new Size(textBoxWidth?.Value ?? 1, textBoxHeight?.Value ?? 1), Color = colorPicker.SelectedColor ?? Colors.Red, Label = IsChecked(checkBoxLabel) ? textBoxLabel.Text : "", Icon = comboBoxIcon.SelectedItem == _noIconItem ? null : ((IconImage)comboBoxIcon.SelectedItem).Name, Radius = textBoxRadius?.Value ?? 0, InfluenceRange = string.IsNullOrEmpty(textBoxInfluenceRange.Text) ? 0 : double.Parse(textBoxInfluenceRange.Text, CultureInfo.InvariantCulture), Borderless = IsChecked(checkBoxBorderless), Road = IsChecked(checkBoxRoad), Identifier = textBoxIdentifier.Text, }; // do some sanity checks if (obj.Size.Width > 0 && obj.Size.Height > 0 && obj.Radius >= 0) { annoCanvas.SetCurrentObject(obj); } else { throw new Exception("Invalid building configuration."); } }
/// <summary> /// Copy constructor used to place independent objects on the grid /// </summary> /// <param name="obj"></param> public AnnoObject(AnnoObject obj) { Size = obj.Size; Color = obj.Color; Position = obj.Position; Label = obj.Label; Icon = obj.Icon; Radius = obj.Radius; Borderless = obj.Borderless; Road = obj.Road; // note: this is not really a copy, just a reference, but it is not supposed to change anyway //BuildCosts = obj.BuildCosts; }
/// <summary> /// Copy constructor used to place independent objects on the grid /// </summary> /// <param name="obj"></param> public AnnoObject(AnnoObject obj) { Size = obj.Size; Color = obj.Color; Position = obj.Position; Label = obj.Label; Identifier = obj.Identifier; Template = obj.Template; //Localization = obj.Localization; Icon = obj.Icon; Radius = obj.Radius; InfluenceRange = obj.InfluenceRange; Borderless = obj.Borderless; Road = obj.Road; // note: this is not really a copy, just a reference, but it is not supposed to change anyway //BuildCosts = obj.BuildCosts; }
private void ApplyPreset() { try { AnnoObject selectedItem = treeViewPresets.SelectedItem as AnnoObject; if (selectedItem != null) { UpdateUIFromObject(new AnnoObject(selectedItem) { Color = colorPicker.SelectedColor }); ApplyCurrentObject(); } } catch (Exception) { MessageBox.Show("Something went wrong while applying the preset."); } }
private void ApplyPreset(AnnoObject selectedItem) { try { if (selectedItem != null) { UpdateUIFromObject(new AnnoObject(selectedItem) { Color = _mainViewModel.BuildingSettingsViewModel.SelectedColor ?? Colors.Red, }); ApplyCurrentObject(); } } catch (Exception ex) { App.WriteToErrorLog("Error in ApplyPreset()", ex.Message, ex.StackTrace); MessageBox.Show("Something went wrong while applying the preset."); } }
private void ApplyCurrentObject() { // parse user inputs and create new object var obj = new AnnoObject { Size = new Size(int.Parse(textBoxWidth.Text), int.Parse(textBoxHeight.Text)), Color = colorPicker.SelectedColor, Label = IsChecked(checkBoxLabel) ? textBoxLabel.Text : "", Icon = comboBoxIcon.SelectedItem == _noIconItem ? null : ((IconImage)comboBoxIcon.SelectedItem).Name, Radius = string.IsNullOrEmpty(textBoxRadius.Text) ? 0 : double.Parse(textBoxRadius.Text), Borderless = IsChecked(checkBoxBorderless), Road = IsChecked(checkBoxRoad) }; // do some sanity checks if (obj.Size.Width > 0 && obj.Size.Height > 0 && obj.Radius >= 0) { annoCanvas.SetCurrentObject(obj); } else { throw new Exception("Invalid building configuration."); } }
/// <summary> /// Sets the current object, i.e. the object which the user can place. /// </summary> /// <param name="obj">object to apply</param> public void SetCurrentObject(AnnoObject obj) { obj.Position = _mousePosition; // note: setting of the backing field doens't fire the changed event _currentObject = obj; InvalidateVisual(); }
/// <summary> /// Fired on the OnCurrentObjectChanged event /// </summary> /// <param name="obj"></param> private void UpdateUIFromObject(AnnoObject obj) { if (obj == null) { return; } // size textBoxWidth.Value = (int)obj.Size.Width; textBoxHeight.Value = (int)obj.Size.Height; // color colorPicker.SelectedColor = obj.Color; // label textBoxLabel.Text = obj.Label; // Ident textBoxIdentifier.Text = obj.Identifier; // icon try { if (string.IsNullOrWhiteSpace(obj.Icon)) { comboBoxIcon.SelectedItem = _noIconItem; } else { var foundIconImage = comboBoxIcon.Items.Cast <IconImage>().SingleOrDefault(x => x.Name.Equals(Path.GetFileNameWithoutExtension(obj.Icon), StringComparison.OrdinalIgnoreCase)); comboBoxIcon.SelectedItem = foundIconImage ?? _noIconItem; } } catch (Exception ex) { Console.WriteLine($"Error finding {nameof(IconImage)} for value \"{obj.Icon}\".{Environment.NewLine}{ex}"); comboBoxIcon.SelectedItem = _noIconItem; } // radius textBoxRadius.Value = obj.Radius; //InfluenceRadius textBoxInfluenceRange.Text = obj.InfluenceRange.ToString(); //Set Influence Type combo box if (obj.Radius > 0 && obj.InfluenceRange > 0) { //Building uses both a radius and an influence //Has to be set manually comboxBoxInfluenceType.SelectedValue = BuildingInfluenceType.Both; } else if (obj.Radius > 0) { comboxBoxInfluenceType.SelectedValue = BuildingInfluenceType.Radius; } else if (obj.InfluenceRange > 0) { comboxBoxInfluenceType.SelectedValue = BuildingInfluenceType.Distance; } else { comboxBoxInfluenceType.SelectedValue = BuildingInfluenceType.None; } // flags //checkBoxLabel.IsChecked = !string.IsNullOrEmpty(obj.Label); checkBoxBorderless.IsChecked = obj.Borderless; checkBoxRoad.IsChecked = obj.Road; }
private void ApplyCurrentObject() { // parse user inputs and create new object var obj = new AnnoObject { Size = new Size(_mainViewModel.BuildingSettingsViewModel.BuildingWidth, _mainViewModel.BuildingSettingsViewModel.BuildingHeight), Color = _mainViewModel.BuildingSettingsViewModel.SelectedColor ?? Colors.Red, Label = _mainViewModel.BuildingSettingsViewModel.IsEnableLabelChecked ? _mainViewModel.BuildingSettingsViewModel.BuildingName : string.Empty, Icon = comboBoxIcon.SelectedItem == _noIconItem ? null : ((IconImage)comboBoxIcon.SelectedItem).Name, Radius = _mainViewModel.BuildingSettingsViewModel.BuildingRadius, InfluenceRange = _mainViewModel.BuildingSettingsViewModel.BuildingInfluenceRange, PavedStreet = _mainViewModel.BuildingSettingsViewModel.IsPavedStreet, Borderless = _mainViewModel.BuildingSettingsViewModel.IsBorderlessChecked, Road = _mainViewModel.BuildingSettingsViewModel.IsRoadChecked, Identifier = _mainViewModel.BuildingSettingsViewModel.BuildingIdentifier, Template = _mainViewModel.BuildingSettingsViewModel.BuildingTemplate }; var objIconFileName = ""; //Parse the Icon path into something we can check. if (!string.IsNullOrWhiteSpace(obj.Icon)) { if (obj.Icon.StartsWith("A5_")) { objIconFileName = obj.Icon.Remove(0, 3) + ".png"; //when Anno 2070, it use not A5_ in the original naming. } else { objIconFileName = obj.Icon + ".png"; } } // do some sanity checks if (obj.Size.Width > 0 && obj.Size.Height > 0 && obj.Radius >= 0) { if (!string.IsNullOrWhiteSpace(obj.Icon) && !obj.Icon.Contains(IconFieldNamesCheck)) { //the identifier text 'Uknown Object' is localized within the StatisticsView, which is why it's not localized here //gets icons origin building info var buildingInfo = annoCanvas.BuildingPresets.Buildings.FirstOrDefault(_ => _.IconFileName?.Equals(objIconFileName, StringComparison.OrdinalIgnoreCase) ?? false); if (buildingInfo != null) { // Check X and Z Sizes of the Building Info, if one or both not right, the Object will be Unknown //Building could be in rotated form - so 5x4 should be equivalent to checking for 4x5 if ((obj.Size.Width == buildingInfo.BuildBlocker["x"] && obj.Size.Height == buildingInfo.BuildBlocker["z"]) || (obj.Size.Height == buildingInfo.BuildBlocker["x"] && obj.Size.Width == buildingInfo.BuildBlocker["z"])) { //if sizes match and icon is a existing building in the presets, call it that object if (obj.Identifier != "Residence_New_World") { obj.Identifier = buildingInfo.Identifier; } } else { //Sizes and icon do not match obj.Identifier = "Unknown Object"; } } else if (!_mainViewModel.BuildingSettingsViewModel.BuildingTemplate.Contains("field", StringComparison.OrdinalIgnoreCase)) //check if the icon is removed from a template field { obj.Identifier = "Unknown Object"; } } else if (!string.IsNullOrWhiteSpace(obj.Icon) && obj.Icon.Contains(IconFieldNamesCheck)) { //Check if Field Icon belongs to the field identifier, else set the official icon var buildingInfo = annoCanvas.BuildingPresets.Buildings.FirstOrDefault(_ => _.Identifier == obj.Identifier); if (buildingInfo != null) { if (!string.Equals(objIconFileName, buildingInfo.IconFileName, StringComparison.OrdinalIgnoreCase)) { obj.Icon = buildingInfo.IconFileName.Remove(buildingInfo.IconFileName.Length - 4, 4); //rmeove the .png for the comboBoxIcon try { comboBoxIcon.SelectedItem = string.IsNullOrEmpty(obj.Icon) ? _noIconItem : comboBoxIcon.Items.Cast <IconImage>().Single(_ => _.Name == Path.GetFileNameWithoutExtension(obj.Icon)); } catch (Exception) { comboBoxIcon.SelectedItem = _noIconItem; } } } else { obj.Identifier = "Unknown Object"; } } if (string.IsNullOrEmpty(obj.Icon) && !_mainViewModel.BuildingSettingsViewModel.BuildingTemplate.Contains("field", StringComparison.OrdinalIgnoreCase)) { obj.Identifier = "Unknown Object"; } annoCanvas.SetCurrentObject(obj); } else { throw new Exception("Invalid building configuration."); } }
private void UpdateUIFromObject(AnnoObject obj) { if (obj == null) { return; } // size textBoxWidth.Text = obj.Size.Width.ToString(); textBoxHeight.Text = obj.Size.Height.ToString(); // color colorPicker.SelectedColor = obj.Color; // label textBoxLabel.Text = obj.Label; // icon try { comboBoxIcon.SelectedItem = string.IsNullOrEmpty(obj.Icon) ? _noIconItem : comboBoxIcon.Items.Cast<IconImage>().Single(_ => _.Name == Path.GetFileNameWithoutExtension(obj.Icon)); } catch (Exception) { comboBoxIcon.SelectedItem = _noIconItem; } // radius textBoxRadius.Text = obj.Radius.ToString(); // flags //checkBoxLabel.IsChecked = !string.IsNullOrEmpty(obj.Label); checkBoxBorderless.IsChecked = obj.Borderless; checkBoxRoad.IsChecked = obj.Road; }
private static Rect GetObjectCollisionRect(AnnoObject obj) { return new Rect(obj.Position, new Size(obj.Size.Width - 0.5, obj.Size.Height - 0.5)); }
/// <summary> /// Fired on the OnCurrentObjectChanged event /// </summary> /// <param name="obj"></param> private void UpdateUIFromObject(AnnoObject obj) { if (obj == null) { return; } // size _mainViewModel.BuildingSettingsViewModel.BuildingWidth = (int)obj.Size.Width; _mainViewModel.BuildingSettingsViewModel.BuildingHeight = (int)obj.Size.Height; // color _mainViewModel.BuildingSettingsViewModel.SelectedColor = ColorPresetsHelper.Instance.GetPredefinedColor(obj) ?? obj.Color; // label _mainViewModel.BuildingSettingsViewModel.BuildingName = obj.Label; // Identifier _mainViewModel.BuildingSettingsViewModel.BuildingIdentifier = obj.Identifier; // Template _mainViewModel.BuildingSettingsViewModel.BuildingTemplate = obj.Template; // icon try { if (string.IsNullOrWhiteSpace(obj.Icon)) { comboBoxIcon.SelectedItem = _noIconItem; } else { var foundIconImage = comboBoxIcon.Items.Cast <IconImage>().SingleOrDefault(x => x.Name.Equals(Path.GetFileNameWithoutExtension(obj.Icon), StringComparison.OrdinalIgnoreCase)); comboBoxIcon.SelectedItem = foundIconImage ?? _noIconItem; } } catch (Exception ex) { Console.WriteLine($"Error finding {nameof(IconImage)} for value \"{obj.Icon}\".{Environment.NewLine}{ex}"); comboBoxIcon.SelectedItem = _noIconItem; } // radius _mainViewModel.BuildingSettingsViewModel.BuildingRadius = obj.Radius; //InfluenceRange if (!_mainViewModel.BuildingSettingsViewModel.IsPavedStreet) { _mainViewModel.BuildingSettingsViewModel.BuildingInfluenceRange = obj.InfluenceRange; } else { _mainViewModel.BuildingSettingsViewModel.GetDistanceRange(true, annoCanvas.BuildingPresets.Buildings.FirstOrDefault(_ => _.Identifier == _mainViewModel.BuildingSettingsViewModel.BuildingIdentifier)); } //Set Influence Type if (obj.Radius > 0 && obj.InfluenceRange > 0) { //Building uses both a radius and an influence //Has to be set manually _mainViewModel.BuildingSettingsViewModel.SelectedBuildingInfluence = _mainViewModel.BuildingSettingsViewModel.BuildingInfluences.Single(x => x.Type == BuildingInfluenceType.Both); } else if (obj.Radius > 0) { _mainViewModel.BuildingSettingsViewModel.SelectedBuildingInfluence = _mainViewModel.BuildingSettingsViewModel.BuildingInfluences.Single(x => x.Type == BuildingInfluenceType.Radius); } else if (obj.InfluenceRange > 0) { _mainViewModel.BuildingSettingsViewModel.SelectedBuildingInfluence = _mainViewModel.BuildingSettingsViewModel.BuildingInfluences.Single(x => x.Type == BuildingInfluenceType.Distance); if (obj.PavedStreet) { _mainViewModel.BuildingSettingsViewModel.IsPavedStreet = obj.PavedStreet; } } else { _mainViewModel.BuildingSettingsViewModel.SelectedBuildingInfluence = _mainViewModel.BuildingSettingsViewModel.BuildingInfluences.Single(x => x.Type == BuildingInfluenceType.None); } // flags //_mainWindowLocalization.BuildingSettingsViewModel.IsEnableLabelChecked = !string.IsNullOrEmpty(obj.Label); _mainViewModel.BuildingSettingsViewModel.IsBorderlessChecked = obj.Borderless; _mainViewModel.BuildingSettingsViewModel.IsRoadChecked = obj.Road; }
/// <summary> /// Handles pressing of mouse buttons /// </summary> /// <param name="e"></param> protected override void OnMouseDown(MouseButtonEventArgs e) { if (!IsFocused) { Focus(); } HandleMouse(e); if (e.ClickCount > 1) { var obj = GetObjectAt(_mousePosition); if (obj != null) { CurrentObject = new AnnoObject(obj); } return; } _mouseDragStart = _mousePosition; if (e.LeftButton == MouseButtonState.Pressed && e.RightButton == MouseButtonState.Pressed) { CurrentMode = MouseMode.DragAllStart; } else if (e.LeftButton == MouseButtonState.Pressed && CurrentObject != null) { // place new object TryPlaceCurrentObject(); } else if (e.LeftButton == MouseButtonState.Pressed && CurrentObject == null) { var obj = GetObjectAt(_mousePosition); if (obj == null) { // user clicked nothing: start dragging the selection rect CurrentMode = MouseMode.SelectionRectStart; } else if (!IsControlPressed()) { CurrentMode = _selectedObjects.Contains(obj) ? MouseMode.DragSelectionStart : MouseMode.DragSingleStart; } } InvalidateVisual(); }
/// <summary> /// Renders a selection highlight on the specified object. /// </summary> /// <param name="drawingContext">context used for rendering</param> /// <param name="obj">object to render as selected</param> private void RenderObjectSelection(DrawingContext drawingContext, AnnoObject obj) { // draw object rectangle var objRect = GetObjectScreenRect(obj); drawingContext.DrawRectangle(null, _highlightPen, objRect); }
/// <summary> /// Renders the influence radius of the given object and highlights other objects within range. /// </summary> /// <param name="drawingContext">context used for rendering</param> /// <param name="obj">object which's influence is rendered</param> private void RenderObjectInfluence(DrawingContext drawingContext, AnnoObject obj) { if (obj.Radius >= 0.5) { // highlight buildings within influence var radius = GridToScreen(obj.Radius); var circle = new EllipseGeometry(GetCenterPoint(GetObjectScreenRect(obj)), radius, radius); foreach (var o in _placedObjects) { var oRect = GetObjectScreenRect(o); var distance = GetCenterPoint(oRect); distance.X -= circle.Center.X; distance.Y -= circle.Center.Y; // check if the center is within the influence circle if (distance.X*distance.X + distance.Y*distance.Y <= radius*radius) { drawingContext.DrawRectangle(_influencedBrush, _influencedPen, oRect); } //o.Label = (Math.Sqrt(distance.X*distance.X + distance.Y*distance.Y) - Math.Sqrt(radius*radius)).ToString(); } // draw circle drawingContext.DrawGeometry(_lightBrush, _radiusPen, circle); } }
/// <summary> /// Renders the given AnnoObject to the given DrawingContext. /// </summary> /// <param name="drawingContext">context used for rendering</param> /// <param name="obj">object to render</param> private void RenderObject(DrawingContext drawingContext, AnnoObject obj) { // draw object rectangle var objRect = GetObjectScreenRect(obj); var brush = new SolidColorBrush(obj.Color); drawingContext.DrawRectangle(brush, obj.Borderless ? new Pen(brush, _linePen.Thickness) : _linePen, objRect); // draw object icon if it is at least 2x2 cells var iconRendered = false; if (_renderIcon && !string.IsNullOrEmpty(obj.Icon)) { // draw icon 2x2 grid cells large var iconSize = obj.Size.Width < 2 && obj.Size.Height < 2 ? GridToScreen(new Size(1,1)) : GridToScreen(new Size(2,2)); // center icon within the object var iconPos = objRect.TopLeft; iconPos.X += objRect.Width/2 - iconSize.Width/2; iconPos.Y += objRect.Height/2 - iconSize.Height/2; var iconName = Path.GetFileNameWithoutExtension(obj.Icon); // for backwards compatibility to older layouts if (iconName != null && Icons.ContainsKey(iconName)) { drawingContext.DrawImage(Icons[iconName].Icon, new Rect(iconPos, iconSize)); iconRendered = true; } else { StatusMessage = string.Format("Icon file missing ({0}).", iconName); } } // draw object label if (_renderLabel) { var textPoint = objRect.TopLeft; var text = new FormattedText(obj.Label, Thread.CurrentThread.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Verdana"), 12, Brushes.Black, null, TextFormattingMode.Display) { MaxTextWidth = objRect.Width, MaxTextHeight = objRect.Height }; if (iconRendered) { // place the text in the top left corner if a icon is present text.TextAlignment = TextAlignment.Left; textPoint.X += 3; textPoint.Y += 2; } else { // center the text if no icon is present text.TextAlignment = TextAlignment.Center; textPoint.Y += (objRect.Height - text.Height) / 2; } drawingContext.DrawText(text, textPoint); } }
private Rect GetObjectScreenRect(AnnoObject obj) { return new Rect(GridToScreen(obj.Position), GridToScreen(obj.Size)); }
/// <summary> /// Checks if there is a collision between given objects a and b. /// </summary> /// <param name="a">first object</param> /// <param name="b">second object</param> /// <returns>true if there is a collision, otherwise false</returns> private static bool ObjectIntersectionExists(AnnoObject a, AnnoObject b) { return GetObjectCollisionRect(a).IntersectsWith(GetObjectCollisionRect(b)); }